溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么開發(fā)一個MyBatis通用Mapper的輪子

發(fā)布時間:2022-12-28 09:54:17 來源:億速云 閱讀:208 作者:iii 欄目:開發(fā)技術(shù)

本篇內(nèi)容介紹了“怎么開發(fā)一個MyBatis通用Mapper的輪子”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

    需求

    通用Mapper起碼應(yīng)該包含以下功能:

    1、增

    2、刪

    3、改

    4、批量增

    5、批量刪

    6、只更新指定字段

    7、分頁查詢查當(dāng)前頁

    8、分頁查詢查總數(shù)

    9、字典字段翻譯

    10、數(shù)據(jù)權(quán)限控制

    大概長下面這個樣子: 

    public interface BaseMapper<T,K> {
    
        int insert(T t);
    
        int batchInsert(List<T> entity);
        
        int deleteById(K id);
        
        int deleteBatchIds(Collection<K> ids);
        
        int updateById(T entity);
        
        int updateSelectiveById(T entity);
        
        T selectById(K id);
        
        List<T> selectBatchIds(Collection<K> ids);
        
        List<T> selectAll();
        
        List<T> selectPage(PageRequest<T> pageRequest);
        
        Long selectCount(T entity);
    
    }

    實現(xiàn)原理

    1、基于MyBatis3提供的SqlProvider構(gòu)建動態(tài)Sql

    怎么開發(fā)一個MyBatis通用Mapper的輪子

    例如如下代碼:

    @SelectProvider(type = UserSqlBuilder.class, method = "buildGetUsersByName")
    List<User> getUsersByName(String name);
    
    class UserSqlBuilder {
      public static String buildGetUsersByName(final String name) {
        return new SQL(){{
          SELECT("*");
          FROM("users");
          if (name != null) {
            WHERE("name like #{value} || '%'");
          }
          ORDER_BY("id");
        }}.toString();
      }
    }

    2、基于自定義注解,為實體和數(shù)據(jù)庫表建立對應(yīng)關(guān)系

    例如如下代碼:

    @Table("user")
    public class User {
        @Id(auto = true)
        @Column(value = "id")
        private Long id;
    
        @Column(value = "name", filterOperator = FilterOperator.LIKE)
        @OrderBy(orderPriority = 0)
        private String name;
    
        @OrderBy(order = Order.DESC, orderPriority = 1)
        private Integer age;
    
        private String email;
    
        @Transient
        private String test;
    }

    基于以上兩個原理,當(dāng)方法被調(diào)用時,我們便可構(gòu)建出相應(yīng)的動態(tài)Sql,從而實現(xiàn)該通用Mapper。

    代碼實現(xiàn)

    1、自定義注解

    1)@Table

    了解Jpa的朋友一定很熟悉,這個就是為實體指定表名,實體不加這個注解就認(rèn)為實體名與表名一致:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    public @interface Table {
        //表名,不指定則使用實體類名
        String value() default "";
    }

    2)@Column

    指定完表名,該指定列名了,同樣的如果字段不指定則認(rèn)為字段名與表列名一致:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Column {
        //對應(yīng)數(shù)據(jù)庫列名
        String value() default "";
        //查詢時的過濾類型
        FilterOperator filterOperator() default FilterOperator.EQ;
        //是否查詢,select是否帶上該字段
        boolean selectable() default true;
        //是否插入,insert是否帶上該字段
        boolean insertable() default true;
        //是否更新,update是否帶上該字段
        boolean updatable() default true;
    }

    3)@Id

    這個注解就是為了表明該字段是否是數(shù)據(jù)庫主鍵。當(dāng)然,這個注解可以與@Column合并,但為了更清晰,我還是決定單獨使用這個注解。并且,也方便后期擴展。

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Id {
        //主鍵是否自動生成
        boolean auto() default false;
    }

    4)@OrderBy

    這個注解來標(biāo)明查詢時的排序字段,同時考慮如果排序字段有多個,可定義優(yōu)先級:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface OrderBy {
        //排序
        Order order() default Order.ASC;
        //多個排序字段先后順序
        int orderPriority() default 0;
    }

    5)@Transient

    考慮實體中有些字段在數(shù)據(jù)庫中不存在的情況。使用這個注解來標(biāo)注這樣的字段:

    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface Transient {
    }

    2、幾個pojo,用來保存實體對應(yīng)的信息

    1)TableInfo,表示一個實體對應(yīng)的數(shù)據(jù)庫表信息

    public class TableInfo {
        //表對應(yīng)的實體類型
        private Class<?> entityClass;
    
        //表名
        private String tableName;
    
        //列
        private List<ColumnInfo> columns;
    
        //是否聯(lián)合主鍵
        private boolean isUnionId;
    }

    2)ColumnInfo,表示實體中的一個字段對應(yīng)的數(shù)據(jù)庫表字段信息

    public class ColumnInfo {
        //對應(yīng)的java類型
        private Class<?> fieldClass;
        private Field field;
        private FilterOperator filterOperator;
        //數(shù)據(jù)庫列
        private String column;
        //是否主鍵
        private boolean isPrimaryKey;
        //主鍵填充方式
        private boolean isPrimaryKeyAuto;
        //排序
        private Order orderBy;
        private int orderByPriority;
        //是否參與insert
        private boolean insertable;
        //是否參與update
        private boolean updatable;
        //是否參與select
        private boolean selectable;
    }

    以上只需要注意一點,如何判斷一個實體是否是聯(lián)合主鍵。這里用的比較粗暴的方法,如果有多個字段加了@Id,那么認(rèn)為是聯(lián)合主鍵。

    3、定義開頭說的BaseMapper

    這個BaseMapper的定義模仿了SpringDataJpa,它需要兩個泛型,T表示實體類型,K表示主鍵類型。

    一般情況下K為簡單數(shù)據(jù)類型,比如Long,String;

    聯(lián)合主鍵情況下,K為自定義的一個復(fù)雜數(shù)據(jù)類型,具體使用方法見文章最后章節(jié)。

    public interface BaseMapper<T,K> {
    
        @InsertProvider(type = SqlProvider.class,method = "insert")
        @Options(useGeneratedKeys = true, keyProperty = "id",keyColumn = "id")
        int insert(T t);
    
        @InsertProvider(type = SqlProvider.class,method = "batchInsert")
        int batchInsert(@Param("list") List<T> entity);
    
        @DeleteProvider(type = SqlProvider.class,method = "deleteById")
        int deleteById(@Param("id") K id);
    
        @DeleteProvider(type = SqlProvider.class,method = "deleteBatchIds")
        int deleteBatchIds(@Param("ids") Collection<K> ids);
    
        @UpdateProvider(type = SqlProvider.class,method = "updateById")
        int updateById(T entity);
    
        @UpdateProvider(type = SqlProvider.class,method = "updateSelectiveById")
        int updateSelectiveById(T entity);
    
        @SelectProvider(type = SqlProvider.class,method = "selectById")
        T selectById(@Param("id") K id);
    
        @SelectProvider(type = SqlProvider.class,method = "selectBatchIds")
        List<T> selectBatchIds(@Param("ids") Collection<K> ids);
    
        @SelectProvider(type = SqlProvider.class,method = "selectAll")
        List<T> selectAll();
    
        @SelectProvider(type = SqlProvider.class,method = "selectPage")
        List<T> selectPage(PageRequest<T> pageRequest);
    
        @SelectProvider(type = SqlProvider.class,method = "selectCount")
        Long selectCount(T entity);
    
    }

    4、SqlProvider

    public class SqlProvider<T> {
        private static Logger logger = LoggerFactory.getLogger(SqlProvider.class);
        private static Map<Class<?>, TableInfo> tableCache = new ConcurrentHashMap<>();
    
        public String insert(T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            String intoColumns = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isInsertable)
                    .map(ColumnInfo::getColumn)
                    .collect(Collectors.joining(","));
            String values = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isInsertable)
                    .map(ColumnInfo::variable)
                    .collect(Collectors.joining(","));
            String sql = new SQL()
                    .INSERT_INTO(tableName)
                    .INTO_COLUMNS(intoColumns)
                    .INTO_VALUES(values).toString();
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String batchInsert(@Param("list" ) List<?> entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            String intoColumns = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isInsertable)
                    .map(ColumnInfo::getColumn)
                    .collect(Collectors.joining(","));
            String values = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isInsertable)
                    .map(column->column.variableWithPrefix("item"))
                    .collect(Collectors.joining(","));
            String sql = new SQL()
                    .INSERT_INTO(tableName)
                    .INTO_COLUMNS(intoColumns).toString();
            sql += " values ";
            sql += "<foreach collection=\"list\" item=\"item\" separator=\",\">" +
                    "  <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\">" +
                    "    " + values +
                    "  </trim>" +
                    "</foreach>";
            sql = "<script>"+sql+"</script>";
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String deleteById(@Param("id") T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            String[] where = null;
            if (tableInfo.isUnionId()){
                where = tableInfo.getColumns()
                        .stream()
                        .filter(ColumnInfo::isPrimaryKey)
                        .map(columnInfo -> columnInfo.getColumn()+" = #{id."+columnInfo.getField().getName()+"}")
                        .toArray(String[]::new);
            }else {
                where = tableInfo.getColumns()
                        .stream()
                        .filter(ColumnInfo::isPrimaryKey)
                        .map(columnInfo -> columnInfo.getColumn()+" = #{id}")
                        .toArray(String[]::new);
            }
            String sql = new SQL()
                    .DELETE_FROM(tableName)
                    .WHERE(where)
                    .toString();
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String deleteBatchIds(@Param("ids") Collection<?> entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            if (tableInfo.isUnionId()){
                String[] where = new String[entity.size()];
                for (int i = 0; i < entity.size(); i++){
                    List<String> list = new ArrayList<>();
                    String s = "%s=#{ids[%d].%s}";
                    for (ColumnInfo columnInfo:tableInfo.getColumns()){
                        if (columnInfo.isPrimaryKey()){
                            list.add(String.format(s,columnInfo.getColumn(),i,columnInfo.getField().getName()));
                        }
                    }
                    where[i] = "("+StringUtils.join(list," and ")+")";
                }
                String sql = "delete from %s where %s ";
                sql = String.format(sql,tableName,StringUtils.join(where," or "));
                logger.info("sql->{},params->{}",sql,entity);
                return sql;
            }else {
                String idName = tableInfo.getColumns()
                        .stream()
                        .filter(ColumnInfo::isPrimaryKey)
                        .findFirst()
                        .get()
                        .getColumn();
                String sql = "DELETE FROM %s WHERE %s IN (%s) ";
                String[] arr = new String[entity.size()];
                for (int i = 0; i < entity.size(); i++){
                    arr[i] = "#{ids["+i+"]}";
                }
                sql = String.format(sql,tableName,idName,StringUtils.join(arr,","));
                logger.info("sql->{},params->{}",sql,entity);
                return sql;
            }
        }
    
        public String updateById(T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            String[] where = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isPrimaryKey)
                    .map(columnInfo -> columnInfo.getColumn()+" = "+columnInfo.variable())
                    .toArray(String[]::new);
            String sql = new SQL().UPDATE(tableName).SET(tableInfo.updateSetColumn()).WHERE(where).toString();
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String updateSelectiveById(T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            String[] where = tableInfo.getColumns()
                    .stream()
                    .filter(ColumnInfo::isPrimaryKey)
                    .map(columnInfo -> columnInfo.getColumn()+" = "+columnInfo.variable())
                    .toArray(String[]::new);
            String sql = new SQL().UPDATE(tableName).SET(tableInfo.updateSetSelectiveColumn(entity)).WHERE(where).toString();
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String selectById(@Param("id")T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String[] where = null;
            if (tableInfo.isUnionId()){
                where = tableInfo.getColumns().stream().filter(ColumnInfo::isPrimaryKey)
                        .map(columnInfo -> columnInfo.getColumn()+" = #{id."+columnInfo.getField().getName()+"}")
                        .toArray(String[]::new);
            }else {
                where = tableInfo.getColumns().stream().filter(ColumnInfo::isPrimaryKey)
                        .map(columnInfo -> columnInfo.getColumn()+" = #{id}")
                        .toArray(String[]::new);
            }
            String sql = new SQL()
                    .SELECT(tableInfo.selectColumnAsProperty())
                    .FROM(tableInfo.getTableName())
                    .WHERE(where)
                    .toString();
            logger.info("sql->{},params->{}",sql,entity);
            return sql;
        }
    
        public String selectBatchIds(@Param("ids")Collection<?> entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            String tableName = tableInfo.getTableName();
            if (tableInfo.isUnionId()){
                String[] where = new String[entity.size()];
                for (int i = 0; i < entity.size(); i++){
                    List<String> list = new ArrayList<>();
                    String s = "%s=#{ids[%d].%s}";
                    for (ColumnInfo columnInfo:tableInfo.getColumns()){
                        if (columnInfo.isPrimaryKey()){
                            list.add(String.format(s,columnInfo.getColumn(),i,columnInfo.getField().getName()));
                        }
                    }
                    where[i] = "("+StringUtils.join(list," and ")+")";
                }
                String sql = "select %s from %s where %s";
                sql = String.format(sql,tableInfo.selectColumnAsProperty(),tableInfo.getTableName(),StringUtils.join(where," or "));
                logger.info("sql->{},params->{}",sql,entity);
                return sql;
            }else {
                String idName = tableInfo.getColumns()
                        .stream()
                        .filter(ColumnInfo::isPrimaryKey)
                        .findFirst()
                        .get()
                        .getColumn();
                String sql = "select %s from %s where %s in (%s) ";
                String[] arr = new String[entity.size()];
                for (int i = 0; i < entity.size(); i++){
                    arr[i] = "#{ids["+i+"]}";
                }
                sql = String.format(sql,tableInfo.selectColumnAsProperty(),tableName,idName,StringUtils.join(arr,","));
                logger.info("sql->{},params->{}",sql,entity);
                return sql;
            }
        }
    
        public String selectAll(T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            SQL sql =  new SQL()
                    .SELECT(tableInfo.selectColumnAsProperty())
                    .FROM(tableInfo.getTableName());
            String orderBy = tableInfo.orderByColumn();
            if (StringUtils.isNotEmpty(orderBy)){
                sql.ORDER_BY(orderBy);
            }
            return sql.toString();
        }
    
        public String selectPage(PageRequest<T> entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            SQL sql = new SQL()
                    .SELECT(tableInfo.selectColumnAsProperty())
                    .FROM(tableInfo.getTableName());
            String[] where = tableInfo.getColumns().stream()
                    .filter(column -> {
                        Field field = column.getField();
                        T bean = entity.getPageParams();
                        Object value = Util.getFieldValue(bean, field);
                        if (value == null) {
                            return false;
                        }
                        return StringUtils.isNotEmpty(value.toString());
                    })
                    .map(column -> {
                        String param = " #{pageParams." + column.getField().getName()+"}";
                        if (column.getFilterOperator() == FilterOperator.LIKE){
                            param = "concat('%', "+param+", '%')";
                        }
                        if (column.getFilterOperator() == FilterOperator.LEFTLIKE){
                            param = "concat("+param+", '%')";
                        }
                        if (column.getFilterOperator() == FilterOperator.RIGHTLIKE){
                            param = "concat('%', "+param+")";
                        }
                        return column.getColumn()+column.filterOperator()+param;
                    })
                    .toArray(String[]::new);
            sql.WHERE(where);
            if (StringUtils.isNotEmpty(entity.getOrder())){
                ColumnInfo columnInfo = tableInfo.getColumns().stream()
                        .filter(columnInfo1 -> columnInfo1.getField().getName().equalsIgnoreCase(entity.getOrder()))
                        .findFirst().orElse(null);
                if (columnInfo != null){
                    String direction = entity.getOrderDirection();
                    direction = (StringUtils.isEmpty(direction) || direction.equalsIgnoreCase("asc"))?" asc ":" desc ";
                    sql.ORDER_BY(columnInfo.getColumn() + direction);
                }
            }else {
                String orderBy = tableInfo.orderByColumn();
                if (StringUtils.isNotEmpty(orderBy)){
                    sql.ORDER_BY(orderBy);
                }
            }
            sql.OFFSET("#{offset}").LIMIT("#{pageSize}");
            String s = sql.toString();
            logger.info("sql->{},params->{}",s,entity);
            return s;
        }
    
        public String selectCount(T entity, ProviderContext context){
            TableInfo tableInfo = getTableInfo(context);
            SQL sql = new SQL()
                    .SELECT("count(1)")
                    .FROM(tableInfo.getTableName());
            String[] where = tableInfo.getColumns().stream()
                    .filter(column -> {
                        Field field = column.getField();
                        Object value = Util.getFieldValue(entity, field);
                        if (value == null) {
                            return false;
                        }
                        return StringUtils.isNotEmpty(value.toString());
                    })
                    .map(column -> {
                        String param = " #{" + column.getField().getName()+"}";
                        if (column.getFilterOperator() == FilterOperator.LIKE){
                            param = "concat('%', "+param+", '%')";
                        }
                        if (column.getFilterOperator() == FilterOperator.LEFTLIKE){
                            param = "concat("+param+", '%')";
                        }
                        if (column.getFilterOperator() == FilterOperator.RIGHTLIKE){
                            param = "concat('%', "+param+")";
                        }
                        return column.getColumn()+column.filterOperator()+param;
                    })
                    .toArray(String[]::new);
            sql.WHERE(where);
            String s = sql.toString();
            logger.info("sql->{},params->{}",s,entity);
            return s;
        }
    
        private TableInfo getTableInfo(ProviderContext context){
            Class<?> clz = getEntityType(context);
            return tableCache.computeIfAbsent(context.getMapperType(), t-> Util.tableInfo(clz));
        }
    
        private Class<?> getEntityType(ProviderContext context) {
            return Stream.of(context.getMapperType().getGenericInterfaces())
                    .filter(ParameterizedType.class::isInstance)
                    .map(ParameterizedType.class::cast)
                    .filter(type -> type.getRawType() == BaseMapper.class)
                    .findFirst()
                    .map(type -> type.getActualTypeArguments()[0])
                    .filter(Class.class::isInstance)
                    .map(Class.class::cast)
                    .orElseThrow(() -> new IllegalStateException("未找到BaseMapper的泛型類 " + context.getMapperType().getName() + "."));
        }
    
    
    }

    5、實體類轉(zhuǎn)TableInfo

    public static TableInfo tableInfo(Class<?> entityClass) {
            TableInfo info = new TableInfo();
            info.setEntityClass(entityClass);
            Table table = entityClass.getAnnotation(Table.class);
            String tableName = entityClass.getSimpleName();
            if (table != null && StringUtils.isNotEmpty(table.value())){
                tableName = table.value();
            }
            info.setTableName(tableName);
            Field[] allFields = getFields(entityClass);
            Field[] fields = Stream.of(allFields)
                    //過濾@Transient注解的field
                    .filter(field -> !field.isAnnotationPresent(Transient.class))
                    .toArray(Field[]::new);
            List<ColumnInfo> columns = new ArrayList<>();
            int idCount = 0;
            for (Field field:fields){
                ColumnInfo columnInfo = new ColumnInfo();
                columnInfo.setFieldClass(field.getDeclaringClass());
                columnInfo.setField(field);
                Id id = field.getAnnotation(Id.class);
                idCount = idCount + (id == null?0:1);
                columnInfo.setPrimaryKey(id == null?Boolean.FALSE:Boolean.TRUE);
                columnInfo.setPrimaryKeyAuto(id == null?Boolean.FALSE:id.auto());
                Column column = field.getAnnotation(Column.class);
                String columnName = field.getName();
                if (column != null && StringUtils.isNotEmpty(column.value())){
                    columnName = column.value();
                }
                columnInfo.setColumn(columnName);
                FilterOperator filterOperator = FilterOperator.EQ;
                if (column != null && column.filterOperator() != null){
                    filterOperator = column.filterOperator();
                }
                columnInfo.setFilterOperator(filterOperator);
    
                if (columnInfo.isPrimaryKeyAuto()){
                    columnInfo.setInsertable(false);
                }else {
                    columnInfo.setInsertable(true);
                    if (column != null){
                        columnInfo.setInsertable(column.insertable());
                    }
                }
                columnInfo.setUpdatable(true);
                columnInfo.setSelectable(true);
                if (column != null){
                    columnInfo.setSelectable(column.selectable());
                    columnInfo.setUpdatable(column.updatable());
                }
                OrderBy orderBy = field.getAnnotation(OrderBy.class);
                if (orderBy != null){
                    columnInfo.setOrderBy(orderBy.order());
                    columnInfo.setOrderByPriority(orderBy.orderPriority());
                }
                columns.add(columnInfo);
            }
            if (idCount > 1){
                info.setUnionId(Boolean.TRUE);
            }
            info.setColumns(columns);
            return info;
        }

    6、字典字段自動翻譯

    簡單實現(xiàn)思路:對需要翻譯的字段加上@FieldTrans注解來表明這個字段需要翻譯,通過AOP方式對結(jié)果數(shù)據(jù)進(jìn)行增強,來將字段進(jìn)行翻譯更新。

    此部分內(nèi)容留待后續(xù)實現(xiàn),同時調(diào)研一下是否還有更優(yōu)雅簡單的實現(xiàn)方式。

    7、數(shù)據(jù)權(quán)限

    我們先來思考一下數(shù)據(jù)權(quán)限到底要干啥?一句話來概括:查一張表的數(shù)據(jù)時在where條件中追加“and 控制權(quán)限的列 in (???)”。

    簡單實現(xiàn)方法:在控制權(quán)限的字段加上@DataAuthrity注解來表明通過這個字段控制權(quán)限,而???的內(nèi)容肯定是由業(yè)務(wù)代碼來生成的,因此考慮給這個注解增加一個屬性,用來指明權(quán)限數(shù)據(jù)由執(zhí)行哪個接口或方法來獲取。

    此部分內(nèi)容留待后續(xù)實現(xiàn),同時調(diào)研一下是否還有更優(yōu)雅簡單的實現(xiàn)方式。

    使用示例

    1、數(shù)據(jù)庫表

    CREATE TABLE `user` (
      `id` bigint(20) NOT NULL AUTO_INCREMENT,
      `name` varchar(255) DEFAULT NULL,
      `age` int(11) DEFAULT NULL,
      `email` varchar(255) DEFAULT NULL,
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

    2、實體

    @Table("user")
    public class User {
        @Id(auto = true)
        @Column(value = "id")
        private Long id;
    
        @Column(value = "name", filterOperator = FilterOperator.LIKE)
        @OrderBy(orderPriority = 0)
        private String name;
    
        @OrderBy(order = Order.DESC, orderPriority = 1)
        private Integer age;
    
        private String email;
    
        @Transient
        private String test;
    }

    3、Mapper

    public interface UserMapper extends BaseMapper<User, Long> {
    
    }

    至此,不需要寫任何mapper.xml,UserMapper已經(jīng)具備了增刪改查能力。

    4、聯(lián)合主鍵示例

    public class User1 {
        @Id
        @Column(value = "id1")
        private String id1;
        
        @Id
        @Column(value = "id2")
        private String id2;
        
        @Column(value = "name", filterOperator = FilterOperator.LIKE)
        @OrderBy(orderPriority = 0)
        private String name;
        
        @OrderBy(order = Order.DESC, orderPriority = 1)
        private Integer age;
        
        private String email;
        
        @Transient
        private String test;
    }
    
    
    public class User1Id {
        private String id1;
        private String id2;
    }
    
    
    public interface User1Mapper extends BaseMapper<User1,User1Id> {
    }

    “怎么開發(fā)一個MyBatis通用Mapper的輪子”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!

    向AI問一下細(xì)節(jié)

    免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

    AI