实现通用的PreparedStatement更新记录的方法

本文分享了一个通用的PreparedStatement方法,用于执行SQL更新操作。该方法适用于多种数据库记录的更新场景,通过预编译SQL语句提高效率并减少SQL注入风险。
摘要由CSDN通过智能技术生成
        在JadePool中,除了常规的更新方法之外,还有以下更新记录的方法,

           1、public int update(String tableName, Map<String, Object> mapRecord, String where) throws SQLException//根据条件更新单条记录
           2、public int update(String tableName, Map<String, Object> mapRecord) throws SQLException//更新单条记录
           3、public int update(String tableName, List<Map> listRecord) throws SQLException  //更新多条记录,主键值不变
           4、public int update(String tableName, List<Map> listRecord, String where) throws SQLException   //根据where条件,更新多条记录,主键值不变

        它们都调用底层最核心的方法
            private int _preparedStatementUpdate(String tableName, List<Map> listRecord, boolean isUpdateKey, String whereStr) throws SQLException

        将使用参数Map变量或者是List<Map>变量更新数据库表中的记录,待 更新的记录的条件是主键值等于mapRecord.get(主键名),在这一组操作中,主键值不变。

        底层核心方法_preparedStatementUpdate同__preparedStatementInsert的共同点有以下几点:
           1、插入语句或更新语句只需要合成一次;
           2、都支持相同的SQL数据类型及其对应的Java类;
           3、都需要实现相同的通配符对应的赋值方法(参见“SQL数据类型与Java类的对应关系”一文);
           4、都整合相同的异常,统一抛出SQLException异常。

        底层核心方法_preparedStatementUpdate同__preparedStatementInsert的区别在于:
           1、合成PreparedStatement的更新语句;
           2、更新数据时,保持主键值不变。

        合成PreparedStatement的更新语句的算法是

        Map<String, Object> _m = new LinkedHashMap(listRecord.get(0));//获取一条记录,作为过滤、分组依据
        String[] tableFields = db.getFields(tableName);//表中的字段
        String[] tableKeys = db.getKeys(tableName);//表中的主键
        Object[] recordFields = (_m.keySet()).toArray(); //获取记录里的字段名的集合
        for (int i = 0; i < recordFields.length; i++) {
            if (!tool.isInFields(tableFields, recordFields[i].toString())) {
                _m.remove(recordFields[i].toString());//移除无效字段, 查看记录中的字段在表中是否存在,如果不存在,则移除到
            }
        }
        Object[] k0 = (_m.keySet()).toArray(); //过滤后的有效字段
        Map<String, Object> key_m = new LinkedHashMap();//记录里的主键
        if (!isUpdateKey) {
            for (int i = 0; i < k0.length; i++) {
                if (tool.isInFields(tableKeys, k0[i].toString())) {//记录中是否有主键
                    key_m.put(k0[i].toString(), _m.remove(k0[i].toString()));//将记录中的主键移到key_m中;保证不对主键更新
                }
            }
        }
        Object[] fields = (_m.keySet()).toArray(); //记录中不包含主键的有效字段;再次过滤掉主键字段的结果
        Object[] keys = (key_m.keySet()).toArray(); //记录中包含的主键


        if (isUpdateKey) {
            if (keys.length == 0 || keys.length != tableKeys.length) {
                return num;
            }
        }


        String[] kss = new String[fields.length]; //保存"键名=?"
        for (int i = 0; i < fields.length; i++) {
            kss[i] = fields[i].toString() + "=?";
        }

        String n_v = tool.arryToString(kss, ",");

        String preparedStatementUpdate = "update " + tableName + " set " + n_v + " ";
        //System.out.println(preparedStatementUpdate);


        完整的_preparedStatementUpdate代码

    /**
     * 使用PreparedStatement更新多条记录 本方法是根据JDBC API类名的判断来存贮数据<br/>
     * 为了方便表单数据的录入,本方法提供了用字符串来表达Integer|Long|Short|Float|Double|Bigdecimal|java.sql.Date等常规类型的支持,<br/>
     * 但请注意:用字符串表达Date时,目前java.sql.Date仅支持将"yyyy-mm-dd"格式转换成Date对象;<br/>
     * 对于其它类型,用户必须建立相应类型的对象; 本方法提供了对上传文件的支持; 零长度字符串将保存为null。<br/>
     * 详细的数据类型,可参阅《Java开发者年鉴》p700 PreparedStatement的setXXX方法<br/>
     *
     *
     * 完成更新的步骤: 1、过滤记录中无效字段,得有效字段Object[] fields<br/>
     * 2、根据isUpdateKey对有效字段继续分组:!true时,再得主键字段组Object[] keys和非主键字段组Object[]
     * fields<br/> 3、自动生成PreparedStatement所需的更新操作<br/> 4、迭代记录for (Map record :
     * listRecord) {}<br/> 5、执行PreparedStatement的executeUpdate(updateSQL);<br/>
     *
     *
     * @param tableName 是一个表名
     * @param listRecord 是具有相同结构的一组记录
     * @param isUpdateKey 是否更新主键
     * @param whereStr
     * 是操作条件,插入时不起作用,更新时,若where==null||"".equals(where),则自动根据记录自身主键字段的键值对组合where条件语句
     * 是从LinkedHashMap参数中获取的值
     * @throws SQLException
     */
    private int _preparedStatementUpdate(String tableName, List<Map> listRecord, boolean isUpdateKey, String whereStr) throws SQLException {
        int num = 0;
        if (listRecord == null || listRecord.isEmpty()) {
            return num;
        }
        Map<Stri
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值