zoukankan      html  css  js  c++  java
  • mybatis一些问题的总结

    mybatis一些总结

    mybatis使用注解开发和xml区别

    mybatis之所以优先使用xml编写sql代码主要是当修改sql的时候代码不用重新编译,解耦性更好。

    mybatis中${} 和 #{}区别

    1. ${}会直接对sql进行字符串拼接,在特殊情况下使用#{}会出现问题

      select * from #{table_name}
      //table_name = "test",解析后
      select * from "test"
      //使用${table_name},解析后
      select * from test
      

      使用#{}

      image-20210413091420572

      使用${}, 直接进行字符串的拼接image-20210413091700135

    2. #{}是可以防止sql注入的,预处理阶段使用?代替,真正查询的时候才传入参数,类似于jdbc中的PreparedStatement。

    总结: 在传入表名,字段名的时候直接使用${},其他的时候就使用#{}

    动态标签总结

    1. if test返回true的时候把if中的sql片段拼接进入sql语句。

    2. choose when otherwise 可以实现类似于 if...else 的功能

    3. where 当where标签包含的元素有返回值的时候在sql中加where,where 后面字符串以and or开头就去掉

    4. update语句中的 set 标签 ,set标签包含的元素有返回值的时候在sql中加set , set 后面的字符串以,结尾就去掉

    5. where标签和set标签是trim的特殊情况,也就是说可以使用trim来实现where和set标签,trim标签的属性如下:

      1. prefix:当trim元素内包含内容时,会给内容增加 prefix指定的前缀。
      2. prefixOverrides:当trim元素内包含内容时,会把内容中匹配的前缓字符串去掉。
      3. suffix:当trim元素内包含内容时,会给内容增加 suffix指定的后缀。
      4. suffixOverrides:当trim元素内包含内容时,会把内容中匹配的后缀字符串去掉。
    6. foreach 标签用来循环拼接,可以实现sql中的实现in ,批量插入等

      1. 在Map中key 是存储在map中的key值,在实现Iterable的类中key是索引值index
    7. bind 标签可以创建一个变量,用于字符串拼接或者打印其他变量的值等。

    8. OGNL 支持逻辑运算与,非,大于,小于等,可以使用类的静态方法,对象的方法和字段。if when的 test bind 的 value属性都支持OGNL

    一对一总结

    1. 直接在sql语句中使用as进行把关联对象的属性和查询出来的字段对应起来

    2. 使用resultMap的result标签把关联对象的属性和查询出来的字段对应起来

    3. 使用resultMap标签中的 association 标签,指定一个resultMap,把关联对象的属性和查询出来的字段对应起来

      此时association标签常用的属性

      1. property 对象里面关联对象的属性名
      2. resultMap 指定关联对象对应的resultMap
      3. columnPrefix:就是对于的ResultMap配置好的colum中都加入这个前缀,那么在sql语句中要对应的也要加入这个前缀

      前三种方法都是使用一次sql查询就查询出结果,这样导致的问题就是sql编写复杂,容易出错。

    4. 使用resultMap标签中的 association 实现嵌套查询实现一对一查询。也就是执行多次sql完成查询。

      此时association的常用属性如下

      1. property
      2. column 列名(或别名),将主查询中列的结果作为嵌套查询的参数,配置方式如column={ prop1=col1,prop2=co12},prop1和prop2将作为嵌套查询的参数。这边的prop1要和接下来执行的sql参数名一致,col1要和查询出来的列名一致。
      3. select 值是对应的select标签的id,mybatis会执行这个select得到嵌套对象
      4. fetchtype 数据加载方式,可选值为lazy和 eager,分别为延退加载和积极加载,这个配置会覆盖全局的lazyloadingenabled配置。

      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 标签实现一对多查询

    1. 第一种还是不嵌套的方式,也就是执行一次sql 获取结果

      collection 标签的常用属性

      1. property
      2. resultMap
      3. columnPrefix

      值得注意的是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"
      
    2. 第二种是嵌套查询

      collection 标签的常用属性

      1. property
      2. select
      3. column
  • 相关阅读:
    js跳出循环
    JavaScript prototype属性
    【DP专题】——洛谷P2279:消防局的设立
    转:android中dialog工具类的实现(多种dialog的创建)
    转:setContentView的时候,到底发生了什么
    转:Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别
    转:Android Studio中的Gradle是干什么的
    转:Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB
    Android 学习
    com.baidu.navisdk.adapter找不到 在百度定位SDK的基础之上导入导航的SDK(针对新版本的坑!)
  • 原文地址:https://www.cnblogs.com/iandf/p/14659869.html
Copyright © 2011-2022 走看看