使用反射简化批量保存sql语句

写批量保存的时候遇到实体类字段比较多的时候写起来非常的头疼,所以我想能不能通过程序自动获取拼接

思路:

1.通过反射获取实体类的所有字段

2.把字段拼接为id,user_name,user_age  和 #{item.id},#{item.userName},#{item.userAge}两种字符串

获得字符串的代码:

复制代码
public static List<Field> getFields(Class<?> clazz) {
        List<Field> fieldList = new ArrayList<>(Lists.newArrayList(clazz.getDeclaredFields()));
        if (!(clazz.getSuperclass().isAssignableFrom(Object.class))) {
            fieldList.addAll(getFields(clazz.getSuperclass()));
        }
        return fieldList;
    }

    /**
     * @param clazz 数据实体类class 注意:字段名一定要驼峰命名
     * @param item  foreach item名,默认为item
     * 获得批量保存数据库字段拼接后的字段 (为数据库批量保存删除用)例如:top = id,user_name,user_age
     *                                   under = #{item.id},#{iitem.userName},#{item.userAge},
     **/
    public static Map<String,String> getTopAndUnder(Class<?> clazz,String item){
        Map<String, String> map = new HashMap<>();
        if(StringUtils.isBlank(item)){
            item = "item";
        }
        List<Field> fields = getFields(clazz);
        List<String> topColumns = new ArrayList<>();
        if(CollectionUtils.isEmpty(fields)){
            map.put("top",null);
            map.put("under",null);
            return map;
        }

        List<String> underColumns = new ArrayList<>();
        for (Field field : fields) {
            //是静态的字段就跳过
            if (Modifier.isStatic(field.getModifiers())) {
                continue;
            }
            underColumns.add("#{"+item + "." + field.getName() + "}");
            String s = toUnderScoreCase(field.getName());
            topColumns.add(s);
        }
        if(!CollectionUtils.isEmpty(topColumns)){
            String top = StringUtils.join(topColumns, ",");
            map.put("top",top);
        }else {
            map.put("top",null);
        }
        if(!CollectionUtils.isEmpty(underColumns)){
            String under = StringUtils.join(underColumns, ",");
            map.put("under",under);
        }else {
            map.put("top",null);
        }

        return map;
    }

**
 * 驼峰命名方法
 *
 * @return toCamelCase(" hello_world ") == "helloWorld"
 * toCapitalizeCamelCase("hello_world") == "HelloWorld"
 * toUnderScoreCase("helloWorld") = "hello_world"
 */
public static String toUnderScoreCase(String s) {
    if (s == null) {
        return null;
    }

    StringBuilder sb = new StringBuilder();
    boolean upperCase = false;
    for (int i = 0; i < s.length(); i++) {
        char c = s.charAt(i);

        boolean nextUpperCase = true;

        if (i < (s.length() - 1)) {
            nextUpperCase = Character.isUpperCase(s.charAt(i + 1));
        }

        if ((i > 0) && Character.isUpperCase(c)) {
            if (!upperCase || !nextUpperCase) {
                sb.append(SEPARATOR);
            }
            upperCase = true;
        } else {
            upperCase = false;
        }

        sb.append(Character.toLowerCase(c));
    }

    return sb.toString();
}
复制代码

service层代码:

复制代码
public Integer batchSave(List<User> list,Integer num) {
        if(CollectionUtils.isEmpty(list) || null == num || num <= 0){
            return 0;
        }
        Map<String, String> topAndUnder = getTopAndUnder(User.class,null);
        if(!CollectionUtils.isEmpty(topAndUnder)){
            String join = topAndUnder.get("top");
            String underColumn = topAndUnder.get("under");
            if(StringUtils.isBlank(join) || StringUtils.isBlank(underColumn)){
                return 0;
            }
            if(list.size() <= num){
                return userMapper.batchSave(join,underColumn,list);
            }else {
                //数据量大进行分割,自己把握
                List<List<User>> partition = ListUtils.partition(list, num);
                Integer i = 0;
                for (List<User> user : partition) {
                    i = userMapper.batchSave(join,underColumn,user);
                }
                return i;
            }
        }else {
            return 0;
        }
    }
复制代码

数组分割工具类ListUtils:

复制代码
public class ListUtils {
    public static <T> List<List<T>> partition(final List<T> list, final int size) {
        if (list == null) {
            throw new NullPointerException("List must not be null");
        }
        if (size <= 0) {
            throw new IllegalArgumentException("Size must be greater than 0");
        }
        return new Partition<>(list, size);
    }

    private static class Partition<T> extends AbstractList<List<T>> {
        private final List<T> list;
        private final int size;

        private Partition(final List<T> list, final int size) {
            this.list = list;
            this.size = size;
        }

        @Override
        public List<T> get(final int index) {
            final int listSize = size();
            if (index < 0) {
                throw new IndexOutOfBoundsException("Index " + index + " must not be negative");
            }
            if (index >= listSize) {
                throw new IndexOutOfBoundsException("Index " + index + " must be less than size " +
                        listSize);
            }
            final int start = index * size;
            final int end = Math.min(start + size, list.size());
            return list.subList(start, end);
        }

        @Override
        public int size() {
            return (int) Math.ceil((double) list.size() / (double) size);
        }

        @Override
        public boolean isEmpty() {
            return list.isEmpty();
        }
    }

}
复制代码

mapper层代码:

 /**
     * 批量保存
     * @param list 数据
     */
    Integer batchSave(@Param("stringColumn")String stringColumn,
                      @Param("underColumn")String underColumn,
                      @Param("list")List<User> list);
<insert id="batchSave">
        INSERT INTO t_user(${stringColumn})
        VALUES 
        <foreach collection="list" item="item" separator=",">
            (${underColumn})
        </foreach>
 </insert>

 

posted @   时光里的少年  阅读(56)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示