SpringBoot+MyBatis中自动根据@Table注解和@Column注解生成增删改查逻辑

习惯使用jpa操作对象的方式,现在用mybatis有点不习惯。

其实是懒得写SQL,增删改查那么简单的事情你帮我做了呗,mybatis:NO。

没办法,自己搞喽!

这里主要是实现了通过代码自动生成mybatis的增删改查语句,并注册到SqlSessionFactory中,并没有生成xml文件,不生成mapper文件。只是在项目启动的时候自动生成,配置到SqlSessionFactory中,下一次启动后自动根据model自动生成相关逻辑。所以不必担心表结构修改需要改一大堆文件。使用了此方法只需要改model文件就可以了。

注意:model必须添加@Table注解,对应的列也必须添加@Column注解(javax)。

思路:

在项目启动时mybatis默认配置运行结束后添加自定义配置

@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class MyBatisTypeMapScannerConfig {

    private Logger log = Logger.getLogger(MyBatisTypeMapScannerConfig.class);

    public MyBatisTypeMapScannerConfig(ApplicationContext applicationContext, SqlSessionFactory sqlSessionFactory) {
        

在配置中可以获取SqlSessionFactory,看到这里,已经结束了。剩下的都是不重要细节。

1.读取项目下的model(包含@table注解的类)

List<Class<?>> list = ClassUtil.getClassesWithAnnotation(Table.class);

 

2.读取model下的字段(根据@Column注解)

Map<String, Map<String, Object>> cols = ClassUtil.getColumnRelation(clas);

 

3.根据table和column信息配置resultmap,mapper

 

End;

 

代码: MyBatisTypeMapScannerConfig 

 

 

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.persistence.Table;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.session.SqlSessionFactory;

import org.apache.tomcat.util.buf.StringUtils;
import org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;

import com.esri.rest.util.ClassUtil;

/**
 * 自动根据@Table注解和@Column注解添加mybatis中的resultmap配置,
 * 此配置生效后不需要在mapper.xml中手动添加resultmap,自动添加的resultmap的ID为类的全路径名
 * <p>
 * Title: MyBatisTypeMapScannerConfig.java
 * </p>
 * <p>
 * Description:
 * </p>
 * 
 * @author lichao1
 * @date 2018年12月4日
 * @version 1.0
 */
@Configuration
@AutoConfigureAfter(MybatisAutoConfiguration.class)
public class MyBatisTypeMapScannerConfig {

    protected final Log log = LogFactory.getLog(getClass());

    public MyBatisTypeMapScannerConfig(ApplicationContext applicationContext, SqlSessionFactory sqlSessionFactory) {
        log.debug("自动添加resultMap");
        org.apache.ibatis.session.Configuration configuration = sqlSessionFactory.getConfiguration();

        // ResultMap rm = new ResultMap.Builder(configuration, id, type,
        // null).build();
        // configuration.addResultMap(rm);
        // 获取默认包下的所有包含@Table注解的类
        List<Class<?>> list = ClassUtil.getClassesWithAnnotation(Table.class);

        for (Class<?> clas : list) {
            System.out.println(clas);
            Map<String, Map<String, Object>> cols = ClassUtil.getColumnRelation(clas);
            ResultMap rm = new ResultMap.Builder(configuration, clas.getName(), clas,
                    getResultMapping(configuration, cols)).build();
            configuration.addResultMap(rm);
            List<ResultMap> resultMaps = new ArrayList<ResultMap>();
            resultMaps.add(rm);

            Table table = clas.getAnnotation(Table.class);
            String tableName = table.name();
            String allColum = getColumListString(cols);

            // select
            // String sql = " select " + allColum + " from " + tableName;
            // SqlSource sqlSource = new RawSqlSource(configuration, sql, clas);
            // Builder builder = new MappedStatement.Builder(configuration,
            // clas.getName() + ".select", sqlSource,
            // SqlCommandType.SELECT);
            // builder.resultMaps(resultMaps);
            // MappedStatement ms = builder.build();
            // configuration.addMappedStatement(ms);

            InputStream inputStream = createXml(clas, cols);
            XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, clas.getName() + ".auto",
                    configuration.getSqlFragments());
            mapperParser.parse();

        }

        log.debug("自动添加resultMap");
    }

    private InputStream createXml(Class<?> clas, Map<String, Map<String, Object>> cols) {
        StringBuilder builder = new StringBuilder();
        String name = clas.getName();
        Table table = clas.getAnnotation(Table.class);
        String tableName = table.name();
        String allColum = getColumListString(cols);

        builder.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
        builder.append(
                "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\" >");
        builder.append("<mapper namespace=\"" + name + "\" >");

        Set<String> keys = cols.keySet();
        String[] keyArr = new String[keys.size()];
        keys.toArray(keyArr);

        /****************** 查询 start ***************/
        builder.append("<select id=\"" + name + ".select\" resultMap=\"" + name + "\"  >");
        builder.append("SELECT " + allColum + " FROM " + tableName + " WHERE 1=1 ");
        // builder.append(" <if test=\"id != null\"> and id like #{id} </if>");
        // 查询条件
        builder.append(createLikelySql(keyArr, clas, cols));

        // 排序
        builder.append(" <if test=\"ORDERBY != null\"> order by ${ORDERBY} </if>");

        // 分页
        builder.append(" <if test=\"pagestart != null\">  limit  #{pagesize} OFFSET #{pagestart} </if>");

        builder.append("</select>");
        /****************** 查询 end ***************/

        /****************** 计数 start ***************/
        builder.append("<select id=\"" + name + ".count\" resultType=\"long\"  >");
        builder.append("SELECT count(*) count FROM " + tableName + " WHERE 1=1 ");
        builder.append(createLikelySql(keyArr, clas, cols));
        builder.append("</select>");

        /****************** 计数 end ***************/
        
        /****************** 精确查询 start ***************/
        builder.append("<select id=\"" + name + ".selectexactly\" resultMap=\"" + name + "\"  >");
        builder.append("SELECT " + allColum + " FROM " + tableName + " WHERE 1=1 ");
        // builder.append(" <if test=\"id != null\"> and id like #{id} </if>");
        // 查询条件
        builder.append(createExactlySql(keyArr, clas, cols));

        // 排序
        builder.append(" <if test=\"ORDERBY != null\"> order by ${ORDERBY} </if>");

        // 分页
        builder.append(" <if test=\"pagestart != null\">  limit  #{pagesize} OFFSET #{pagestart} </if>");

        builder.append("</select>");
        /****************** 精确查询 end ***************/

        /****************** 精确计数 start ***************/
        builder.append("<select id=\"" + name + ".countexactly\" resultType=\"long\"  >");
        builder.append("SELECT count(*) count FROM " + tableName + " WHERE 1=1 ");
        builder.append(createExactlySql(keyArr, clas, cols));
        builder.append("</select>"); 
        /****************** 精确计数 end ***************/
        
        
        /****************** 自定义条件语句查询 start ***************/
        builder.append("<select id=\"" + name + ".selectwhere\" resultMap=\"" + name + "\"  >");
        builder.append("SELECT " + allColum + " FROM " + tableName + "  "); 
        // 查询条件
        builder.append(" <if test=\"WHERESTR != null\"> WHERE ${WHERESTR} </if>");

        // 排序
        builder.append(" <if test=\"ORDERBY != null\"> order by ${ORDERBY} </if>");

        // 分页
        builder.append(" <if test=\"pagestart != null\">  limit  #{pagesize} OFFSET #{pagestart} </if>");

        builder.append("</select>");
        /****************** 自定义条件语句查询 end ***************/

        /****************** 自定义条件语句计数 start ***************/
        builder.append("<select id=\"" + name + ".countwhere\" resultType=\"long\"  >");
        builder.append("SELECT count(*) count FROM " + tableName + "  ");
        // 查询条件
        builder.append(" <if test=\"WHERESTR != null\"> WHERE ${WHERESTR} </if>");
        builder.append("</select>"); 
        /****************** 自定义条件语句计数 end ***************/
        
        
        

        /****************** 删除 start ***************/
        builder.append("<delete id=\"" + name + ".delete\" parameterType=\"java.lang.String\" >");
        builder.append("  DELETE FROM " + tableName + " WHERE  id =#{id} ");
        builder.append("</delete>");
        /****************** 删除 end ***************/

        /****************** 批量删除 start ***************/
        builder.append("<delete id=\"" + name + ".deletebatch\" >");
        builder.append("  DELETE FROM " + tableName + "    WHERE 1=1  ");
        builder.append(createExactlySql(keyArr, clas, cols));
        builder.append("</delete>");
        /****************** 批量删除 end ***************/

        /****************** 更新 start ***************/
        builder.append("<update id=\"" + name + ".update\"  parameterType=\"" + name + "\"   >");
        builder.append("UPDATE " + tableName + "  SET ");
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            Map<String, Object> obj = cols.get(key);
            builder.append(" " + (String) obj.get("dbname") + " = #{" + key + "}");
            if (i < (keyArr.length - 1)) {
                builder.append(",");
            }
        }
        builder.append(" WHERE  id =#{id} ");
        builder.append("</update>");
        /****************** 更新 end ***************/

        /****************** 按需更新 start ***************/
        builder.append("<update id=\"" + name + ".updatesection\"  parameterType=\"" + name + "\"   >");
        builder.append("UPDATE " + tableName + "  SET ");
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            Map<String, Object> obj = cols.get(key);
            // builder.append(" " + (String) obj.get("dbname") + " = #{" + key +
            // "}");
            if (!"id".equals(key)) {
                 builder.append(" <if test=\"_parameter.containsKey('" + key + "')\">" + (String) obj.get("dbname") + " = #{" + key
                         + "} , </if>");
                // builder.append(" " + (String) obj.get("dbname") + " = #{" + key + "} , ");
            }
        }
        builder.append(" id = #{id} ");
        builder.append(" WHERE  id =#{id} ");
        builder.append("</update>");
        /****************** 按需更新 end ***************/

        /****************** 插入 start ***************/
        builder.append("<insert id=\"" + name + ".insert\" parameterType=\"" + name + "\"  >");
        builder.append("insert  INTO " + tableName + "  (" + allColum + ") VALUES");
        builder.append("(" + getColumListString2(cols, "#{", "}") + ") ");
        builder.append("</insert>");
        /****************** 插入 end ***************/

        builder.append("</mapper>");
        InputStream is = new ByteArrayInputStream(builder.toString().getBytes());
        return is;
    }

    private String createListXml() {
        StringBuilder builder = new StringBuilder();

        return builder.toString();
    }

    /**
     * 生成查询条件语句
     * 
     * @param keyArr
     * @param clas
     * @param cols
     * @return
     */
    private String createLikelySql(String[] keyArr, Class<?> clas, Map<String, Map<String, Object>> cols) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            Map<String, Object> obj = cols.get(key);
            try {
                Class t = (Class) obj.get("type");
                if (t == String.class) {
                    // String 类型自动支持like '%' || #name# || '%'
                    builder.append(" <if test=\"" + key + " != null\"> and " + (String) obj.get("dbname")
                            + " like '%'||#{" + key + "}|| '%' </if>");
                } else {
                    builder.append(" <if test=\"" + key + " != null\"> and " + (String) obj.get("dbname") + " = #{"
                            + key + "} </if>");
                }

            } catch (Exception e) {
                log.info(obj);
                log.info(key);
                log.info(clas.getName());
            }
        }
        return builder.toString();
    }

    private String createExactlySql(String[] keyArr, Class<?> clas, Map<String, Map<String, Object>> cols) {
        StringBuilder builder = new StringBuilder();
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            Map<String, Object> obj = cols.get(key);
            builder.append(
                    " <if test=\"" + key + " != null\"> and " + (String) obj.get("dbname") + " = #{" + key + "} </if>");
        }
        return builder.toString();
    }

    /**
     * 获取表内字段
     * 
     * @param cols
     * @return
     */
    private String getColumListString(Map<String, Map<String, Object>> cols) {
        return getColumListString(cols, "", "");
    }

    private String getColumListString(Map<String, Map<String, Object>> cols, String pre, String end) {
        pre = pre == null ? "" : pre;
        end = end == null ? "" : end;
        Set<String> keys = cols.keySet();
        String[] keyArr = new String[keys.size()];
        String[] nameArr = new String[keys.size()];
        keys.toArray(keyArr);
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            Map<String, Object> obj = cols.get(key);
            if (((String) obj.get("dbname")).equals("update_date")) {
                log.info("key");
            }
            nameArr[i] = pre + (String) obj.get("dbname") + end;
        }
        return StringUtils.join(nameArr);
    }

    private String getColumListString2(Map<String, Map<String, Object>> cols) {
        return getColumListString2(cols, "", "");
    }

    private String getColumListString2(Map<String, Map<String, Object>> cols, String pre, String end) {
        pre = pre == null ? "" : pre;
        end = end == null ? "" : end;
        Set<String> keys = cols.keySet();
        String[] keyArr = new String[keys.size()];
        String[] nameArr = new String[keys.size()];
        keys.toArray(keyArr);
        for (int i = 0; i < keyArr.length; i++) {
            String key = keyArr[i];
            nameArr[i] = pre + key + end;
        }
        return StringUtils.join(nameArr);
    }

    /**
     * 根据@Column注解生成字段映射关系
     * 
     * @param configuration
     * @param Map<String,
     *            Map<String, Object>> cols
     * @return
     */
    private List<ResultMapping> getResultMapping(org.apache.ibatis.session.Configuration configuration,
            Map<String, Map<String, Object>> cols) {
        List<ResultMapping> resultMappings = new ArrayList<ResultMapping>();

        System.out.println(cols);
        Set<String> keys = cols.keySet();
        String[] keyArr = new String[keys.size()];
        keys.toArray(keyArr);

        for (String key : keyArr) {
            String property;
            String column;
            Object javaType;
            Map<String, Object> map = cols.get(key);
            property = key;
            column = (String) map.get("dbname");
            javaType = map.get("type");
            ResultMapping mapping = new ResultMapping.Builder(configuration, property, column, (Class<?>) javaType)
                    .build();
            resultMappings.add(mapping);
        }

        return resultMappings;
    }

}

 

 

 

