众所周知,ibatis是对jdbc的封装,所以要理解ibatis里面的$与#,首先,我们先分析一下jdbc里面的Statement与Preparestatement,
Statement stmt=conn.CreateStatement();
resultSet rs=stmt.executeQuery(sql);
PrepareStatement ptmt=conn.PreparedStatement(sql);
resultSet rs=ptmt.executeQuery();
Statement 是PreparedStatement的父类,
大家请注意sql放置的位置,前者在executeQuery方法里,后者在Preparestatement构造函数里,这就意味着前者是在执行查询的时候才传入sql语句,后者在类构建的时候就传sql语句,而执行查询方法时并没有传入sql语句,所以后者必然是在构建时就已经将sql传送到数据库做预编译,然后在执行查询方法时,直接从数据库缓存中取。
在开发中一般用PrepareStatement,原因多数是安全问题。
比如:
public void queryByName(String username){
String sql = “select * from student where name= ‘ " +username +" ' ";
Statement stmt=conn.CreateStatement();
resultSet rs=stmt.executeQuery(sql);
}
这是一个未经编译的sql语句,如果传入的参数是“linqifeng”,“tom”等参数没有任何问题,但是当传入
"lin' or 1=1;",问题出现了,传入"lin' or 1=1;drop table student;",问题更大。
如果:
public void queryByName(String username){
String sql = “select * from student where name= ?" ;
PrepareStatement ptmt=conn.PreparedStatement(sql);
ptmt.setstring("name",username);
resultSet rs=ptmt.executeQuery();
......
}
这样处理,username不再是sql语句的一部分,而是作为一个字符串参数,它不参与sql语句的编译;
至此,jdbc简单介绍完毕。下面就讲解一下,$与#和前面Statement PreparedStatement的关系,
$ 的作用实际上是字符串拼接,
select * from $tableName$
等效于
StringBuffer sb = new StringBuffer(256);
sb.append("select * from ").append(tableName);
sb.toString();
#用于变量替换
select * from table where id = #id#
等效于
prepareStement = stmt.createPrepareStement("select * from table where id = ?")
prepareStement.setString(1,'abc');