SQL字段类型与Java类的对应关系

使用PreparedStatement插入记录的过程,首先是调用预插入语句创建PreparedStatement对象,如在上一篇中的示意性代码:

String preparedStatement_insert = "insert into tableName  (col_long,col_string,col_binarystream,col_date ) values (?,?,?,?)";
PreparedStatement pstmt = con.prepareStatement(preparedStatement_insert);
        插入多少个字段的数据由values(?,?,?,?)部分决定,其中的通配符“?”代表了任意类型的数据,而插入什么类型的数据 由字段数据的Java类型决定,通过调用pstmt.setXXX(通配符位号,匹配字段类型的数据)方法实现。

        针对一个已经明确的数据库的表,实现一个具体的PreparedStatement插入操作没有什么难度,因为字段的类型已经明确。而实现一个通用的PreparedStatement插入方法就存在着一定的挑战。JadePool如何实现通用的PreparedStatement插入方法,必需要理清SQL字段类型、SQL字段类型的名称及其与Java类三者之间的对应关系;在JadePool中,Field类把分散在元数据中的相关的字段信息整合在一个对象中,保持了三者之间的对应关系,方便了应用。

        可以这样使用元数据获取字段名、字段的数据类型、字段类型的名称:

        DatabaseMetaData dm = con.getMetaData();
        ResultSet rs = dm.getColumns(catalog, null, tableName, null);
        while (rs.next()) {
            String name = rs.getString("COLUMN_NAME");//参数值可参考dm.getColumns(catalog, null, tableName, null)的帮助文档
            fieldSet.add(lowerCase(name));
            Field f = new Field();
            f.setName(lowerCase(name));
            String dataType = rs.getString("DATA_TYPE");
            f.setSqlType(new Integer(dataType).intValue());//如:java.sql.Types.INTEGER
            String type = rs.getString("TYPE_NAME");//如:BIGINT
            f.setTypeName(lowerCase(type));
            ......
            field_map.put(name.toLowerCase(), f);
        }

        但DatabaseMetaData元数据没有为我们提供字段数据的Java类型,字段数据的Java类型通过以下(ResultSetMetaData元数据)代码获取,这段代码使用了一个小技巧,查询主键值为null的记录,如果没有主键,则将第一个字段当做主键对待。以下这段代码是通过普通的查询,将字段对应的Java类型保存在Field对象中。

            ///给Field属性typeClassName赋值
            String squeryFieldTypeClassName = "select * from " + tableName.toLowerCase() + " where " + table.getFields()[0] + " is null";
            if (table.getKeys().length > 0) {
                squeryFieldTypeClassName = "select * from " + tableName.toLowerCase() + " where " + table.getKeys()[0] + " is null";
            }
            Statement stmt0 = con.createStatement();
            ResultSet rscname = stmt0.executeQuery(squeryFieldTypeClassName);
            ResultSetMetaData rsmd = rscname.getMetaData();
            for (int i = 1; i <= rsmd.getColumnCount(); i++) {
                String fieldNmae = rsmd.getColumnName(i);
                field_map.get(fieldNmae.toLowerCase()).setTypeClassName(rsmd.getColumnClassName(i));//将字段的Java类型保存在Field对象的typeClassName中//通过mssql、mysql、derby
            }
            stmt0.close();
        至此, 通过以上两段代码,我们把字段名、字段的SQL数据类型、SQL数据类型的名称、...以及该字段数据的Java类型的属性值整合到了Field对象中。这为下一步根据条件判断实现通用的PreparedStatement赋值方法奠定了基础。

        JadePool作为简化JDBC编程工具,必须要根据字段数据的Java类型、字段的SQL数据类型等信息实现以下全部或者大部分常用的PreparedStatement的通配符所对应的方法。 以下列出所有的对应通配符的PreparedStatement的方法,涉及到共计约28个Java数据类型,将近50个方法

 
                            java.util.Calendar calendar = new GregorianCalendar(2013, 3 - 1, 13);
                            Object value = new Object();
                            int index = 1;
                            int int_sqlType = java.sql.Types.INTEGER;//4
                            int int_scaleOrLength = 4;
                            int bytes_size = 256;
                            int int_length = 10;
                            long long_length = 10l;
                            String str_sqlTypeName = "LONG";

                            //以下是实现通配符所对应的示意性方法,涉及到共计约28个Java数据类型,将近50个方法。

                            pstmt.setArray(index, (java.sql.Array) value);
                            pstmt.setAsciiStream(index, (java.io.InputStream) value);
                            pstmt.setAsciiStream(index, (java.io.InputStream) value, int_length);
                            pstmt.setAsciiStream(index, (java.io.InputStream) value, long_length);
                            pstmt.setBigDecimal(index, (java.math.BigDecimal) value);
                            pstmt.setBinaryStream(index, (java.io.InputStream) value);
                            pstmt.setBinaryStream(index, (java.io.InputStream) value, int_length);
                            pstmt.setBinaryStream(index, (java.io.InputStream) value, long_length);
                            pstmt.setBlob(index, (java.sql.Blob) value);
                            pstmt.setBlob(index, (java.io.InputStream) value);
                            pstmt.setBlob(index, (java.io.InputStream) value, long_length);
                            pstmt.setBoolean(index, (Boolean) value);
                            pstmt.setByte(index, (byte) 30);
                            pstmt.setBytes(index, (byte[]) value);
                            pstmt.setCharacterStream(index, (java.io.Reader) value);
                            pstmt.setCharacterStream(index, (java.io.Reader) value, int_length);
                            pstmt.setCharacterStream(index, (java.io.Reader) value, long_length);
                            pstmt.setClob(index, (java.sql.Clob) value);
                            pstmt.setClob(index, (java.io.Reader) value);
                            pstmt.setClob(index, (java.io.Reader) value, long_length);
                            pstmt.setDate(index, (java.sql.Date) value);
                            pstmt.setDate(index, (java.sql.Date) value, calendar);
                            pstmt.setDouble(index, (java.lang.Double) value);
                            pstmt.setFloat(index, (java.lang.Float) value);
                            pstmt.setInt(index, (java.lang.Integer) value);
                            pstmt.setLong(index, (java.lang.Long) value);
                            pstmt.setNCharacterStream(index, (java.io.Reader) value);
                            pstmt.setNCharacterStream(index, (java.io.Reader) value, 123l);
                            pstmt.setNClob(index, (java.sql.NClob) value);
                            pstmt.setNClob(index, (java.io.Reader) value);
                            pstmt.setNClob(index, (java.io.Reader) value, 123l);
                            pstmt.setNString(index, (String) value);
                            pstmt.setNull(index, int_sqlType);
                            pstmt.setNull(index, int_sqlType, str_sqlTypeName);
                            pstmt.setObject(index, value);
                            pstmt.setObject(index, value, int_sqlType);
                            pstmt.setObject(index, value, int_sqlType, int_scaleOrLength);
                            pstmt.setRef(index, (java.sql.Ref) value);
                            pstmt.setRowId(index, (java.sql.RowId) value);
                            pstmt.setSQLXML(index, (java.sql.SQLXML) value);
                            pstmt.setShort(index, (java.lang.Short) value);
                            pstmt.setString(index, (java.lang.String) value);
                            pstmt.setTime(index, (java.sql.Time) value);
                            pstmt.setTimestamp(index, (java.sql.Timestamp) value);
                            pstmt.setTimestamp(index, (java.sql.Timestamp) value, calendar);
                            pstmt.setURL(index, (java.net.URL) value);
                            pstmt.setUnicodeStream(index, (java.io.InputStream) value, int_length);
                            
        jadepool-1.0-GBK版本没有完全实现上述通配符所对应的方法,但已经实现了以上常用的方法。JadePool在未来版中,将尽可能的实现上述更多直至全部的方法。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值