mybatis之所以优先使用xml编写sql代码主要是当修改sql的时候代码不用重新编译,解耦性更好。
${}会直接对sql进行字符串拼接,在特殊情况下使用#{}会出现问题
select * from #{table_name}
//table_name = "test",解析后
select * from "test"
//使用${table_name},解析后
select * from test
使用#{}
使用${}, 直接进行字符串的拼接
#{}是可以防止sql注入的,预处理阶段使用?代替,真正查询的时候才传入参数,类似于jdbc中的PreparedStatement。
总结: 在传入表名,字段名的时候直接使用${},其他的时候就使用#{}
if test返回true的时候把if中的sql片段拼接进入sql语句。
choose when otherwise 可以实现类似于 if...else 的功能
where 当where标签包含的元素有返回值的时候在sql中加where,where 后面字符串以and or开头就去掉
update语句中的 set 标签 ,set标签包含的元素有返回值的时候在sql中加set , set 后面的字符串以,结尾就去掉
where标签和set标签是trim的特殊情况,也就是说可以使用trim来实现where和set标签,trim标签的属性如下:
foreach 标签用来循环拼接,可以实现sql中的实现in ,批量插入等
bind 标签可以创建一个变量,用于字符串拼接或者打印其他变量的值等。
OGNL 支持逻辑运算与,非,大于,小于等,可以使用类的静态方法,对象的方法和字段。if when的 test bind 的 value属性都支持OGNL
直接在sql语句中使用as进行把关联对象的属性和查询出来的字段对应起来
使用resultMap的result标签把关联对象的属性和查询出来的字段对应起来
使用resultMap标签中的 association 标签,指定一个resultMap,把关联对象的属性和查询出来的字段对应起来
此时association标签常用的属性
前三种方法都是使用一次sql查询就查询出结果,这样导致的问题就是sql编写复杂,容易出错。
使用resultMap标签中的 association 实现嵌套查询实现一对一查询。也就是执行多次sql完成查询。
此时association的常用属性如下
column 中使用column={ prop1=col1,prop2=co12} 这种格式对应的 select 标签中不能使用 parameterType 属性。使用 parameterType 属性会报错.
我的理解就是使用column={ prop1=col1,prop2=co12} 这个方式传送的可能不只一个参数,那么select标签中的parameterType 只能指定一个参数的类型,如果column中的参数不一致,这样就会发生错误。
<association property="teacher" column="{id=teacher_id}" select="com.example.mybatis_practice.yogurt.dao.TeacherMapper.selectByPrimaryKey" fetchType="lazy"/>
如果就使用标签 column=col1 传输一个参数 这种格式对应的 select 标签中能使用 parameterType 属性。
<association property="teacher" column="teacher_id" select="com.example.mybatis_practice.yogurt.dao.TeacherMapper.selectByPrimaryKey" fetchType="lazy" />
值得注意的是我们通常开启全局懒加载模式避免 N+1 问题,就是使用selectAll 返回N条数据,对每条数据都进行嵌套查询,一共要执行N次嵌套查询。还有就是生命周期的问题,sqlSession 会在控制层的时候被销毁,所以在控制层进行懒加载会出错。
在resultMap中,进行一对一和一对多 查询的时候,添加 id 子标签减少了字段的对比次数,有助于提高效率。如果没有添加id标签,他会对每一个result标签里column对应的字段进行比较。
**比较规则 : **
? Mybatis会对每一层级的对象进行比较,Mybatis会对顶级对象进行比较,如果SysRole相同那么就比较SysRole对象,如果SysRole不同,就会添加一个SysRole,如果相同就会保留前一个SysRole。如果SysRole还有下一级就以此类推。
在resultMap中使用 collection 标签实现一对多查询
第一种还是不嵌套的方式,也就是执行一次sql 获取结果
collection 标签的常用属性
值得注意的是columnPrefix是叠加的,也就是说columnPrefix中对应的resultMap中的association 或者 collection 又含有columnPrefix ,那么该resultMap中的column在sql中就要把两个Prefix全部加上
sp.id "role_privilege_id",
sp.privilege_name "role_privilege_privilege_name",
sp.privilege_url "role_privilege_privilege_url"
第二种是嵌套查询
collection 标签的常用属性
原文:https://www.cnblogs.com/iandf/p/14659869.html