一梦三千年

导航

【框架】- 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

posted on 2021-05-11 00:16  一梦三千年  阅读(62)  评论(0编辑  收藏  举报