应用 

 

CommonDaoimpl

 

/**
 * CommonDaoimpl
 * <p>
 * Title: CommonDaoimpl.java
 * </p>
 * <p>
 * Description:
 * </p>
 * 
 * @author lichao1
 * @date 2018年11月19日
 * @version 1.0
 * @param <T>
 * @param <ID>
 */
@Repository
public class CommonDaoimpl<T, ID extends Serializable> implements ICommonDao<T, ID> {

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    public SqlSessionFactory sqlSessionFactory;

    protected <T> String getStatement(Class<T> clazz, String prefix) {
        String entityName = clazz.getSimpleName();
        if (entityName.endsWith("Model")) {
            entityName = entityName.substring(0, entityName.length() - 5);
        }
        if (entityName.endsWith("Entity")) {
            entityName = entityName.substring(0, entityName.length() - 6);
        }
        entityName = prefix + entityName;
        return entityName;
    }

    // Mybatis 查询方法, 只需要输入mapper的命名空间名称和方法名就可以实现数据库操作

    
    /**
     * 执行删除语句
     * @param statement
     * @param parameter
     * @return
     */
    public int deleteByMyBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().delete(statement, parameter);
    }

    /**
     * 执行删除语句
     * @param t
     * @param funName
     * @param parameter
     * @return
     */
    public int deleteByMyBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return deleteByMyBatis(statement, parameter);
    }
    public int deleteByMyBatis(Class<T> t, Object parameter) {
        String statement = t.getName() + "." + "delete";
        return deleteByMyBatis(statement, parameter);
    }

    /**
     * 执行查询列表
     * @param statement
     * @param parameter
     * @return
     */
    public List<T> listByMyBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().selectList(statement, parameter);
    }

    /**
     * 执行查询列表语句
     * @param t
     * @param funName
     * @param parameter
     * @return
     */
    public List<T> listByMyBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return listByMyBatis(statement, parameter);
    }
    
    public List<T> ListByMyBatis(Class<T> t, Object parameter){
        String statement = t.getName() + "." + "select";
        return listByMyBatis(statement, parameter);
    }

    /**
     * 执行插入语句
     * @param statement
     * @param parameter
     * @return
     */
    public int insertByMyBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().insert(statement, parameter);
    }

    /**
     * 执行插入语句
     * @param t
     * @param funName
     * @param parameter
     * @return
     */
    public int insertByMyBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return insertByMyBatis(statement, parameter);
    }

    /**
     * 执行选择一条记录语句
     * @param statement
     * @param parameter
     * @return
     */
    public T selectOneByMyBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().selectOne(statement, parameter);
    }

    /**
     * 执行选择一条记录语句
     * @param t
     * @param funName
     * @param parameter
     * @return
     */
    public T selectOneByMyBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return selectOneByMyBatis(statement, parameter);
    }
    
    /**
     * 计数
     * @param t
     * @param parameter
     * @return
     */
    
    public long countByMyBatis(String statement, Object parameter) {
        return (long)this.sqlSessionFactory.openSession().selectOne(statement, parameter);
    }
    
    public long countByMyBatis(Class<?> t, Object parameter){
        String statement = t.getName() + ".count";
        return countByMyBatis(statement, parameter);
    }

    /**
     * 更新数据
     * @param statement
     * @param parameter
     * @return
     */
    public int updateByMyBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().update(statement, parameter);
    }

    /**
     * 更新数据
     * @param t
     * @param funName
     * @param parameter
     * @return
     */
    public int updateByMyBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return updateByMyBatis(statement, parameter);
    }
    
    public int updateByMyBatis(Class<T> t,  Object parameter) {
        String statement = t.getName() + ".update";
        return updateByMyBatis(statement, parameter);
    }
    
    /**
     * 插入数据
     * @param statement
     * @param parameter
     * @return
     */
    public int insertByMayBatis(String statement, Object parameter) {
        return this.sqlSessionFactory.openSession().insert(statement, parameter);
    }
    
    public int insertByMayBatis(Class<T> t, String funName, Object parameter) {
        String statement = t.getName() + "." + funName;
        return this.sqlSessionFactory.openSession().insert(statement, parameter);
    }
    
    public int insertByMayBatis(Class<T> t, Object parameter) { 
        return insertByMayBatis(t,"insert", parameter);
    }

 

转载于:https://www.cnblogs.com/Leechg/p/10097777.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值