Mybatis笔记

1.初识Mybatis

1.引入相关jar包

<!--Mybatis依赖包-->
<dependency>
   <groupId>org.mybatis</groupId>
   <artifactId>mybatis</artifactId>
   <version>3.5.2</version>
</dependency>
<!--mysql驱动包-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>5.1.47</version>
</dependency>

2.搭建数据库

3.编写Mybatis全局配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <environments default="development">
       <environment id="development">
           <transactionManager type="JDBC"/>
           <dataSource type="POOLED">
               <property name="driver" value="com.mysql.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
               <property name="username" value="root"/>
               <property name="password" value="123456"/>
           </dataSource>
       </environment>
   </environments>
   <mappers>
       <mapper resource="com/kuang/dao/userMapper.xml"/>
   </mappers>
</configuration>

4.创建实体类和mapper接口

5.编写mapper.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="dao.EmployeeMapper">
    <select id="getEmpById" resultType="bean.Employee">
    	select id,last_name lastName,gender,email from tbl_employee where id = #{id}
    </select>
</mapper>

6.测试

//1.读取mybatis配置文件,获取SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession实例,能直接执行已经映射的sql语句
SqlSession openSession = sqlSessionFactory.openSession();
//3.获取接口的实现类对象
//Mybatis会为接口自动创建一个代理对象,代理对象去执行增删改查
EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
//下面再通过代理对象mapper进行增删改查
Employee employee = mapper.getEmpById(1);
//记得手动关闭openSession
openSession.close();

可能会出现静态资源过滤问题

<resources>
   <resource>
       <directory>src/main/java</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
   <resource>
       <directory>src/main/resources</directory>
       <includes>
           <include>**/*.properties</include>
           <include>**/*.xml</include>
       </includes>
       <filtering>false</filtering>
   </resource>
</resources>

2.Mybatis全局配置文件

configuration 配置:下面的这些配置要完全按照顺序配置,否则会报错

  • properties 属性

    引入外部资源,如数据库连接的基本信息

    <properties resource="dbconfig.properties"></properties>
    
  • settings 设置

    <settings>
            <!--开启驼峰命名法-->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
            <!--懒加载,需要用到哪个表的值再去加载而不是一起加载-->
            <setting name="lazyLoadingEnabled" value="true"/>
        	<!--入侵式加载-->
            <setting name="aggressiveLazyLoading" value="false"/>
        </settings>
    
  • typeAliases 别名处理器

    可以为指定的java类型取一个别名

    <typeAliases>
            <typeAlias type="bean.Department" alias="dept"/>
    </typeAliases>
    

    也可以为一整个包取别名,别名就是简单类名小写。

    <typeAliases>
            <package name="com.atguigu.bean"/>
    </typeAliases>
    

    还可以在实体类上使用@Alias注解

    @Alias("dept")
    public class Department {}
    
  • typeHandlers 类型处理器

  • objectFactory 对象工厂

  • plugins 插件

  • environments 环境

    • environment 环境变量
      • transactionManager 事务管理器
      • dataSource 数据源
    <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root"/>
                </dataSource>
            </environment>
        </environments>
    
  • databaseIdProvider 数据库厂商标识

  • mappers 映射器
    1.使用映射器接口实现类的完全限定类名
    需要配置文件名称和接口名称一致,并且位于同一目录下

    <mappers>
     <mapper class="org.mybatis.builder.AuthorMapper"/>
    </mappers>
    

    2.使用相对于类路径的资源引用

    <mappers>
     <mapper resource="org/mybatis/builder/PostMapper.xml"/>
    </mappers>
    

    3.使用使用完全限定资源定位符(URL)

    <mappers>
     <mapper url="file:///var/mappers/AuthorMapper.xml"/>
    </mappers>
    

    4.将包内的映射器接口实现全部注册为映射器
    但是需要配置文件名称和接口名称一致,并且位于同一目录下

    <mappers>
     <package name="org.mybatis.builder"/>
    </mappers>
    

3.mapper映射文件

namespace
  • namespace的命名必须跟某个接口同名
  • 接口中的方法与映射文件中sql语句id应该一一对应
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.UserMapper">
   
</mapper>

使用不同的数据库操作语句时,应使用不同的映射语句标签

