今天写JDF框架代码,写到了bean的SQL加工以及变量绑定。就写了个方法,希望大家喜欢。用过的就过来打酱油,没用过的,就过来俯卧撑一把吧。
我们写JAVA代码,在操作数据库用JDBC的方法的时候,会用到SQL的绑定变量。
我们大家一般的做法是用"?" ,然后按"?"的排序给予赋值,但是如果是复杂的SQL,或者说一个好好的SQL,需要在中间加一个条件,那么对应的后面的付值变量都要改动了。例如。
SELECT NAME,ID,? FROM USER WHERE CODE=?
PreparedStatement.setString(1, "AGE");
PreparedStatement.setString(2, "ADMIN");
这里我们绑定了两个变量,一个是动态读取列,一个是条件,如果现在我们由于业务需要,需要再多读一列。
那下面的SQL是这样,那么这里给CODE绑定的变量赋值的索引就要改变了。
SELECT NAME,ID,?,? FROM USER WHERE CODE=?
PreparedStatement.setString(1, "AGE");
PreparedStatement.setString(3, "ADMIN");
PreparedStatement.setString(2, "FLAG");
这里我们可以发现,需要把CODE的赋值的索引给改掉,如果是复杂的SQL,那改动更多,那怎么办呢?
下面我们用这种类型的绑定来做,也就是换个思路,把绑定的变量用name给替换下,通过程序自动排序。
SELECT NAME,ID,?,? FROM USER WHERE CODE=?
替换为
SELECT NAME,ID,:CLUM1,:CLUM2 FROM USER WHERE CODE=:CODE
我们在赋值的时候,做个MAP
HashMap map = new HashMap();
map.put("CODE",new Long(2));
map.put("CLUM1","AGE");
map.put("CLUM2","STATE");
然后写个绑定变量的方法,这里的顺序问题就无所谓了,代码如下:
public static PreparedStatement getStatementValues(Connection con,String sql,HashMap map) throws SQLException{ PreparedStatement stmt = null; ArrayList clumBandNameList = new ArrayList(); //存放绑定变量的名字 String [] temp = sql.split(":"); //这里把变量的名字给取出来 for (int i = 1; i < temp.length; i++) { clumBandNameList.add(temp[i].substring(0,temp[i].indexOf(" "))); } sql = sql.replaceAll(":(.*?)\\s","?");//把绑定变量的名字:XXX 取出为 ?,生成标准SQL stmt = con.prepareStatement(sql); int index = 0; for (int i = 0; i < clumBandNameList.size(); i++) { Object value = map.get(clumBandNameList.get(i)); System.out.println("邦定变量的值:"+clumBandNameList.get(i)+"="+value.toString()); String type = value.getClass().getName().substring(value.getClass().getName().lastIndexOf(".")); //获取绑定的类型 index = i+1; //绑定的索引 if (type.equalsIgnoreCase("String")) { String content = value.toString(); if (content.length() > 2000) { stmt.setCharacterStream(index, new StringReader(content), content.length()); } else { stmt.setString(index, content); } } else if (type.equalsIgnoreCase("Short")) { stmt.setShort(index, Short.parseShort(value.toString())); } else if (type.equalsIgnoreCase("Integer")) { stmt.setInt(index, Integer.parseInt(value.toString())); } else if (type.equalsIgnoreCase("Float")) { stmt.setFloat(index, Float.parseFloat(value.toString())); } else if (type.equalsIgnoreCase("Byte")) { stmt.setByte(index, Byte.parseByte(value.toString())); } else if (type.equalsIgnoreCase("Char")) { stmt.setString(index, value.toString()); } else if (type.equalsIgnoreCase("Long")) { stmt.setLong(index, Long.parseLong(value.toString())); } else if (type.equalsIgnoreCase("Double")) { stmt.setDouble(index, Double.parseDouble(value.toString())); }else if (type.equalsIgnoreCase("Boolean")) { stmt.setBoolean(index, Boolean.getBoolean(value.toString())); } else if (type.equalsIgnoreCase("Date")) { if (value instanceof java.sql.Date) stmt.setDate(index, (java.sql.Date)value); else stmt.setDate(index, java.sql.Date.valueOf(value.toString())); } else if (type.equalsIgnoreCase("Time")) { if (value instanceof Time) stmt.setTime(index, (Time)value); else stmt.setTime(index, Time.valueOf(value.toString())); } else if (type.equalsIgnoreCase("DateTime")) { if (value instanceof Timestamp) stmt.setTimestamp(index, (Timestamp)value); else if (value instanceof java.sql.Date) stmt.setTimestamp(index, new Timestamp(((java.sql.Date)value).getTime())); else stmt.setTimestamp(index, Timestamp.valueOf(value.toString())); } else if(type.equalsIgnoreCase("Timestamp")){ stmt.setTimestamp(index, (Timestamp)value); } else if (value instanceof Character) { stmt.setString(index, value.toString()); } else { stmt.setObject(index, value); } } return stmt; } public static void main(String[] args) { try{ Class.forName("com.mysql.jdbc.Driver").newInstance(); Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "admin"); conn.setAutoCommit(false); //这里便于查看SQL日志,所以把JDBC给代理一下 conn = ConnectionProxy.newInstance(conn); String sql = "INSERT INTO PERSON(PERSON_ID,AGE,FIRSTNAME,LASTNAME,STATE) VALUES(:PERSON_ID ,:AGE ,:FIRSTNAME ,:FIRSTNAME ,:STATE )"; HashMap map = new HashMap(); map.put("PERSON_ID",new Long(2)); map.put("AGE",new Long(22)); map.put("FIRSTNAME","张三"); map.put("STATE",new Long(1)); PreparedStatement p = getStatementValues(conn,sql,map); p.execute(); conn.close(); }catch(Throwable t){ } }
这里唯一的小要求就是SQL的绑定变量 :xx 后面要留个空格,便于正则表达式寻找。这里希望谁能给我个好的正则表达式,这样就可以不用这个了。
上面的程序,我们运行,输出结构如下:
ConnectionId=100000
ConnectionId=100000 Preparing Statement: INSERT INTO PERSON(PERSON_ID,AGE,FIRSTNAME,LASTNAME,STATE) VALUES(? ,? ,?,?,?)
邦定变量的值:PERSON_ID=2
邦定变量的值:AGE=22
邦定变量的值:FIRSTNAME=张三
邦定变量的值:FIRSTNAME=张三
邦定变量的值:STATE=1
PreparedStatementId=100001 Executing Statement: INSERT INTO PERSON(PERSON_ID,AGE,FIRSTNAME,LASTNAME,STATE) VALUES(? ,? ,?,?,?)
PreparedStatementId=100001 Parameters: [2, 22, 张三, 张三, 1]
PreparedStatementId=100001 Types: [java.lang.Long, java.lang.Long, java.lang.String, java.lang.String, java.lang.Long]
大家看看,是不是很简单呢?而且不用为那个索引头疼了。
原创文章,请尊重版权噢:
http://http://blog.csdn.net/keyboardsun
作者KEYBOARDSUN