zoukankan      html  css  js  c++  java
  • 【框架】- MyBatis基础

    mybatis

    1. 什么是mybatis

      ​ orm的半自动化框架,自己封装了jdbc,创建驱动,创建链接,创建statement等,采取mapper动态代理机制,使使用者只需要关注sql的编写。

      ​ mybatis的sql是通过xm或者注解来进行对欲生成的sql进行配置,再通过配置的类路劲反射找到类的对象,从而找到要执行的方法,获取方法中的动态参数, 再将参数根据反射匹配#{}中字符串根据set方法写入到sql中,从而组装成完整的sql在进行执行。最后将执行的结果在映射成对象或者map集合返回回来。

    2. mybatis优缺点:

      • 优点:

        • sql写在文件中可以让sql与代码解析解耦,后期便于维护
        • 相对于原生jdbc会减少大量冗余代码
        • 采取jdbc来链接数据库,所以会兼容各种数据库
        • 便于与spring进行集成
        • 提供了映射标签,可以是对象与数据库字段进行映射
      • 缺点:

        • sql需要自己编写,工程量较大
        • sql依赖数据库,所以不便于数据库的迁移
    3. #{} ${} 区别

      • #{} 代表预处理,会将#{}替换成?在调用preparStatement中的set方法进行赋值
      • ${} 代表字符串替换,会将${}中的字符直接替换,一般用于表名,关键字等
    4. 通常一个mapper.xml文件,都会对应一个Dao接口,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?

      • Dao接口就是Mappper接口,
        • dao接口中的全类名就是配置文件中的namesqpce的值
        • 接口的方法名对应映射文件中得id值
        • 接口的方法参数就是sql的动态参数
      • 通过类全名+方法名可以唯一确定映射文件中的对应的执行sql语句
    5. 如何进行分页查询,分页插件原理是什么

      • 第一中可以直接在sql中编写limit语句
      • mybatis是采取RowBounds对象来对返回的结果进行内存分页,而非物理分页,所以一般对于少数据查询可以使用,若是大数据则不推荐使用。
    6. Mybatis是否支持延迟加载?如果支持,它的实现原理是什么

      • 仅支持association(一对一)和collection(一对多)进行延迟加载通过lazyLoadingEnabled=true|false
      • 在调用目标方法时,进行拦截,若是目标方法中不需要获取聚合对象的值,则进行拦截仅查询第一条sql,若是用到聚合对象的值,则在获取第一条sql的返回值来查询第二条sql语句
    7. Mybatis是如何将sql执行结果封装为目标对象并返回的?都有哪些映射形式

      • 通过resultMap来进行逐一映射数据库列名和对象属性名之间的关系
      • 也可以给数据库查询语句中的列定义个别名来进行映射
      • 获取映射关系后通过反射来获取对象调用set方法来给对象赋值并返回
    8. Mybatis动态sql有什么用?执行原理?有哪些动态sql?

      • 动态sql可以在映射文件中以标签形式来编写sql
      • 提供的标签有:trim | where | set | foreach | if | choose | when | otherwise | bind、
    9. Xml映射文件中,除了常见的select | insert | updae | delete标签之外,还有哪些标签?

      • 标签 定义一个sql片段 有个id属性
      • 标签 可以应用 sql标签的片段sql
      • 标签 定义返回值进行映射配置
      • 定义返回值类型
      • 不支持自增的主键生成策略标签
    10. 使用MyBatis的mapper接口调用时有哪些要求

      • 接口方法名与映射文件mapper.xml中的sql的id 一致
      • Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
      • Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
      • Mapper.xml文件中的namespace即是mapper接口的类全名路径
    11. 模糊查询like语句该怎么写

      • 直接在sql中写入如下:

        // 容易引发sql注入
        <select id=”selectlike”>
                 select * from foo where bar like '%${}%'
        </select>
        
      • 采取传参还有%%方式进行配置:

        // 调用方法时直接传参含有%%  比较麻烦
        sqlSession.selectList("类路径","%zht%");
        <select id=”selectlike”>
                 select * from foo where bar like #{}
        </select>
        
      • 直接在sql中采取concat进行拼接处理

        <select id=”selectlike”>
                 select * from foo where bar like concat('%',#{},'%')
        </select>
        
    12. 当实体类中的属性名和表中的字段名不一样 ,怎么办

      • 查询语句字段起别名使别名与属性名一致
      • 通过来映射字段名和实体类属性名的一一对应的关系
    13. 如何获取自动生成的(主)键值

      • insert方法中总会返回一个值,代表插入的行数

      • 获取自增主键值可以在标签中配置:usegeneratedkeys=”true”如下:

        <insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
             insert into names (name) values (#{name})
        </insert>
            
         int rows = mapper.insertname(name);
        // 完成后,id已经被设置到对象中
        system.out.println(“rows inserted = ” + rows);
        system.out.println(“generated key value = ” + name.getid());
        
    14. 在mapper中如何传递多个参数

      • 直接传递多个参数,sql语句写成#{0},#{1}进行匹配

        //DAO层的函数
        Public UserselectUser(String name,String area);  
        //对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
        <select id="UserselectUser"resultMap="BaseResultMap">  
            select *  fromuser_user_t   whereuser_name = #{0} anduser_area=#{1}  
        </select>
        
      • 直接传递参数,在参数前面协商注解

        //DAO层的函数
        Public UserselectUser(@param("name") String name, @param("area") String area);  
        //对应的xml,#{0}代表接收的是dao层中的第一个参数,#{1}代表dao层中第二参数,更多参数一致往后加即可。
        <select id="UserselectUser"resultMap="BaseResultMap">  
            select *  fromuser_user_t   whereuser_name = #{name} anduser_area=#{area}  
        </select>
        
      • 参数封装成map

        Map<String, Object> map = new HashMap();
        map.put("name", name);
        map.put("area", area);
        return sqlSession.selecOne("UserselectUser", map);
        
        <select id="UserselectUser"resultMap="BaseResultMap">  
            select *  fromuser_user_t   whereuser_name = #{name} anduser_area=#{area}  
        </select>
        
    15. 一对一、一对多的关联查询

      <mapper namespace="com.lcb.mapping.userMapper">  
          <!--association  一对一关联查询 -->  
          <select id="getClass" parameterType="int" resultMap="ClassesResultMap">  
              select * from class c,teacher t where c.teacher_id=t.t_id and c.c_id=#{id}  
          </select>  
       
          <resultMap type="com.lcb.user.Classes" id="ClassesResultMap">  
              <!-- 实体类的字段名和数据表的字段名映射 -->  
              <id property="id" column="c_id"/>  
              <result property="name" column="c_name"/>  
              <association property="teacher" javaType="com.lcb.user.Teacher">  
                  <id property="id" column="t_id"/>  
                  <result property="name" column="t_name"/>  
              </association>  
          </resultMap>  
       
       
          <!--collection  一对多关联查询 -->  
          <select id="getClass2" parameterType="int" resultMap="ClassesResultMap2">  
              select * from class c,teacher t,student s where c.teacher_id=t.t_id and c.c_id=s.class_id and c.c_id=#{id}  
          </select>  
       
          <resultMap type="com.lcb.user.Classes" id="ClassesResultMap2">  
              <id property="id" column="c_id"/>  
              <result property="name" column="c_name"/>  
              <association property="teacher" javaType="com.lcb.user.Teacher">  
                  <id property="id" column="t_id"/>  
                  <result property="name" column="t_name"/>  
              </association>  
       
              <collection property="student" ofType="com.lcb.user.Student">  
                  <id property="id" column="s_id"/>  
                  <result property="name" column="s_name"/>  
              </collection>  
          </resultMap>  
      </mapper>
      
    16. MyBatis实现一对一/一对多有几种方式?具体怎么操作的

      • 有联合查询和嵌套查询,联合查询是几个表联合查询,只查询一次, 通过在resultMap里面配置association节点配置一对一/ collection节点配置一对多的类就可以完成
      • 嵌套查询是先查一个表,根据这个表里面的结果的 外键id,去再另外一个表里面查询数据,也是通过association/collection配置,但另外一个表的查询通过select属性配置
    17. 什么是MyBatis的接口绑定?有哪些实现方式

      • 接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定
      • 实现方式
        • 一种是通过注解绑定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql语句来绑定
        • 通过xml里面写SQL来绑定, 在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名
    18. MyBatis与Hibernate有哪些不同

      • MyBatis需要程序员自己写sql Hibernate不需要
      • Mybatis无法做到数据库无关性如果需要实现支持多种数据库的软件,则需要自定义多套sql映射文件,工作量大 而 Hibernate 可以

    备注:本文来源于:https://blog.csdn.net/a745233700/article/details/80977133

  • 相关阅读:
    SecureCRT
    Jsoup 标签选择器 选择img标签中src的值
    使用Jsoup 爬取网易首页所有的图片
    java自定义类型 比较排序 Comparator接口
    eclipse下导入jdk源码
    java爬虫--使用正则表达式获取网页中的email
    Java正则表达式--Matcher.group函数的用法
    使用org.jsoup.Jsoup下载网络中的图片
    Tomcat中的Session小结
    关于JAVA中的static方法、并发问题以及JAVA运行时内存模型
  • 原文地址:https://www.cnblogs.com/tar8087/p/14753574.html
Copyright © 2011-2022 走看看