select – 映射查询语句
  • id即为mapper接口中的方法名

  • parameterType:参数类型

    可以不传,MyBatis会根据TypeHandler自动推断

  • 必须设置接收类型即resultType或者resultMap,前者为实体类的类型,后者为自定义的类型

    resultType

    <select id="getDeptById" resultType="bean.Department">
            select id,dept_name departmentName from tbl_dept where id=#{id}
    </select>
    

    resultMap

    <resultMap  type="bean.Employee" id="MySimpleEmp">
          <!--指定主键列的封装规则
          column:指定哪一列
          property:指定对应的javaBean的属性
          -->
          <id column="id" property="id"/>
          <result column="last_name" property="lastName"/>
          <!--其他不指定的列会自动封装,但,建议,我们只要写resultMap就把全部的映射规则都写上-->
          <result column="email" property="email"/>
          <result column="gender" property="gender"/>
    </resultMap>
    
    <select id="getEmpById" resultMap="MySimpleEmp">
            select * from tbl_employee where id=#{id}
        </select>
    
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
sql –抽取可重用语句块
resultMap – 自定义结果集映射
  • 多对一:association

    <!--按查询结果嵌套处理-->
    <resultMap id="StudentTeacher2" type="Student">
       <id property="id" column="sid"/>
       <result property="name" column="sname"/>
       <!--关联对象property 关联对象在Student实体类中的属性-->
       <association property="teacher" javaType="Teacher">
           <result property="name" column="tname"/>
       </association>
    </resultMap>
    
    <select id="getStudents2" resultMap="StudentTeacher2" >
      select s.id sid, s.name sname , t.name tname
      from student s,teacher t
      where s.tid = t.id
    </select>
    
    <!--按查询嵌套处理 : 略-->
    
  • 一对多:collection

    <!--按查询结果嵌套处理-->
    <resultMap id="TeacherStudent" type="Teacher">
        <result  property="name" column="tname"/>
        <collection property="students" ofType="Student">
            <result property="id" column="sid" />
            <result property="name" column="sname" />
            <result property="tid" column="tid" />
        </collection>
    </resultMap>
    
    <select id="getTeacher" resultMap="TeacherStudent">
       select s.id sid, s.name sname , t.name tname, t.id tid
       from student s,teacher t
       where s.tid = t.id and t.id=#{id}
    </select>
    
    <!--按查询嵌套处理 : 略-->
    

    JavaType和ofType都是用来指定对象类型的

    • JavaType是用来指定pojo中属性的类型
    • ofType指定的是映射到list集合属性中pojo的类型
cache –命名空间的二级缓存配置
cache-ref – 其他命名空间缓存配置的引用

4.动态sql

if
<select id="queryBlogIf" parameterType="map" resultType="blog">
  select * from blog where 1=1
   <if test="title != null">
      and title = #{title}
   </if>
   <if test="author != null">
      and author = #{author}
   </if>
</select>
choose (when, otherwise)
<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>
where

​ where元素只会在子元素返回任何内容的情况下才插入 “where” 子句。而且,若子句的开头为 “and” 或 “or”,where元素也会将它们去除。

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
    <if test="author != null and author.name != null">
        AND author_name like #{author.name}
    </if>
  </where>
</select>
set

set 元素会动态地在行首插入set关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)

<update id="updateAuthorIfNecessary">
  update Author
    <set>
      <if test="username != null">username=#{username},</if>
      <if test="password != null">password=#{password},</if>
      <if test="email != null">email=#{email},</if>
      <if test="bio != null">bio=#{bio}</if>
    </set>
  where id=#{id}
</update>
trim

​ 模拟where: prefixOverrides属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)

​ 会移除所有 prefixOverrides属性中指定的内容,并且插入 prefix*属性中指定的内容

<trim prefix="WHERE" prefixOverrides="AND |OR ">
  <if test="state != null">
       state = #{state}
  </if>
  <if test="title != null">
      AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
      AND author_name like #{author.name}
  </if>
</trim>

​ 模拟set:覆盖了后缀值设置,并且自定义了前缀值

<trim prefix="SET" suffixOverrides=",">
  <if test="username != null">username=#{username},</if>
  <if test="password != null">password=#{password},</if>
  <if test="email != null">email=#{email},</if>
  <if test="bio != null">bio=#{bio}</if>
</trim>
foreach
<select id="queryBlogForeach" parameterType="map" resultType="blog">
  select * from blog where 1=1
   <where>
       <!--
       collection:指定输入对象中的集合属性
       item:每次遍历生成的对象
       open:开始遍历时的拼接字符串
       close:结束时拼接的字符串
       separator:遍历对象之间需要拼接的字符串
       select * from blog where 1=1 and (id=1 or id=2 or id=3)
     -->
       <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
          id=#{id}
       </foreach>
   </where>
</select>

5.缓存

Mybatis缓存
  • Mybatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存
    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
一级缓存失效的四种情况
  • sqlSession不同:结论:每个sqlSession中的缓存相互独立

  • sqlSession相同,查询条件不同:结论:当前缓存中,不存在这个数据

  • sqlSession相同,两次查询之间执行了增删改操作!结论:因为增删改操作可能会对当前数据产生影响

  • sqlSession相同,手动清除一级缓存

    session.clearCache();//手动清除缓存
    
二级缓存
  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存
  • 工作机制
    • 一个会话(sqlSession)查询一条数据,这个数据就会被放在当前会话的一级缓存中
    • 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中
    • 新的会话查询信息,就可以从二级缓存中获取内容
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中
使用二级缓存

1.在mybatis全局配置文件中开启全局缓存

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

2.在mapper映射文件中配置使用二级缓存

<cache/>

3.所有的实体类要实现序列化接口

public class Department implements Serializable {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值