tk.my batis 는 어떻게 자신의 유 니 버 설 mapper 를 확장 합 니까?

18131 단어 tk.mybatismapper
tk.my batis 확장 유 니 버 설 mapper
목적:tk.my batis 가 제공 하 는 유 니 버 설 mapper 는 사용 하기에 편리 하지만 일부 sql 에 서 는 우리 의 수 요 를 만족 시 키 지 못 합 니 다.또한 우 리 는 deleted 문 구 를 관리 하고 싶 습 니 다(유 니 버 설 mapper 가 제공 하 는 것 은 물리 적 삭제 이기 때문에 가끔 민감 한 데 이 터 를 논리 적 으로 삭제 할 수 밖 에 없습니다).따라서 우 리 는 기 존의 유 니 버 설 mapper 를 바탕 으로 자신의 확장 을 진행 할 것 입 니 다.
1 jar 도입

     <!--  springboot -->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper</artifactId>
            <version>3.4.0</version>
        </dependency>
이 가방

      <!-- springboot -->
             <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>2.0.2</version>
            </dependency>
springboot 프로젝트 는 이 가방 을 직접 인용 합 니 다.이번 에는 springboot 를 기반 으로 개발 할 것 입 니 다.jar 패키지 버 전 을 주의 하 십시오.너무 낮은 버 전에 문제 가 생 길 수 있 습 니 다.다음 에 소개 하 겠 습 니 다.
2 설정 클래스 작성

package com.example.configuration;
import com.example.common.mapper.commonMapper.CommonMapper;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;
import java.util.Properties;
@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class MyBatisConfiguration {
    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setBasePackage("com.example.dao.mapper");
        Properties properties = new Properties();
        properties.setProperty("mappers", CommonMapper.class.getName());
        properties.setProperty("notEmpty", "false");
        properties.setProperty("identity", "MYSQL");
        properties.setProperty("order","BEFORE");
        mapperScannerConfigurer.setProperties(properties);
        return mapperScannerConfigurer;
    }
}
여 기 는 두 가 지 를 주의해 야 한다.
1>CommonMapper 이것 은 우리 가 정의 한 유 니 버 설 mapper 입 니 다.단독 가방 아래 에 놓 습 니 다.즉,이 가방 아래 에 이 mapper 만 있 습 니 다.그렇지 않 으 면 우 리 는 실 용적 인 팬 형 을 사용 할 때 유형 전환 문제 가 발생 할 수 있 습 니 다.(나 는 이곳 에서 오랫동안 고민 했다)
2>사용자 정의 mapper 스 캔 경 로 를 설정 합 니 다.springboot 프로젝트 는 jar 패키지 버 전 을 주의해 야 합 니 다.버 전이 너무 낮 으 면 설정 류 에서 의 정 의 는 소 용이 없습니다.스 캔 이 안 되 는 지 제 가 예전 에 사 용 했 던 버 전 1,2,3 에 이 문제 가 발생 할 것 입 니 다.더 높 은 버 전 으로 바 꾸 면 해결 할 수 있 습 니 다.
3 일반적인 방법 인 터 페 이 스 를 사용자 정의 Mapper 인터페이스 에 통합 합 니 다.
저 희 는 my sql 데이터 베 이 스 를 사용 하기 때문에 유 니 버 설 기능 을 사용 할 때 자주 사용 하 는 방법 을 선택 적 으로 도입 합 니 다.다음은 자신 이 정의 하 는 자주 사용 하 는 mapper 류 의 통합 입 니 다.이 기본 클래스 는 BasePackage 의 경로 에 두 지 마 십시오.이 경로 의 mapper 는 모두 명확 한 범 형 형식 을 지정 해 야 합 니 다.
1>조회 기능 제공 Mapper:

package com.example.common.mapper.basics;
import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.select.*;
import tk.mybatis.mapper.common.condition.SelectByConditionMapper;
import tk.mybatis.mapper.common.condition.SelectCountByConditionMapper;
import tk.mybatis.mapper.common.example.SelectByExampleMapper;
import tk.mybatis.mapper.common.ids.SelectByIdsMapper;
/**
 * @desc       mapper
 *
 */
public interface SelectMapper<T> extends Marker,
        SelectOneMapper<T>,
        tk.mybatis.mapper.common.base.select.SelectMapper<T>,
        SelectAllMapper<T>,
        SelectCountMapper<T>,
        SelectByPrimaryKeyMapper<T>,
        ExistsWithPrimaryKeyMapper<T>,
        SelectByIdsMapper<T>,
        SelectByConditionMapper<T>,
        SelectCountByConditionMapper<T>,
        SelectByExampleMapper<T> {
}
2>추가 기능 mapper 제공

