首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

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

2013-03-19 
实现通用的PreparedStatement更新记录的方法在JadePool中,除了常规的更新方法之外,还有以下更新记录的方法

实现通用的PreparedStatement更新记录的方法
        在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的更新语句的算法是

    /**     * 使用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<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);        PreparedStatement pstmt = null;        try {            if (whereStr != null) {                pstmt = con.prepareStatement(preparedStatementUpdate + whereStr);//如果whereStr!=null,从这里执行PrepareStatement更新            }            for (Map record : listRecord) {                if (whereStr == null) {                    String _w = "";                    if (keys.length > 0) {                        Field f = db.getField(tableName, keys[0].toString());                        Object _o = record.get(keys[0].toString());                        String _s = "";                        if (f.getTypeClassName().equals("java.lang.String")) {                            _s = keys[0].toString() + " like '" + _o.toString() + "'";                        } else {                            _s = keys[0].toString() + " = " + _o.toString();                        }                        if (keys.length > 1) {                            for (int i = 1; i < keys.length; i++) {                                f = db.getField(tableName, keys[i].toString());                                _o = record.get(keys[i].toString());                                if (f.getTypeClassName().equals("java.lang.String")) {                                    _s = _s + " and " + keys[i].toString() + " like '" + _o.toString() + "'";                                } else {                                    _s = _s + " and " + keys[i].toString() + " = " + _o.toString();                                }                            }                        }                        _w = " where " + _s;                    }                    //System.out.println(preparedStatementUpdate + _w);//批量更新                    pstmt = con.prepareStatement(preparedStatementUpdate + _w);//如果whereStr==null,从这里执行PrepareStatement更新//条件不同,只能逐条变更插入语句                }                //为了提高运算效率,规定判断条件优先顺序:常用标准条件精确匹配、标准条件精确匹配、非标准条件精确匹配、非标准条件概略匹配、非标准条件概略小写匹配                for (int i = 0; i < fields.length; i++) {                    Field f = db.getField(tableName, fields[i].toString());                    String className = f.getTypeClassName();                    int index = f.getSqlType();                    Object v = record.get(fields[i].toString());                    if (v == null) {                        pstmt.setNull(i + 1, index);//continue;                    } else if (v != null) {                        String _c = ((Class) v.getClass()).getName(); //增加对表单数据的支持,在表单中获取的数据均为String型,固应对其进行转换.                        if ((_c.equals("java.lang.String")) && ("".equals(((String) v).trim()))) {                            pstmt.setNull(i + 1, index);//continue;                        } else {                            if (className.equals("java.lang.String")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setString(i + 1, (String) v);                                }                                continue;                            }                            if (className.equals("java.lang.Integer")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setInt(i + 1, Integer.parseInt((String) v));                                } else {                                    if (_c.equals("java.lang.Integer")) {                                        pstmt.setInt(i + 1, ((Integer) v).intValue());                                    } else {                                        Integer n = new Integer(v.toString());                                        pstmt.setInt(i + 1, n);                                    }                                }                                continue;                            }                            if (className.equals("java.lang.Long")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setLong(i + 1, Long.parseLong((String) v));                                } else {                                    if (_c.equals("java.lang.Long")) {                                        pstmt.setLong(i + 1, ((Long) v).longValue());                                    } else {                                        Long l = new Long(v.toString());                                        pstmt.setLong(i + 1, l);                                    }                                }                                continue;                            }                            if (className.equals("java.lang.Short")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setShort(i + 1, Short.parseShort((String) v));                                } else {                                    pstmt.setShort(i + 1, ((Short) v).shortValue());                                }                                continue;                            }                            if (className.equals("java.lang.Float")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setFloat(i + 1, Float.parseFloat((String) v));                                } else {                                    pstmt.setFloat(i + 1, ((Float) v).floatValue());                                }                                continue;                            }                            if (className.equals("java.lang.Double")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setDouble(i + 1, Double.parseDouble((String) v));                                } else {                                    pstmt.setDouble(i + 1, ((Double) v).doubleValue());                                }                                continue;                            }                            if (className.equals("java.lang.Boolean")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setBoolean(i + 1, (Boolean.valueOf((String) v)).booleanValue());                                } else {                                    pstmt.setBoolean(i + 1, ((Boolean) v).booleanValue());                                }                                continue;                            }                            if (className.equals("java.sql.Timestamp")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    String _s = ((String) v).trim();                                    if (tool.matches(RegexType.chinaDate, _s)) {//如:2012-01-24                                        Time t = new Time(0l);                                        _s = _s + " " + t.toString();                                        pstmt.setTimestamp(i + 1, java.sql.Timestamp.valueOf(_s));                                    } else {                                        pstmt.setTimestamp(i + 1, java.sql.Timestamp.valueOf((String) v));                                    }                                } else if (className.equals("java.sql.Date")) {                                    java.sql.Date _v = (java.sql.Date) v;                                    pstmt.setTimestamp(i + 1, new Timestamp(_v.getTime()));                                } else if (className.equals("java.util.Date")) {                                    java.util.Date _v = (java.util.Date) v;                                    pstmt.setTimestamp(i + 1, new Timestamp(_v.getTime()));                                } else if (className.equals("java.sql.Time")) {                                    java.sql.Time _v = (java.sql.Time) v;                                    pstmt.setTimestamp(i + 1, new Timestamp(_v.getTime()));                                } else {                                    pstmt.setTimestamp(i + 1, new Timestamp(((java.util.Date) v).getTime()));//能支持更多的应用                                    //pstmt.setTimestamp(i + 1,  (java.sql.Timestamp) v);//使用jsf日期转换后获得的结果可能不完整,这时会出现转换异常                                }                                continue;                            }                            if (className.equals("java.sql.Date") || className.equals("java.util.Date")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setDate(i + 1, java.sql.Date.valueOf((String) v));                                } else if (className.equals("java.util.Date")) {                                    java.util.Date _v = (java.util.Date) v;                                    pstmt.setDate(i + 1, new java.sql.Date(_v.getTime()));                                } else {                                    pstmt.setDate(i + 1, (java.sql.Date) v);                                }                                continue;                            }                            if (className.equals("java.sql.Time")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setTime(i + 1, java.sql.Time.valueOf((String) v));                                } else {                                    pstmt.setTime(i + 1, (java.sql.Time) v);                                }                                continue;                            }                            if (className.equals("[B") || className.equals("byte[]")) {                                //SQL Server 的image、timestamp、binary类型是byte[],MySQL 的blob系列是java.lang.Object,Sybase的image是[B                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setBytes(i + 1, ((String) v).getBytes());                                } else {                                    pstmt.setBytes(i + 1, (byte[]) v);                                }                                continue;                            }                            if (className.equals("java.sql.Blob")) {                                //SQL Server 的image、timestamp、binary类型是byte[],MySQL 的blob系列是java.lang.Object,Sybase的image是[B                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setBytes(i + 1, ((String) v).getBytes());                                } else {                                    pstmt.setBlob(i + 1, (java.sql.Blob) v);                                }                                continue;                            }                            if (className.equals("java.lang.Object")) {                                //SQL Server 的image、timestamp、binary类型是byte[],MySQL 的blob系列是java.lang.Object,Sybase的image是[B                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setBytes(i + 1, ((String) v).getBytes());                                } else {                                    pstmt.setObject(i + 1, v);                                }                                continue;                            }                            if (className.equals("java.lang.Byte")) {                                //MySQL的tinyint是java.lang.Byte                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setByte(i + 1, java.lang.Byte.parseByte((String) v));                                } else {                                    pstmt.setByte(i + 1, java.lang.Byte.parseByte(v.toString()));                                }                                continue;                            }                            if (className.equals("java.math.BigDecimal")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setBigDecimal(i + 1, new BigDecimal((String) v));                                } else {                                    pstmt.setBigDecimal(i + 1, (BigDecimal) v);                                }                                continue;                            }                            //以下部分将根据具体的数据库需要而定,有待验证                            if (className.equals("java.sql.Clob")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setString(i + 1, (String) v);//给clob类型的字段赋予字符串型                                } else {                                    pstmt.setClob(i + 1, (java.sql.Clob) v);                                }                                continue;                            }                            //以下部分将根据具体的数据库需要而定,有待验证                            if (className.equals("java.sql.Array")) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    //                                } else {                                    pstmt.setArray(i + 1, (java.sql.Array) v);                                }                                continue;                            }                            //特殊类型,非常用,置后                            if (className.equals("com.sybase.jdbc2.tds.SybTimestamp") || className.toLowerCase().indexOf("timestamp") > 0) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setTimestamp(i + 1, java.sql.Timestamp.valueOf((String) v));                                } else {                                    pstmt.setTimestamp(i + 1, (java.sql.Timestamp) v);                                }                                continue;                            }                            //概略匹配                            if (className.toLowerCase().indexOf("date") > 0) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setDate(i + 1, java.sql.Date.valueOf((String) v));                                } else {                                    pstmt.setDate(i + 1, new java.sql.Date(((java.util.Date) v).getTime()));                                }                                continue;                            }                            if (className.toLowerCase().indexOf("time") > 0) {                                if ((_c.equals("java.lang.String")) && (!"".equals(((String) v).trim()))) {                                    pstmt.setTime(i + 1, java.sql.Time.valueOf((String) v));                                } else {                                    pstmt.setTime(i + 1, (java.sql.Time) v);                                }                                continue;                            }                            if (_c.equals("java.io.FileInputStream")) {                                //调用如:FileInputStream in = new FileInputStream("D:\\test.jpg");的结果                                pstmt.setBinaryStream(i + 1, (FileInputStream) v, ((FileInputStream) v).available());                                continue;                            }//java.io.FileInputStream                            //其它特殊类型,非常用,置后,更多的setXXX方法详见《年鉴》p700                        }                    }                }                num = num + pstmt.executeUpdate();            }        } catch (java.lang.ClassCastException ex) {            throw new SQLException("java.lang.ClassCastException: " + ex.getMessage(), ex.getCause());        } catch (NumberFormatException ex) {            throw new SQLException("NumberFormatException: " + ex.getMessage(), ex.getCause());        } catch (IOException ex) {            throw new SQLException("IOException: " + ex.getMessage(), ex.getCause());        } finally {            pstmt.close();        }        return num;    }


        通配符对应的赋值方法参见“SQL数据类型与Java类的对应关系”一文






热点排行