反射生成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);
    }

测试结果:

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, 鱼香茄子, 少放油]
时间: 2024-11-06 10:14:05

反射生成INSERT多个对象的SQL语句的相关文章

C#与数据库访问技术总结(六)之Command对象创建SQl语句代码示例

Command对象创建SQl语句代码示例 说明:前面介绍了 Command 对象的方法和一些属性,回顾一下 Command对象主要用来执行SQL语句.利用Command对象,可以查询数据和修改数据. 在下面这段代码里,首先根据连接字符串创建一个SqlConnecdon连接对象,并用此对象连接数据源:然后创建一个SqlCommand对象,并用此对象的ExecuteNonQuery方法执行不带返回结果集的SQL语句. 1 //连接字符串 2 3 private static string strCo

python脚本批量生成50000条插入数据的sql语句

1 f = open("xx.txt",'w') 2 for i in range(1,50001): 3 str_i = str(i) 4 realname = "lxs"+str_i 5 phone = 13678101715 + i 6 email = "lxs" + str_i +"@126.com" 7 sql = 'insert into table_a (realname,phone,email,sign,eve

生成表结构数据库文档sql语句

CREATE PROCEDURE [dbo].[生成表结构数据库文档]ASBEGIN -- SET NOCOUNT ON added to prevent extra result sets from -- interfering with SELECT statements. SET NOCOUNT ON; -- Insert statements for procedure here SELECT 表名 = Case When A.colorder=1 Then D.name Else ''

生成批量删除多个表sql语句

--批量删除多个表 select 'drop table ' +name from sysobjects where type = 'U' order by name

Java注解项目实战即模拟Hibenernate生成sql语句

整理了近期学习java注解的部分代码 ,借助java注解模拟Hibenernate ORM模型建立对象与sql语句的映射 Table 注解的创建 package com.imooc.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.

如何通过sql语句快速生成 删除表的sql

select 'drop table '+name tablename from sysobjects where xtype='U' and name like 'ta_bsk%' 备注: 从系统表(sysobjects)中查询类型是用户表(xtype='U')表名以ta_bsk开头的表名(name like '%ta_bsk%'),拼接上'drop table'就生成了我想要的sql语句了.哈哈

ORACLE数据库SQL语句的执行过程

首先是最简单链接数据库的过程,JDBC标准的链接的过程: 1. 载入JDBC驱动程序,一般来说载入驱动程序,采用的都是利用Class.forName()反射来加载驱动 Oracle: Class.forName("oracle.jdbc.driver.OracleDriver"); SQLServer: Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver"); MySql: Class.forNam

数据库-转换sql语句

文章描述:主要说明转换成SQL语句的过程.----必要信息(数据库名,表名,条件)转换成SQL语句 一些界面上数据增删改查的操作往往只需要输入一数据库名,表名,加条件就可以进行数据查询了,在这背后是怎么实现了呢,这些程序有些是使用封装的方法,有些直接输入sql语句进行操作,封装的方法最后也是将查询条件(上面输入操作)转换为SQL语句用Statement对象对应方法进行相关操作 而Statement对象获得SQL语句后怎么执行查询(这个不归statement管了),Statement这里是通过jd

SQL语句全解析

一.基本的建库.建表操作(增删改查略去不讲) --创建数据库School Create database School --使用数据库 Use School --创建学生表(SID为自增主键,Ssex有Check约束,且所有字段,均不为空) create  table Student(SID int identity not null primary key,Sname nvarchar(30) not null,Sage int not null, Ssex nvarchar(5) check