package com.example.common.mapper.basics;
import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.MySqlMapper;
import tk.mybatis.mapper.common.base.insert.InsertSelectiveMapper;
/**
 * @desc       mapper
 */
public interface InsertMapper<T> extends Marker,
        tk.mybatis.mapper.common.base.insert.InsertMapper<T>,
        InsertSelectiveMapper<T>,
        MySqlMapper<T>{
}
3>업데이트 기능 mapper 제공

package com.example.common.mapper.basics;
import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeyMapper;
import tk.mybatis.mapper.common.base.update.UpdateByPrimaryKeySelectiveMapper;
import tk.mybatis.mapper.common.condition.UpdateByConditionMapper;
import tk.mybatis.mapper.common.condition.UpdateByConditionSelectiveMapper;
import tk.mybatis.mapper.common.example.UpdateByExampleSelectiveMapper;
/**
 * @desc       mapper
 *
 */
public interface UpdateMapper<T> extends Marker,
        UpdateByPrimaryKeyMapper<T>,
        UpdateByPrimaryKeySelectiveMapper<T>,
        UpdateByConditionMapper<T>,
        UpdateByConditionSelectiveMapper<T>,
        UpdateByExampleSelectiveMapper<T> {
}
4>삭제 기능 mapper 제공

package com.example.common.mapper.basics;
import com.example.common.mapper.defined.DeleteShamByIdsMapper;
import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.delete.DeleteByPrimaryKeyMapper;
import tk.mybatis.mapper.common.condition.DeleteByConditionMapper;
import tk.mybatis.mapper.common.ids.DeleteByIdsMapper;
/**
 * @desc       mapper
 *
 */
public interface DeleteMapper<T> extends Marker,
        tk.mybatis.mapper.common.base.delete.DeleteMapper<T>,
        DeleteByPrimaryKeyMapper<T>,
        DeleteByConditionMapper<T>,
        DeleteByIdsMapper<T>{
}
5>첨삭 검사 의 기본 클래스 CommonMapper 제공

package com.example.common.mapper.commonMapper;
import com.example.common.mapper.basics.DeleteMapper;
import com.example.common.mapper.basics.InsertMapper;
import com.example.common.mapper.basics.SelectMapper;
import com.example.common.mapper.basics.UpdateMapper;
/**
 * @param <T>
 * @desc         mapper
 */
public interface CommonMapper<T> extends
        DeleteMapper<T>,
        InsertMapper<T>,
        SelectMapper<T>,
        UpdateMapper<T> {
}
6>실체 대상

package com.example.dao.entity;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
import java.io.Serializable;
@Table(name="user")
@Data
public class User implements Serializable {
    @Id
    private Integer id;
    private String trueName;
    private String userName;    
    private Integer isDeleted;
}
7>사용자 정의 mapper 가 CommenMapper 를 계승 하도록 하면 이 문 구 를 사용 할 수 있 습 니 다.

package com.example.dao.mapper;
import com.example.common.mapper.commonMapper.CommonMapper;
import com.example.dao.entity.User;
public interface UserMapper extends CommonMapper<User> {
}
다음은 CommonMapper 에서 삭제 방법 을 제공 하 는 DeleteMapper 를 강화 하여 논리 적 으로 삭제 하 는 문 구 를 추가 할 것 입 니 다.
1>사용자 정의 Provider 는 MapperTemplate 를 계승 하고 구조 방법 을 복사 해 야 합 니 다.
이것 은 원본 코드 의 대량 삭제 입 니 다.

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package tk.mybatis.mapper.provider;
import java.util.Set;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.MapperException;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
public class IdsProvider extends MapperTemplate {
    public IdsProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }
    public String deleteByIds(MappedStatement ms) {
        Class<?> entityClass = this.getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.deleteFromTable(entityClass, this.tableName(entityClass)));
        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);
        if (columnList.size() == 1) {
            EntityColumn column = (EntityColumn)columnList.iterator().next();
            sql.append(" where ");
            sql.append(column.getColumn());
            sql.append(" in (${_parameter})");
            return sql.toString();
        } else {
            throw new MapperException("   deleteByIds       [" + entityClass.getCanonicalName() + "]          @Id      ");
        }
    }
    public String selectByIds(MappedStatement ms) {
        Class<?> entityClass = this.getEntityClass(ms);
        this.setResultType(ms, entityClass);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, this.tableName(entityClass)));
        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);
        if (columnList.size() == 1) {
            EntityColumn column = (EntityColumn)columnList.iterator().next();
            sql.append(" where ");
            sql.append(column.getColumn());
            sql.append(" in (${_parameter})");
            return sql.toString();
        } else {
            throw new MapperException("   selectByIds       [" + entityClass.getCanonicalName() + "]          @Id      ");
        }
    }
}
다음 에 우 리 는 IdsProvider 를 확장 해서 그 로 하여 금 대량 논리 삭 제 를 지원 하 게 한다
1>IdsdProvider 의 하위 클래스 만 들 기

