目录

Mybatis <https://blog.csdn.net/liyang_com/article/details/83756273#Mybatis>

1.谈谈MyBatis
<https://blog.csdn.net/liyang_com/article/details/83756273#1.%E8%B0%88%E8%B0%88MyBatis>

2.Mybatis分为三层
<https://blog.csdn.net/liyang_com/article/details/83756273#2.Mybatis%E5%88%86%E4%B8%BA%E4%B8%89%E5%B1%82>

3.Mybatis和jdbc的区别 
<https://blog.csdn.net/liyang_com/article/details/83756273#3.Mybatis%E5%92%8Cjdbc%E7%9A%84%E5%8C%BA%E5%88%AB%C2%A0>

4.映射文件
<https://blog.csdn.net/liyang_com/article/details/83756273#4.%E6%98%A0%E5%B0%84%E6%96%87%E4%BB%B6>

5.模糊查询:LIKE
<https://blog.csdn.net/liyang_com/article/details/83756273#5.%E6%A8%A1%E7%B3%8A%E6%9F%A5%E8%AF%A2%EF%BC%9ALIKE>

6.$和#的区别
<https://blog.csdn.net/liyang_com/article/details/83756273#6.%24%E5%92%8C%23%E7%9A%84%E5%8C%BA%E5%88%AB>

7.主键自增
<https://blog.csdn.net/liyang_com/article/details/83756273#7.%E4%B8%BB%E9%94%AE%E8%87%AA%E5%A2%9E>

8.API <https://blog.csdn.net/liyang_com/article/details/83756273#8.API>

9.SqlSession不是线程安全的
<https://blog.csdn.net/liyang_com/article/details/83756273#9.SqlSession%E4%B8%8D%E6%98%AF%E7%BA%BF%E7%A8%8B%E5%AE%89%E5%85%A8%E7%9A%84>

10.调用sqlSession.selectOne()还是SQLSession.selectList()是由mapper接口的返回值决定的
<https://blog.csdn.net/liyang_com/article/details/83756273#10.%E8%B0%83%E7%94%A8sqlSession.selectOne()%E8%BF%98%E6%98%AFSQLSession.selectList()%E6%98%AF%E7%94%B1mapper%E6%8E%A5%E5%8F%A3%E7%9A%84%E8%BF%94%E5%9B%9E%E5%80%BC%E5%86%B3%E5%AE%9A%E7%9A%84>

11.Mapper接口的参数:简单类型,pojo类型包装类型,Map,List集合等
<https://blog.csdn.net/liyang_com/article/details/83756273#11.Mapper%E6%8E%A5%E5%8F%A3%E7%9A%84%E5%8F%82%E6%95%B0%EF%BC%9A%E7%AE%80%E5%8D%95%E7%B1%BB%E5%9E%8B%EF%BC%8Cpojo%E7%B1%BB%E5%9E%8B%E5%8C%85%E8%A3%85%E7%B1%BB%E5%9E%8B%EF%BC%8CMap%EF%BC%8CList%E9%9B%86%E5%90%88%E7%AD%89>

12.指定别名
<https://blog.csdn.net/liyang_com/article/details/83756273#12.%E6%8C%87%E5%AE%9A%E5%88%AB%E5%90%8D>

13.隐射文件的加载
<https://blog.csdn.net/liyang_com/article/details/83756273#13.%E9%9A%90%E5%B0%84%E6%96%87%E4%BB%B6%E7%9A%84%E5%8A%A0%E8%BD%BD>

14.输入参数
<https://blog.csdn.net/liyang_com/article/details/83756273#14.%E8%BE%93%E5%85%A5%E5%8F%82%E6%95%B0>

15.只写map的
<https://blog.csdn.net/liyang_com/article/details/83756273#15.%E5%8F%AA%E5%86%99map%E7%9A%84>

16.动态sql的编写
<https://blog.csdn.net/liyang_com/article/details/83756273#16.%E5%8A%A8%E6%80%81sql%E7%9A%84%E7%BC%96%E5%86%99>

17.缓存
<https://blog.csdn.net/liyang_com/article/details/83756273#17.%E7%BC%93%E5%AD%98>

18.Mybatis的编程步骤
<https://blog.csdn.net/liyang_com/article/details/83756273#18.Mybatis%E7%9A%84%E7%BC%96%E7%A8%8B%E6%AD%A5%E9%AA%A4>

19.主键自增问题
<https://blog.csdn.net/liyang_com/article/details/83756273#19.%E4%B8%BB%E9%94%AE%E8%87%AA%E5%A2%9E%E9%97%AE%E9%A2%98>

21.如何获取自动生成的(主)键值
<https://blog.csdn.net/liyang_com/article/details/83756273#21.%E5%A6%82%E4%BD%95%E8%8E%B7%E5%8F%96%E8%87%AA%E5%8A%A8%E7%94%9F%E6%88%90%E7%9A%84(%E4%B8%BB)%E9%94%AE%E5%80%BC>

22.使用MyBatis的mapper接口调用有哪些要求?
<https://blog.csdn.net/liyang_com/article/details/83756273#22.%E4%BD%BF%E7%94%A8MyBatis%E7%9A%84mapper%E6%8E%A5%E5%8F%A3%E8%B0%83%E7%94%A8%E6%9C%89%E5%93%AA%E4%BA%9B%E8%A6%81%E6%B1%82%EF%BC%9F>

23.Statement和PrepareStatement的区别
<https://blog.csdn.net/liyang_com/article/details/83756273#23.Statement%E5%92%8CPrepareStatement%E7%9A%84%E5%8C%BA%E5%88%AB>

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