合成PreparedStatement插入语句

在JadePool中,支持多种插入记录的方法,最重要、最方便、最常用方法是:

public int insert(String tableName, Map<String, Object> mapRecord) throws SQLException //插入单条记录
public int insert(String tableName, Map<String, Object> mapRecord, boolean autoInsertKey) throws SQLException //插入单条记录,并自动插入主键值
public int insert(String tableName, List<Map> listRecord) throws SQLException插入多条记录
public int insert(String tableName, List<Map> listRecord, boolean autoInsertKey) throws SQLException //插入多条记录,并自动插入主键值

它们都调用底层最核心的方法

private int _preparedStatementInsert(String tableName, List<Map> listRecord, boolean autoInsertKey) throws SQLException

我们从这些方法的参数可以看出,待插入的数据是Map变量或者是List<Map>变量,至于怎样完成插入操作,用户不需要关心,用户只需要把待插入的数据准备好就可以了。在Map变量中,只有键名等于表的字段名的数据才会插入到表中

JadePool是怎样施展魔法,将这些记录插入到数据库中的呢?

先看下面调用PreparedStatement插入记录的示意性代码:

    private java.sql.Connection con;

    public int preparedStatementInsert() throws SQLException, FileNotFoundException {
        String preparedStatement_insert = "insert into tableName  (col_long,col_string,col_binarystream,col_date ) values (?,?,?,?)";
        //设字段1是长整形,字段2是字符串型,字段3是Blob型,字段n是日期型
        PreparedStatement pstmt = con.prepareStatement(preparedStatement_insert);
        pstmt.setLong(1, 123l);
        pstmt.setString(2, "HashMap关系数据映射技术");
        File f = new File("d:\\a.jpg");
        FileInputStream is = new FileInputStream(f);
        pstmt.setBinaryStream(3, is);
        pstmt.setDate(4, new java.sql.Date(System.currentTimeMillis()));
        int num = pstmt.executeUpdate();
        return num;
    }

_preparedStatementInsert会根据参数自动合成PreparedStatement插入语句preparedStatementInsert,这是确保成功插入记录的关键。

_preparedStatementInsert在合成插入语句preparedStatementInsert上做了以下工作:

  • 过滤mapRecord记录中无效字段,得有效字段Object[] fields

  • 根据isUpdateKey对有效字段继续分组:true时,再得主键字段组Object[] keys和非主键字段组Object[]fields

  • 自动组合成PreparedStatement所需要的插入语句,算法如下:

        String preparedStatementInsert = "";

        Map<String, Object> _m = new LinkedHashMap(listRecord.get(0));//获取一条记录,作为创建preparedStatementSQL语句的依据
        Object maxFieldValue = null;
        String[] tableFields = db.getFields(tableName);//表中的字段名的集合 //db是DbCenter的一个实例
        String[] tableKeys = db.getKeys(tableName);//表中的主键字段集
        if (autoInsertKey) {
            Map lastRecord = this.queryLastRecord(tableName);//准备自动插入的主键
            if (tableKeys.length > 0) {
                maxFieldValue = lastRecord.get(tableKeys[0]);
                _m.put(tableKeys[0], "");//防止记录中不含tableKeys[0]主键字段
            } else {
                maxFieldValue = lastRecord.get(tableFields[0]);
                _m.put(tableFields[0], "");//防止记录中不含tableKeys[0]主键字段
            }
        }
        Object[] recordFields = (_m.keySet()).toArray(); //获取记录里的字段名的集合
        //private JadeTool tool = new JadeTool();
        for (int i = 0; i < recordFields.length; i++) {
            if (!tool.isInFields(tableFields, recordFields[i].toString())) {
                _m.remove(recordFields[i].toString());//移除无效字段, 查看记录中的字段在表中是否存在,如果不存在,则移除 
            }
        }

        Object[] fields = (_m.keySet()).toArray(); //过滤后的有效字段
        String[] values = new String[fields.length]; //保存通配符'?'
        for (int i = 0; i < fields.length; i++) {
            values[i] = "?";
        }

        String sql_field = tool.arryToString(fields, ",");
        String sql_values = tool.arryToString(values, ",");
        preparedStatementInsert = "insert into " + tableName + " (" + sql_field + " ) values (" + sql_values + ")";//合成preparedStatement语句

完整地源代码参见源文件ProcessVO.java的方法_preparedStatementInsert。

通过以上算法,可以看出,JadePool不需要xml映射、注入映射,而是通过查询已经实例化的DbCenter实例得到数据库的结构信息;对照数据库结构信息过滤掉无效字段,进一步区分主键字段、非主键字段,针对有效字段进一步合成插入语句;因此,JadePool插入操作具有较高的智能化水平,给JadePool用户带来了方便。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值