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.映射文件

  <mapper name="text">

        <select id="FindByID" paramenterType="int" resultType="com.guigu.User">

               select * from user where id=#{id}

        </select>

  </mapper>

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

5.模糊查询:LIKE

   <selectid="findByName2"

       parameterType="java.lang.String" resultType="com.gugiu.model.User">

              select *  from user where name like  '%${value}%'

   </select>

   修改  

 <update id="updateUserById"  parameterType="com.gugiu.model.User">

              update user set name = #{name},age =#{age},address=#{address}

              where id =#{id}

  </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接口的返回值决定的

  

     List<User>  findUserByName(String name);  selectList()

       User  findUserByName(String name);   selectOne()

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

12.指定别名

  单个文件        

      

 <typeAliases>

        <typeAlias type="com.gugiu.model.User" alias="user"/>

 </typeAliases>

  批量    

   <typeAliases>

              <package name="com.guigu.model1"/>

              <package name="com.guigu.model2"/>

   </typeAliases>

13.隐射文件的加载

    单个文件     

  <mappers>

              <!—加载单个映射文件-->

              <mapper resource="com/guigu/mapper/UserMapper.xml"/>
</mappers>

    批量 

     <mappers>

         <package name="com.guigu.mapper"/>

       </mappers>

14.输入参数

   (1)简单类型     

 <select id="findById" parameterType="int" resultType="user" >

           select * from User where id = #{id} ;

</select>

   (2)pojo类型 

   <insert id="addUser" parameterType="com.guigu.model.User">

          <selectKey keyColumn="id" order="AFTER" resultType="int">

             SELECT LAST_INSERT_ID()

          </selectKey>

        INSERT INTO user (name,age,address)

              VALUE(#{name},#{age},#{address})

   </insert>

   (3)pojo的包装类型  

 <select id="findById" parameterType="com.guigu.model.UserVo" resultType="user">

              select * from User where id = #{user.id} ;

 </select>

   (4)Map

   <insert id="addUserMap" parameterType="hashmap">

    INSERT INTO my_user(NAME,age,address)  VALUE(#{name},#{age},#{address})

   </insert>

15.只写map的

 

    <selectid="findById"  parameterType="int"  resultMap="userMap">

          SELECT id ,name user_name  FROM my_user WHERE id = #{id}

    </select>

16.动态sql的编写

    (1)if

         <insert id="addUserVo"  parameterType="com.guigu.mybatis.pojo.UserVo">

               <if  test="user != null">

                  insert into  my_user (name,age,address)

                  value(#{user.name},#{user.age},#{user.address})

               </if>

          </insert>

    (2)where          

   <select id="findByUserVo" parameterType="UserVo"resultType="User">

               select * from my_user

                            <where>

                                   <iftest="user!= null">

                                          <if test="user.id != null and user.id !='' ">

                                                 and id = #{user.id}

                                          </if>

                                          <if test="user.name != null and user.name !='' ">

                                                 and name like '%#{user.name}%'

                                          </if>

                                   </if>

                            </where>

            </select>

    (3)sql代码片段      

    <sql id="find_user_byId">

                     <if test="user.id != null and user.id !='' ">

                                          and id = #{user.id}

                     </if>

        </sql>

              <sql id="find_user_byAge">

                     <if test="user.age != null and user.age !='' ">

                                          and age = #{user.age}

                     </if>

              </sql>

              <select id="findByUserVo"  parameterType="UserVo" resultType="User">

                     select * from my_user

                     <where>

                            <if test="user!= null">

                            <include ref id="find_user_byId"></include>

                            <include ref id="find_user_byAge"></include>

                            </if>

                     </where>

              </select>

     (4)foreach

           <insert id="addUsers" parameterType="map">

                  insert into my_user (name,age,address)

                <if test="users != null">

                values

                  <foreach collection="users" item="user" separator=",">

                    (#{user.name},#{user.age},#{user.address})

                  </foreach>

                </if>

              </insert>

             

              <select id="findByIds"  parameterType="map" resultType="User">

                     <if test="userIds != null">

                            select * from my_user

                            <where>

                                   <foreach collection="userIds"  item="userId" separator="or">

                                   id = #{userId}

                                   </foreach>

                            </where>

                     </if>

              </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()关闭会话

       publicclass MyBatisUtil {

              privatestatic SqlSessionFactory  factory = null;

              static {

                     try {

                            SqlSessionFactoryBuilder builder = newSqlSessionFactoryBuilder();

                            InputStream  inputStream = Resources.getResourceAsStream("MyBatisConfig.xml");

                            //创建Session工厂

                            factory = builder.build(inputStream);

                     } catch (Exception e) {

                            e.printStackTrace();

                     }

              }

             

              publicstatic SqlSession  getSqlSession(){

                     //获得session会话

                     return factory.openSession();

              }

       }

19.主键自增问题

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

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

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

  


 <resultMap type="User" id="UserResultMap">

     <id column="id" property="id"/>

     <result column="user_name" property="userName"/>

     <result column="user_password" property="userPassword"/>

 </resultMap>
  1. Mybatis提供了一个全局属性mapUnderscoreToCamelCase来解决两者名字不一致的问题。
<settings>

           <setting name="mapUnderscoreToCamelCase" value="true"/>

</settings>

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

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

    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">

              <selectKey keyProperty="id" order="AFTER" resultType="int">

                 select LAST_INSERT_ID()

              </selectKey>

          INSERT INTO USER(username,birthday,sex,address)

          VALUES(#{username},#{birthday},#{sex},#{address)

     </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的第一次执行消耗是很高的. 它的性能体现在后面的重复执行

猜你喜欢

转载自blog.csdn.net/zjf1665119803/article/details/83655060
今日推荐