場景
下訂單時,將生成一個訂單和對應的多個訂單詳情,即一個 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); }
測試結果:
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, 魚香茄子, 少放油]