MyBatis总结(笔面试题)

目录

Mybatis

1.谈谈MyBatis

2.Mybatis分为三层

3.Mybatis和jdbc的区别 

4.映射文件

5.模糊查询:LIKE

6.$和#的区别

7.主键自增

8.API

9.SqlSession不是线程安全的

10.调用sqlSession.selectOne()还是SQLSession.selectList()是由mapper接口的返回值决定的

11.Mapper接口的参数:简单类型,pojo类型包装类型,Map,List集合等

12.指定别名

13.隐射文件的加载

14.输入参数

15.只写map的

16.动态sql的编写

17.缓存

18.Mybatis的编程步骤

19.主键自增问题

21.如何获取自动生成的(主)键值

22.使用MyBatis的mapper接口调用有哪些要求?

23.Statement和PrepareStatement的区别


Mybatis

1.谈谈MyBatis

Mybatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使得开发者只需要专注于SQL语句本身,而不用去关心注册驱动,创建connection等,Mybatis通过xml文件配置或者注解的方式将要执行的各种statement配置起来,并通过java对象和statement中的sql进行映射成最终执行的sql语句,最后由Mybatis框架执行sql并将结果映射成java对象并返回。

2.Mybatis分为三层

  (1)API接口层:提供给外部使用的接口API

  (2)数据处理层:负责具体的SQL

  (3)基础支撑层:负责最基础的功能支撑,如连接管理,事务管理,配置加载和缓存处理

3.Mybatis和jdbc的区别 

  相比与jdbc,Mybatis具有以下优点    

       (1)数据库链接创建,释放频繁造成系统资源浪费会影响系统性能,使用数据库可以解决

               解决:在核心配置文件SqlMapConfig.xml中配置数据链接池,使用数据链接池管理数据库链接

       (2)Sql写在代码中不易于维护,修改需要变动java代码

             在映射文件XXXMapper.xml文件中配置sql语句与Java代码分离

       (3)向Sql语句传输参数麻烦,因为Sql语句的WHERE条件不一定,可能多也可能少,占位符需要和参数一一对应

            Mybatis可以自动将Java对象映射到sql语句

       (4)对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,将数据库记录封装成pojo对象解析更加方便

              Mybatis可以自动将sql执行结果映射到Java对象

4.映射文件


   
   
   
   
  1.   <mapper name="text">
  2.         <select id="FindByID" paramenterType="int" resultType="com.guigu.User">
  3.                select * from user where id=#{id}
  4.          select>
  5.   mapper>

namespace:名称空间  id:根据id执行sql  parameterType:入参  resultType:出参   #{id} 接收的参数

5.模糊查询:LIKE


   
   
   
   
  1.    <selectid="findByName2"
  2.        parameterType= "java.lang.String" resultType= "com.gugiu.model.User">
  3.               select *  from user where name like  '%${value}%'
  4.    select>

   修改  


   
   
   
   
  1. <update id="updateUserById"  parameterType="com.gugiu.model.User">
  2.               update user set name = #{name},age =#{age},address=#{address}
  3.               where id =#{id}
  4.   update>

6.$和#的区别

  (1)#把传入的参数当做字符串处理  $表示直接显示

  (2)#很大程度防止Sql注入(语句拼接)

  (3)能用#尽量用#

7.主键自增

8.API

  (1)SqlSessionFactoryBuilder

    通过加载MyBatisde 核心配置文件,创建SqlSessionFactory

  (2)SqlSessionFactory

      定义了openSession的不同重载方法

  (3)sqlSession

      定义了数据库的操作,增删改查

9.SqlSession不是线程安全的

10.调用sqlSession.selectOne()还是SQLSession.selectList()是由mapper接口的返回值决定的

  


   
   
   
   
  1.      List  findUserByName(String name);  selectList()
  2.         User  findUserByName(String name);   selectOne()

11.Mapper接口的参数:简单类型,pojo类型包装类型,Map,List集合等