package com.example.common.mapper.defined;
import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.MapperException;
import tk.mybatis.mapper.entity.EntityColumn;
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
import tk.mybatis.mapper.provider.IdsProvider;
import java.util.Set;
public class IdsProviderDefined extends IdsProvider {
    public IdsProviderDefined(Class<?> mapperClass, MapperHelper mapperHelper) {
        super(mapperClass, mapperHelper);
    }
    public String deleteShamByIds(MappedStatement ms) {
        Class<?> entityClass = this.getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.updateTable(entityClass, this.tableName(entityClass)));
        sql.append("<set> is_deleted='1' </set>");
        Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass);
        if (columnList.size() == 1) {
            EntityColumn column = (EntityColumn)columnList.iterator().next();
            sql.append(" where ");
            sql.append(column.getColumn());
            sql.append(" in (${_parameter})");
            return sql.toString();
        } else {
            throw new MapperException("   deleteByIds       [" + entityClass.getCanonicalName() + "]          @Id      ");
        }
    }
}
deleteShamByIds 는 바로 우리 문 에서 대량으로 논리 적 으로 삭제 하 는 방법 입 니 다.이 방법 은 바로 sql 을 재 조립 하 는 것 입 니 다.tk 에서 sql 을 조립 하 는 데 도움 을 주 고 매개 변수 클래스(SqlHelper,EntityHelper)를 많이 제공 합 니 다.우 리 는 사용 할 수 있 습 니 다.
2>DeleteShamByIdsMapper 인터페이스 만 들 기

package com.example.common.mapper.defined;
import org.apache.ibatis.annotations.DeleteProvider;
public interface DeleteShamByIdsMapper<T> {
    @DeleteProvider(
            type = IdsProviderDefined.class,
            method = "dynamicSQL"
    )
    int deleteShamByIds(String var1);
    //             IdsProviderDefined       
}
3>deleteMapper 에서 사용자 정의 논리 삭제 인 터 페 이 스 를 계승 합 니 다 deleteShamByIdsMapper

package com.example.common.mapper.basics;
import com.example.common.mapper.defined.DeleteShamByIdsMapper;
import tk.mybatis.mapper.common.Marker;
import tk.mybatis.mapper.common.base.delete.DeleteByPrimaryKeyMapper;
import tk.mybatis.mapper.common.condition.DeleteByConditionMapper;
import tk.mybatis.mapper.common.ids.DeleteByIdsMapper;
/**
 * @desc       mapper
 *
 */
public interface DeleteMapper<T> extends Marker,
        tk.mybatis.mapper.common.base.delete.DeleteMapper<T>,
        DeleteByPrimaryKeyMapper<T>,
        DeleteByConditionMapper<T>,
        DeleteByIdsMapper<T>,
        DeleteShamByIdsMapper<T>{
}
여기에서 사용자 정의 대량 논리 삭 제 를 정의 하면 유 니 버 설 마 퍼 를 확장 할 수 있 습 니 다.
TK my batis 플러그 인 유 니 버 설 mapper 와 Oacle 의 구덩이
최근 회사 에 서 는 몇 가지 프로젝트 의 데이터 베 이 스 를 사용 하 는 Oacle 이 있 습 니 다.한동안 사용 하지 않 았 다가 과감하게 구덩이 에 빠 졌 습 니 다.몇 가 지 를 기록 하 는 것 이 대표 적 입 니 다.
1:Oacle 의 대량 데이터 삽입 에 대해 서 는 TK 유 니 버 설 mapper 의 insertList 방법 으로 자동 으로 연 결 된 sql 이 이 렇 습 니 다.

insert  into table(column1,column2)values 
(value1,value2),
(value3,value4)。。。
어떻게 보면 문제 가 없 을 까?그리고 sql 이 정확하게 끝나 지 않 았 다 고 계속 보고 했다.자신의 sql 에 대한 지나친 자신 감 때문에 매개 변수 문제 인지 생각 하고 몇 시간 을 낭비 했다.나중에 sql 을 잘 맞 춰 서 데이터 베 이 스 를 잃 어 버 리 고 뛰 었 더 니 이런 sql 은 Oacle 에서 뛸 수 없다 는 것 을 알 게 되 었 다.Oacle 에서 대량으로 삽입 하 는 문법 은 다음 과 같 아야 한다.

INSERT ALL 
INTO A(field_1,field_2) VALUES (value_1,value_2) 
INTO A(field_1,field_2) VALUES (value_3,value_4) 
INTO A(field_1,field_2) VALUES (value_5,value_6)
TK 코드 를 대충 살 펴 보 니 데이터베이스 드라이버 를 검사 하지 않 고 바로 sql 을 맞 추기 시작 한 것 같 습 니 다.

