zoukankan      html  css  js  c++  java
  • 反射生成 INSERT 多个对象的 SQL 语句(批量插入)

    场景

    下订单时,将生成一个订单和对应的多个订单详情,即一个 order 对象和多个 orderinfo 对象。

    多个 orderinfo 对象在落库时,DAO 层向上层调用的接口入参是 List<OrderInfo>,那么接口的实现就需要将 List<OrderInfo> 转为一条完整的 SQL 语句。

    如:

    insert into person(name, age, info) values ('18岁的郑斌', 18, '大一'),('22岁的郑斌', 22, '大四');

    下面通过反射的方法,生成带有占位符的 SQL,和填充占位符的数据数组。

    源码

    private static void insertObject(List<?> objectList) throws IllegalAccessException {
            /**
             * 比如:
             * SQL 语句:insert into person(name, age, info) values ('...', '...', '...');
             * 其中 values 改为占位符:
             * SQL 语句:insert into person(name, age, info) values (?, ?, ?);
             * 再获取所有的数据值 Object 数组
             * [zhengbin, 21, 要毕业了]
             */
            // 确定占位符的个数(即对象中不为 null 的字段个数)
            int columnNum = 0;
            // 插入数据的列名
            StringBuilder columns = new StringBuilder("(");
            // 填充占位符的值(即对象中不为null的字段的值)
            List<Object> valuesList = new ArrayList<Object>();
            // 如果为空则不执行
            if (CollectionUtil.isEmpty(objectList)) {
                return;
            }
            // 通过 List 中的第一个 Object,确定插入对象的字段
            Object object = objectList.get(0);
            Class clazz = object.getClass();
            Field[] fields = clazz.getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                if (field.get(object) != null) {
                    columnNum++;
                    columns.append(field.getName()).append(", ");
                    valuesList.add(field.get(object));
                }
            }
            columns.replace(columns.lastIndexOf(", "), columns.length(), ")");
    
            // 获取所有的值
            for (int i = 1; i < objectList.size(); i++) {
                for (Field field : fields) {
                    field.setAccessible(true);
                    if (field.get(objectList.get(i)) != null) {
                        valuesList.add(field.get(objectList.get(i)));
                    }
                }
            }
            // 确定一个 Object 的占位符 '?'
            StringBuilder zhanweifuColumn = new StringBuilder("(");
            for (int i = 0; i < columnNum; i++) {
                zhanweifuColumn.append("?, ");
            }
            zhanweifuColumn.replace(zhanweifuColumn.lastIndexOf(", "), zhanweifuColumn.length(), ")");
    
            // 确定所有的占位符
            int objectNum = objectList.size();
            StringBuilder zhanweifu = new StringBuilder();
            for (int j = 0; j < objectNum; j++) {
                zhanweifu.append(zhanweifuColumn.toString()).append(", ");
            }
            zhanweifu.replace(zhanweifu.lastIndexOf(", "), zhanweifu.length(), "");
    
            // 生成最终 SQL
            String sql = "INSERT INTO " + object.getClass().getSimpleName().toLowerCase() + " " + columns + " VALUES " + zhanweifu.toString();
            System.out.println(sql);
            System.out.println(valuesList);
        }

    测试

    public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {
            List<OrderInfo> orderInfos = new ArrayList<OrderInfo>();
            OrderInfo orderInfo1 = new OrderInfo();
            orderInfo1.setOrder_id(10);
            orderInfo1.setFood_id(1);
            orderInfo1.setPrice(18d);
            orderInfo1.setNum(1);
            orderInfo1.setTotal_price(18d);
            orderInfo1.setFood_name("宫保鸡丁");
            orderInfo1.setRemark("少放辣椒");
    
            OrderInfo orderInfo2 = new OrderInfo();
            orderInfo2.setOrder_id(10);
            orderInfo2.setFood_id(1);
            orderInfo2.setPrice(16d);
            orderInfo2.setNum(1);
            orderInfo2.setTotal_price(16d);
            orderInfo2.setFood_name("鱼香茄子");
            orderInfo2.setRemark("少放油");
    
            orderInfos.add(orderInfo1);
            orderInfos.add(orderInfo2);
    
            insertObject(orderInfos);
        }
    View Code

    测试结果:

    INSERT INTO orderinfo (order_id, food_id, price, num, total_price, food_name, remark) VALUES (?, ?, ?, ?, ?, ?, ?), (?, ?, ?, ?, ?, ?, ?)
    [10, 1, 18.0, 1, 18.0, 宫保鸡丁, 少放辣椒, 10, 1, 16.0, 1, 16.0, 鱼香茄子, 少放油]
  • 相关阅读:
    GIT 相关
    createFile
    值传递、指针传递、引用传递
    Sightseeing trip
    find the longest of the shortest
    Laurenty and Shop
    Dima and Lisa
    Marina and Vasya
    Kolya and Tanya
    Two Substrings
  • 原文地址:https://www.cnblogs.com/zhengbin/p/6855868.html
Copyright © 2011-2022 走看看