1.mybatis 中 #{}和 ${}的区别是什么?
#{}一般都是替换查询数据的id,username,password这种数据库字段
${}一般都是替换查询语句的条件,order by之类的。
#{}是预编译处理,${}是字符串替换。
(1)mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值。
(2)mybatis在处理${}时,就是把${}替换成变量的值。
(3)使用#{}可以有效的防止SQL注入,提高系统安全性。原因在于:预编译机制。
预编译是提前对SQL语句进行预编译,而其后注入的参数将不会再进行SQL编译。我们知道,SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。预编译完成之后,SQL的结构已经固定,即便用户输入非法参数,也不会对SQL的结构产生影响,从而避免了潜在的安全风险。
注:$符号一般用来当作占位符,常使用Linux脚本。例如:$1,$2等等表示输入参数的占位符。
2.mybatis 逻辑分页和物理分页的区别是什么?
物理分页指的是依赖于某一物理实体,即数据库,利用数据库的limit操作。返回的数据量小,每次都访问数据库,对数据库的压力大,实时性强,能时刻了解数据库的最新情况。
逻辑分页指的是依赖于程序员的代码。数据库返回的是全部数据,依靠程序员的代码实现分页。只访问一次数据库,数据库压力小,无法获得数据库的最新状态。
3.mybatis是否支持延迟加载?如果支持,它的实现原理是什么?
Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载,association 指的就是一对一,collection 指的就是一对多查询。在 Mybatis配置文件中,可以配置是否启用延迟加载 lazyLoadingEnabled=true|false。它的原理是,使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用 a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。这就是延迟加载的基本原理。当然了,不光是 Mybatis,几乎所有的包括 Hibernate,支持延迟加载的原理都是一样的。
延迟加载的原理用我自己的理解就是,为目标类建立一个代理,这个代理除了主键都是空的,当调用他的方法的时候就会发现他们是空的,那么就会调用sql语句查询。
4.MyBatis与Hibernate有哪些不同
5.mybatis 分页插件的实现原理是什么?
分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql,然后重写 sql,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。