public String insertList(MappedStatement ms) {
        Class<?> entityClass = this.getEntityClass(ms);
        StringBuilder sql = new StringBuilder();
        sql.append(SqlHelper.insertIntoTable(entityClass, this.tableName(entityClass)));
        sql.append(SqlHelper.insertColumns(entityClass, true, false, false));
        sql.append(" VALUES ");
        sql.append("<foreach collection=\"list\" item=\"record\" separator=\",\" >");
        sql.append("<trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">");
        Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);
        Iterator var5 = columnList.iterator();
        while(var5.hasNext()) {
            EntityColumn column = (EntityColumn)var5.next();
            if (!column.isId() && column.isInsertable()) {
                sql.append(column.getColumnHolder("record") + ",");
            }
        }
        sql.append("</trim>");
        sql.append("</foreach>");
        return sql.toString();
    }
그러나 저 는 이런 플러그 인 은 호 환 방안 이 있 을 것 이 라 고 생각 합 니 다.그리고 이 플러그 인 을 사용 한 것 은 원본 my batis 를 사용 하 는 것 과 충돌 하지 않 기 때문에 실제 개발 에 영향 을 주지 않 습 니 다.Oacle 의 기 초 를 복습 하고 자신 에 게 일 깨 워 주 는 셈 입 니 다.프로그래머 는 성실 하 게 먼저 실행 하고 독선 적 인 경험 도 가끔 씩 함정 에 빠 집 니 다.
2:oracle 에 대한 비교 기호(<>=)와 null
일단 복습 을 해 보도 록 하 겠 습 니 다.
일반 데이터베이스 에서 특정한 필드 가 비어 있 거나 비어 있 지 않 을 때 is null 또는 is not null 을 사용 합 니 다.
검색 조건 사용=null 또는<>null 은 데 이 터 를 찾 을 수 없습니다.
그러나 할당 은 사용 할 수 있 습 니 다.

update BUS_PLATFORM.bus_trans set return_code = null where return_msg= 'tac    ';
이것 은 성공 적 으로 실행 할 수 있 습 니 다.그러나 이것 은 모두 표 밖의 값 조작 입 니 다.그러면 표 안의 데이터 가 null 이 있 을 때 어떤 구덩이 가 있 습 니까?예 를 들 어.

select * from table1 where name <>'zhansan'
조회 표 의 name 필드 는 zhangsan 의 데이터 가 아 닙 니 다.표 에 name 이 null 인 데이터 가 있 을 때 이 데 이 터 는 찾 을 수 없습니다.예 를 들 어 표 에 100 개의 데이터 가 있 고 한 데이터 의 name 값 은 zhangsan 이 며 9 개의 데이터 의 name 값 은 null 입 니 다.그러면 이 sql 은 90 개의 데이터 만 찾 을 수 있 습 니 다.따라서 정확 한 수요 가 있 으 면 name 값 이 zhangsan 이 아 닌 데 이 터 를 조회 하고 name 값 이 null 인 데 이 터 를 포함 하면 sql 은

select * from table1 where name <>'zhansan' or name is null
3:이것 은 my batis 의 규범 입 니 다.기본적으로 숫자 를 채 우 는 것 이지 만 저 를 함정 에 빠 뜨 린 적 이 있 습 니 다.
먼저 내용:my batis 가 null 값 을 삽입 할 때 이 값 의 형식(jdbctype)을 지정 해 야 합 니 다.그렇지 않 으 면 오류 가 발생 할 수 있 습 니 다.
형식 을 지정 하지 않 으 면 my batis 는 일치 하 는 데이터베이스 필드 형식 을 스스로 맞 출 수 있 기 때문에 null 은 적합 하지 않 습 니 다.어쩌면 잘못 을 보고 할 지도 모 르 니 매우 확실 하 다.그러나 일반적으로 xml 로 sql 을 설정 하면 이 문제 가 발생 하지 않 습 니 다.쓸 때 편 하 게 적 습 니 다.이것 도 제 가 TK 를 사용 할 때 드 러 난 문제 입 니 다.insert 방법 을 사용 할 때 null 이 있 으 면 끊 습 니 다.하지만 TK 는 insert Selective 방법 으로 삽입 할 때 자동 으로 빈 값 을 걸 러 냅 니 다.
이상 은 개인 적 인 경험 이 므 로 여러분 에 게 참고 가 되 기 를 바 랍 니 다.여러분 들 도 저 희 를 많이 응원 해 주시 기 바 랍 니 다.

좋은 웹페이지 즐겨찾기