12.指定别名

  单个文件        

      


   
   
   
   
  1. <typeAliases>
  2.          <typeAlias type="com.gugiu.model.User" alias="user"/>
  3. typeAliases>

  批量    


   
   
   
   
  1.    <typeAliases>
  2.               <package name="com.guigu.model1"/>
  3.               <package name="com.guigu.model2"/>
  4.     typeAliases>

13.隐射文件的加载

    单个文件     


   
   
   
   
  1.   <mappers>
  2.               <!—加载单个映射文件-->
  3.               <mapper resource="com/guigu/mapper/UserMapper.xml"/>
  4. mappers>

    批量 


   
   
   
   
  1.     <mappers>
  2.          <package name="com.guigu.mapper"/>
  3.        mappers>

14.输入参数

   (1)简单类型     


   
   
   
   
  1. <select id="findById" parameterType="int" resultType="user" >
  2.            select * from User where id = #{id} ;
  3. select>

   (2)pojo类型 


   
   
   
   
  1.    <insert id="addUser" parameterType="com.guigu.model.User">
  2.           <selectKey keyColumn="id" order="AFTER" resultType="int">
  3.              SELECT LAST_INSERT_ID()
  4.           selectKey>
  5.         INSERT INTO user (name,age,address)
  6.               VALUE(#{name},#{age},#{address})
  7. insert>

   (3)pojo的包装类型  


   
   
   
   
  1. <select id="findById" parameterType="com.guigu.model.UserVo" resultType="user">
  2.               select * from User where id = #{user.id} ;
  3. select>

   (4)Map


   
   
   
   
  1.    <insert id="addUserMap" parameterType="hashmap">
  2.     INSERT INTO my_user(NAME,age,address)  VALUE(#{name},#{age},#{address})
  3.    insert>

15.只写map的

 


   
   
   
   
  1.     <selectid="findById"  parameterType="int"  resultMap="userMap">
  2.           SELECT id ,name user_name  FROM my_user WHERE id = #{id}
  3.     select>

16.动态sql的编写

    (1)if


   
   
   
   
  1.          <insert id="addUserVo"  parameterType="com.guigu.mybatis.pojo.UserVo">
  2.            <if  test="user != null">
  3.                   insert into  my_user (name,age,address)
  4.                   value(#{user.name},#{user.age},#{user.address})
  5.            if>
  6.           insert>

    (2)where          


   
   
   
   
  1.    <select id="findByUserVo" parameterType="UserVo"resultType="User">
  2.                select * from my_user
  3.                             <where>
  4.                                    <iftest="user!= null">
  5.                                           <if test="user.id != null and user.id !='' ">
  6.                                                  and id = #{user.id}
  7.                                           if>
  8.                                           <if test="user.name != null and user.name !='' ">
  9.                                                  and name like '%#{user.name}%'
  10.                                           if>
  11.                                    if>
  12.                             where>
  13.             select>

    (3)sql代码片段      


   
   
   
   
  1.     <sql id="find_user_byId">
  2.                      <if test="user.id != null and user.id !='' ">
  3.                                           and id = #{user.id}
  4.                      if>
  5.         sql>
  6.               <sql id="find_user_byAge">
  7.                      <if test="user.age != null and user.age !='' ">
  8.                                           and age = #{user.age}
  9.                      if>
  10.               sql>
  11.               <select id="findByUserVo"  parameterType="UserVo" resultType="User">
  12.                      select * from my_user
  13.                      <where>
  14.                             <if test="user!= null">
  15.                             <include ref id="find_user_byId"> include>
  16.                             <include ref id="find_user_byAge"> include>
  17.                             if>
  18.                      where>
  19.               select>

     (4)foreach


   
   
   
   
  1.            <insert id="addUsers" parameterType="map">
  2.                   insert into my_user (name,age,address)
  3.                 <if test="users != null">
  4.                 values
  5.                   <foreach collection="users" item="user" separator=",">
  6.                     (#{user.name},#{user.age},#{user.address})
  7.                   foreach>
  8.                 if>
  9.               insert>
  10.              
  11.               <select id="findByIds"  parameterType="map" resultType="User">
  12.                      <if test="userIds != null">
  13.                             select * from my_user
  14.                             <where>
  15.                                    <foreach collection="userIds"  item="userId" separator="or">
  16.                                    id = #{userId}
  17.                                    foreach>
  18.                             where>
  19.                      if>
  20.               select>

17.缓存

  (1)一级缓存(SqlSession级别)

      MyBatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行

         相同的sql语句,第一次执行后会将查询到的数据存储到缓存当中,第二次会从缓

         存中进行查找,从而提高查询效率,当一个SqlSession结束之后,一级缓存也将不

         存在,Mybatis默认开启一级缓存。

  (2)二级缓存(Mapper级别)

         二级缓存的作用域是mapper的同一个namespace,执行两次相同的SQL语句,第一次执行后会将查询到的数据存储到缓存当中,第二次会从缓存中进行查找,从而提高查询效率,默认不开启。      

18.Mybatis的编程步骤

   (0)创建SqlSessionFactoryBuilder

   (1)通过SqlsesionFactoryBuilder创建sqlSessionFactory

   (2)通过SqlSessionFactory创建sqlSession  

   (3)通过sqlSession执行数据库操作

   (4)调用session.commit()提交事务

   (5)调用session.close()关闭会话


   
   
   
   
  1.        publicclass MyBatisUtil {
  2.               privatestatic SqlSessionFactory  factory = null;
  3.               static {
  4.                      try {
  5.                             SqlSessionFactoryBuilder builder = newSqlSessionFactoryBuilder();
  6.                             InputStream  inputStream = Resources.getResourceAsStream( "MyBatisConfig.xml");
  7.                             //创建Session工厂
  8.                             factory = builder.build(inputStream);
  9.                      } catch (Exception e) {
  10.                             e.printStackTrace();
  11.                      }
  12.               }
  13.              
  14.               publicstatic SqlSession  getSqlSession(){
  15.                      //获得session会话
  16.                      return factory.openSession();
  17.               }
  18.        }

19.主键自增问题

20.实体类中的属性名和数据表中的列名不一致

   (1)在sql语句中使用别名

   (2)事先指定映射关系,这样Mybatis也能自动完成映射。Mybatis提供了resultMap标签

  


   
   
   
   
  1.   <resultMap type="User" id="UserResultMap">
  2.      <id column="id" property="id"/>
  3.      <result column="user_name" property="userName"/>
  4.      <result column="user_password" property="userPassword"/>
  5.   resultMap>
  1. Mybatis提供了一个全局属性mapUnderscoreToCamelCase来解决两者名字不一致的问题。

   
   
   
   
  1. <settings>
  2.             <setting name="mapUnderscoreToCamelCase" value="true"/>
  3. settings>

21.如何获取自动生成的(主)键值

   解决思路:通过LAST_INSERT_ID()获取刚插入记录的自增主键值,在insert语句执行后,执行select LAST_INSERT_ID()就可以获取自增主键。


   
   
   
   
  1.     <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
  2.               <selectKey keyProperty="id" order="AFTER" resultType="int">
  3.                  select LAST_INSERT_ID()
  4.               selectKey>
  5.           INSERT INTO USER(username,birthday,sex,address)
  6.           VALUES(#{username},#{birthday},#{sex},#{address)
  7.       insert>

22.使用MyBatis的mapper接口调用有哪些要求?

(1)Mapper接口方法名和mapper.xml中定义的每个sql的id相同

(2)Mapper接口中输入的参数类型和mapper.xml中定义的每个sql的ParameterType相同

(3)Mapper接口中输出的参数类型和mapper.xml中定义的每个sql的resultType相同

(4)Mapper.xml文件中的namespace即是接口的类路径

23.Statement和PrepareStatement的区别

  PreparedStatement:表示预编译的 SQL 语句的对象。

  (1)PrepareStatement可以使用占位符,是预编译的,批处理比Statement效率高

  (2)在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。

  (3)PreparedStatement的第一次执行消耗是很高的. 它的性能体现在后面的重复执行

你可能感兴趣的:(MyBatis总结(笔面试题))