• @InsertProvider 根据bean属性,自动生成插入sql语句


    以Test为例,用mybatis的@InsertProvider的注解插入数据的时候,每次都要写类似于

    Mapper类

    @Mapper
    public interface TestDao {
        
        @InsertProvider(type = TestSqlProvider.class,method="insertAll")
        public void insertOrderLine(@Param("list")List<Test> list);
    
    }
    SqlProvider方法
        public String insertAll(Map map) {
            List<Test> list = (List<Test>) maop.get("list");
            StringBuilder sb = new StringBuilder();
            sb.append("INSERT INTO TEST");
            sb.append("(PKEY,NAME,AGE,SEX");
            sb.append("VALUES");
            MessageFormat mf = new MessageFormat(
                    "#'{'list[{0}].pkey},#'{'list[{0}].name},#'{'list[{0}].age},#'{''list[{0}].sex}");
            for (int i = 0; i < list.size(); i++) {
                sb.append(mf.format(new Object[] { i }));
                if (i < list.size() - 1)
                    sb.append(",");
            }
            return sb.toSting();
        }

    这种方式的话,写法很繁琐,如果字段多,就特别麻烦。所以我在想可不可以通过一种比较通用化的方式,生成插入语句。
    方式:
    用一个注解的形式,记录字段对应的数据库列名
    注解类:

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface Columns {
    
        String value();//字段名
        
        String comment() default "";//注释
        
        
    }

    在Test类的字段中加上@Columns注解

    例如:

        @Columns(value = "PKEY",comment = "主键")
        protected Integer pkey;//主键

    然后写一个工具类,通过反射生成插入语句

    方法:

    public static String getInsertSql(Class<?> clas,int size) {
            String tableName = SCHEMAS + "." + underscoreName(clas.getSimpleName());
            List<Field> fieldList = getSuperFields(clas);
            StringBuilder insertTable = new StringBuilder();
            insertTable.append("INSERT INTO ");
            insertTable.append(tableName);
            StringBuilder columnsStr = new  StringBuilder("(");
            StringBuilder valuesStr = new StringBuilder("(");
            for (int i = 0; i < fieldList.size(); i++) {
                fieldList.get(i).setAccessible(true);
                Columns columns = fieldList.get(i).getAnnotation(Columns.class);
                if (columns != null) {
                    columnsStr.append(columns.value());
                    
                }
                String fieldName = fieldList.get(i).getName();
                if (fieldName.equals("pkey")) {//db2自定生成自增主键的方式,也可以uuid
                    valuesStr.append("default");
                }else {
                    valuesStr.append("#'{'list[{0}].").append(fieldName).append("}");
                }
                if (i < fieldList.size() - 1) {
                    valuesStr.append(",");
                    columnsStr.append(",");
                }
            }
            columnsStr.append(")");
            valuesStr.append(")");
            
            StringBuilder sql = new StringBuilder();
            sql.append(insertTable).append(columnsStr).append("VALUES");
            MessageFormat mf = new MessageFormat(valuesStr.toString());
            for (int i = 0; i < size; i++) {
                sql.append(mf.format(new Object[] { i }));
                if (i < size - 1) {
                    sql.append(",");
                }
            }
            
            return sql.toString();
        }
        
        // 驼峰转大写+下划线,abcAbcaBc->ABC_ABCA_BC
        public static String underscoreName(String name) {
            StringBuilder result = new StringBuilder();
            if ((name != null) && (name.length() > 0)) {
                result.append(name.substring(0, 1).toUpperCase());
                for (int i = 1; i < name.length(); i++) {
                    String s = name.substring(i, i + 1);
                    if ((s.equals(s.toUpperCase())) && (!Character.isDigit(s.charAt(0)))) {
                        result.append("_");
                    }
                    result.append(s.toUpperCase());
                }
            }
            System.err.println("underscoreName:" + result.toString());
            return result.toString();
        }
    
        /**
         * 
         * <p>Title: getSuperFields</p>  
         * <p>Description:获取所有属性,包含父类</p>  
         * @param clas
         * @return
         */
        public static List<Field> getSuperFields(Class<? extends BeanBase> clas) {
            List<Field> fieldList = new ArrayList<>() ;
            while (clas != null) {//取父类属性
                  fieldList.addAll(Arrays.asList(clas .getDeclaredFields()));
                  clas = (Class<? extends BeanBase>) clas.getSuperclass(); //父类
            }
            return fieldList;
        }

    insetAll的写法

        public String insertAll(Map map) {
            List<Test> list = (List<Test>) map.get("list");
            String insertSql = BeanUtils.getInsertSql(Test.class, list.size());
            return insertSql;
        }

    到此就完成了自动化方法,这个只是粗劣的写一下,希望各位看过的大佬,指出不足

  • 相关阅读:
    试题 历届试题 国王的烦恼
    试题 历届试题 九宫重排
    试题 历届试题 网络寻路
    试题 历届试题 危险系数
    试题 历届试题 横向打印二叉树
    试题 历届试题 幸运数
    试题 历届试题 大臣的旅费
    试题 历届试题 连号区间数
    Linux多进行之fork
    linux C语言getopt()函数的使用
  • 原文地址:https://www.cnblogs.com/zhyStudy/p/10532826.html
Copyright © 2020-2023  润新知