#{}和${}区别以及PreparedStatement预编译理解

1,846 阅读1分钟

一.mysql如何开启预编译

Mysql是默认 没有开启预编译的,需要在配置中加上

jdbc:mysql://xxx.22.11.31:3306/dbname?useServerPrepStmts=true

JDBC中使用PreparedStatement来抽象预编译语句,从而使用达到预编译效果。

1:预编译阶段可以对sql语句进行优化。

预编译可以将多个操作步骤合并成一个步骤,一般而言,越复杂的sql,编译程度也会复杂,难度大,耗时,费性能,而预编译可以合并这些操作,预编译之后DBMS可以省去编译直接运行sql。

2:预编译语句可以重复利用。

把一个 sql 预编译后产生的 PreparedStatement 对象缓存下来,下次对于同一个sql,可以直接使用这个缓存的 PreparedState 对象。有兴趣的可以查看mysql驱动包里面的ConnectionImpl类是如何操作预编译的,这里提一下缓存PreparedStatement,在执行预编译时会先去判断是否存在缓存,如果存在则对参数清空,绑定新的参数。如果不存在则调用数据库进行预编译处理生成一个PreparedStatement对象。

那如果按照默认不开启预编译的话,会是什么情况? 每次JDBC都需要编译一条新的sql,即使查询的是同样的sql,也是重新编译一条sql

开启预编译,如果是${}是在此时将参数一起编译,如果是#{}参数不编译,会在执行sql查询的时候,将参数当成字符串放进去,也就是同样的sql语句只需要编译一次。

所以使用${}会编译你参数的这个参数,会有sql风险,而使用#{}仅仅是 select * from t_user where id = xxx ,将参数不编译以字符串的形式,放到xxx的位置,参数你写别的sql想注入 就会报错。 能用#{}尽量用#{}!