mybatis

前言

  1. Mybatis 是什么?

  2. 我们为什么要学习 Mybatis?

  3. 持久化是什么?

  4. 持久层是什么?

  5. Mybatis 依赖

    <dependency> 
        <groupId>org.mybatis</groupId> 
        <artifactId>mybatis</artifactId> 
        <version>3.5.2</version>
    </dependency>
    
    <build>
            <!-- 更改maven编译规则 -->
            <resources>
                <resource>
                    <!-- 资源目录 -->
                    <directory>src/main/java</directory>
                    <includes>
                        <include>*.xml</include><!-- 默认(新添加自定义则失效) -->
                        <include>**/*.xml</include><!-- 新添加 */代表1级目录 **/代表多级目录 -->
                    </includes>
                    <filtering>true</filtering>
                </resource>
            </resources>
        </build>
    
  6. 使用mybatis流程

    1. 导入maven依赖
    2. 编写mybatis.xml配置文件(配置连接数据库环境)
    3. 编写工具类MybatisUtils
      1. 通过Resource.getResourceAsStream方法获得一个流
      2. 通过SqlSessionFactoryBuilder().build获得sqlSessionFactory
      3. 通过sqlSessionFactory.open获得sqlSession
    4. 编写dao在属性上加注解
    5. 编写mapper.xml
    6. 在pom.xml总配置文件中设置配置文件可以在任意路径
    7. 在mybatis.xml配置中加入映射器映射mapper.xml文件

一、mybatis 程序

1. 思路:搭建环境 -> 导入 mybatis 的 jar 包 -> 编写代码 -> 测试

2.mybatis 程序

  1. 写工具类读取 mybatis 的配置文件获取 sqlSession 对象。

    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import java.io.IOException;
    import java.io.InputStream;
    public class MybatisUtil { 
        
        private static SqlSessionFactory sqlSessionFactory; 
        
        static {     
            try {        
                // 使用mybatis第一步,获取sqlSessionFactory对象         
                String resource = "mybatis-config.xml";         
                InputStream inputStream = Resources.getResourceAsStream(resource);         
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);     
            } catch (IOException e) {         
                e.printStackTrace();     
            } 
        } 
        
        // 有了SqlSessionFactory,我们就可以获得sqlsession的实例了 
        // sqlsession对象完全包含了面向数据库执行sql命令需要的所有方法 
        public static SqlSession getSqlSession() {     
            return sqlSessionFactory.openSession(); 
        }
    }
    
  2. 配置 mybatis 配置文件,连接数据库。

    <!-- mybatis-config.xml -->
    <?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/mybatis01?useUnicode=true&amp;characterEncoding=UTF-8"/>            
                    <property name="username" value="root"/>            
                    <property name="password" value="root"/>      
                </dataSource>   
            </environment>
        </environments>
        
        <!--每一个mapper.xml都需要在mybatis核心配置文件中注册--> 
        <mappers>     
            <mapper resource="com/neu/mapper/UserMapper.xml"></mapper> 
        </mappers>
        
    </configuration>
    
  3. 搭建环境,编写代码。(User,UserMapper 接口,UserMapper.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="com.neu.mapper.UserMapper">
        
        <delete id="deleteUser">    
            delete from user 
            where id = #{userId}
        </delete>
        
        <select id="selectUserList" resultType="com.neu.entity.User">  
            select * from user 
        </select> 
        
        <select id="selectById" resultType="com.neu.entity.User">     
            select * 
            from user
            where id = #{id} 
        </select> 
        
        <insert id="insertUser" parameterType="com.neu.entity.User">    
            insert into user(name,age) 
            values (#{name},#{age}) 
        </insert>
        
    </mapper>
    
  4. 测试。

    @Test 
    public void test01(){     
        // 1.获取sqlsession对象   
        SqlSession sqlSession = MybatisUtil.getSqlSession();    
        // 2.方式一:获取UserMapper接口,去执行方法    
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);  
        
        List<User> users = mapper.selectUserList();   
        
        for (User user : users) {        
            System.out.println(user);    
        } 
    } 
    
    @Test 
    public void test05(){ 
        
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        //方式二:通过全限定名直接调用方法
        List<User> userList = sqlSession.selectList("com.neu.mapper.UserMapper.selectUserList");  
        
        for (User user : userList) {       
            System.out.println(user);   
        } 
    }
    

3. 可能出现的问题

  1. 配置文件没有注册。(mybatis 配置文件中的 没有配置)
  2. 绑定接口错误。(UserMapper.xml 文件中的 namespace 配置不对)
  3. 方法名不对。(UserMapper.xml 文件中 id 对应的方法名不对)
  4. 返回类型不对。(UserMapper.xml 文件的 resultType 类型不对)
  5. 资源导出失败问题。(需要在 pom.xml 中的 build 中配置 resources)

4. 注意点

  1. resource 绑定 mapper,需要使用路径 /

二、crud

1. 万能 Map

  1. Map 传递参数,直接在 sq 中取出 Map 的 key。

    Map map = new Map();
    map.set("name","zhangsan");
    map.set("userId",1);
    mapper.getUserById(map);
    // UserMapperUser getUserById(Map map);
    // UserMapper.xml
    // <select id="getUserById" parameterType="map"> 
    //      select * 
    //      from user 
    //      where username=#{name} or user_id=#{userId}
    // </select>
    
  2. 对象传递参数,直接在 sq 中取对象的属性。

    User user = new User();
    user.setUsername("zhangsan");
    user.setUserId(1);
    mapper.getUserById(user);
    // UserMapperUser getUserById(User user);
    // UserMapper.xml
    // <select id="getUserById" parameterType="user"> 
    // 		select * 
    //      from user 
    //		where username=#{username} or user_id=#{userId}
    // </select>
    
  3. 只有一个基本类型参数的情况下,可以直接在 sq 中取到,省略 parameterType。

    mapper.getUserById(id);
    // UserMapperUser getUserById(int id);
    // UserMapper.xml
    // <select id="getUserById"> 
    //    	select * 
    //      from user 
    //		where username=#{username} or user_id=#{userId}
    // </select>
    
  4. 多个参数传递时,用 Map,或者 @RequestParm注解。

2. 模糊查询

  1. java 代码执行时传递通配符。

    List<User> userList = mapper.getUserList("%李%");
    
  2. 在 sql 拼接时使用通配符。

    select * from user where username like "%"#{username}"%"
    

三、配置优化

1. 总配置

#db.properties 加上jdbc前缀避免出错(连接不到数据库)jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/mybatis?useEncoding=true&characterEncoding=utf-8jdbc.username=rootjdbc.password=xxx
<!-- mybatis-config.xml --><?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>           <!--引入外部配置文件:可以增加属性-->        <!--如果外部配置文件和增加的属性都用,优先使用外部配置-->        <properties resource="db.properties">        <!--db.properties在resources目录下可以直接写文件名-->               <property name="username" value="root"/>              <property name="password" value="root"/>        </properties>        <!--settings配置-->       <settings>             <!--全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认true-->          <setting name="cacheEnabled" value="true"/>            <!--延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。也就是用到时才加载        特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。默认false-->              <setting name="lazyLoadingEnabled" value="默认false"/>             <!--允许JDBC支持自动生成主键,需要数据库驱动支持。默认false-->            <setting name="useGeneratedKeys" value="false"/>            <!--指定MyBatis所用日志的具体实现,未指定时将自动查找。默认未指定-->             <setting name="logImpl" value="LOG4J"/>     </settings>           <!--别名设置:1给实体类起别名,2配置一个包名-->      <typeAliases>         <!--<typeAlias type="com.neu.entity.User" alias="user"></typeAlias>-->               <package name="com.neu.entity"/>       </typeAliases>         <environments default="development">             <!--环境一-->          <environment id="development">                      <!--mybatis事务管理器:默认时JDBC,还有一个managed-->                   <transactionManager type="JDBC"/>                     <!--mybatis数据源:默认POOLED,还有UNPOOLED和JNDI-->                 <dataSource type="POOLED">                           <property name="driver" value="${driver}"/>                      <property name="url" value="${url}"/>                           <property name="username" value="${username}"/>                     <property name="password" value="${password}"/>                    </dataSource>            </environment>           <!--环境二-->              <environment id="test">                     <transactionManager type="JDBC"/>                    <dataSource type="POOLED">                       <property name="driver" value="${driver}"/>                     <property name="url" value="${url}"/>                       <property name="username" value="${username}"/>                      <property name="password" value="${password}"/>                   </dataSource>             </environment>       </environments>          <!--mappers映射器-->     <mappers>             <mapper resource="org/mybatis/example/BlogMapper.xml"/>     </mappers>    </configuration>

2. 相关配置属性

  1. properties(属性)

  2. settings(设置)

  3. typeAliases(类型别名)

  4. environments(环境配置)

    • environment(环境变量)
      • transactionManager(事务管理器)
      • dataSource(数据源)
        不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
  5. mappers(映射器)

    1. 方式一:resource(推荐使用)

      <mappers>     <!--每一个Mapper.xml文件都需要在核心配置文件中注册-->     <mapper resource="com/neu/mapper/UserMapper.xml"/></mappers>
      
    2. 方式二:使用 class 文件绑定注册

      <mappers>     <!--每一个接口都需要在核心配置文件中注册-->    <mapper class="com.neu.mapper.UserMapper"/></mappers><!-- 注意:--><!--1接口和它的Mapper.xml配置文件必须同名。--><!--2接口和它的Mapper.xml配置文件必须在同一个包下。-->
      
    3. 方式三:使用扫描包进行绑定注册。

      <mappers>    <package name="com.neu.mapper"/></mappers><!--注意:--><!--1接口和它的Mapper.xml配置文件必须同名。--><!--2接口和它的Mapper.xml配置文件必须在同一个包下。-->
      

四、生命周期和作用域

生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题

img

  1. SqlSessionFactoryBuider 作用域。
    • 一旦创建了 SqlSessionFactory,就不再需要它了
    • 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(局部方法变量)
  2. SqlSessionFactory 作用域。
    • SqlSessionFactory 可以想象成连接池。
    • SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
    • 因此 SqlSessionFactory 的最佳作用域是应用作用域。有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。
  3. SqlSession 作用域。
    • 可以视为连接到连接池的一个请求。
    • SqlSession 的实例不是线程安全的,因此是不能被共享的。
    • 所以它的最佳的作用域是请求或方法作用域。
    • 用完之后关闭,否则资源会被占用。
    • 为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中。

五、ResultMap

1.ResultMap 结果集映射。

  1. 起别名

    <mapper namespace="com.neu.mapper.UserMapper">    <select id="getUserById" resultType="com.neu.entity.User">           select id,username,pwd as password         from User         where id = #{id}    </select></mapper>
    
  2. ResultMap 结果集映射(可以只映射字段名和属性名不同的)

    <resultMap id="userMap" type="com.neu.entity.User">     <id column="id" property="id"/>    <!--数据库字段id和实体类属性id名称一致可省略id的映射-->    <result column="username" property="username"/>    <!--数据库字段username和实体类属性username名称一致可省略username的映射-->    <result column="pwd" property="password"/>    <!--数据库字段pwd和实体类属性password名称不一致不可省略的映射--></resultMap><select id="getUserById" resultMap="userMap">     select id,username,pwd     from User     where id = #{id}</select>
    

2.ResultMap 多对一映射

2.1 按照查询嵌套处理
@Datapublic class Student {       private int id;      private String username;      private Teacher teacher;}
<mapper namespace="com.neu.mapper.StudentMapper">      <!--    	思路:1.查询所有的学生         	 2.根据查询出来的学生表的tid字段,查找对应的老师    -->        <resultMap id="studentTeacherMap" type="com.neu.entity.Student">             <id property="id" column="id"></id>               <result property="username" column="username"/>             <!--对象:association,tid是学生表中关联的老师的id-->             <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>        </resultMap>           <select id="getStudentList" resultMap="studentTeacherMap">             select *         from student      </select>          <select id="getTeacher" resultType="Teacher">               select *         from teacher         where id = #{tid}        <!--这个参数名推荐和上面column="tid"保持一致,但是不保持一致也不会出错-->        </select></mapper>
2.1 按照结果嵌套处理
<mapper namespace="com.neu.mapper.StudentMapper">            <resultMap id="studentTeacherMap" type="com.neu.entity.Student">             <id property="id" column="id"></id>            <result property="username" column="username"/>               <!--对象:association-->            <association property="teacher" javaType="Teacher">                       <id property="id" column="tid"></id>                   <result property="username" column="tname"></result>             </association>       </resultMap>         <select id="getStudentList" resultMap="studentTeacherMap">              select s.id,s.username,t.id tid,t.username tname         from student s,teacher t         where s.tid=t.id        </select></mapper>

3.ResultMap 一对多映射

3.1 按照查询嵌套处理
@Datapublic class Teacher {       private int id;     private String username;     private List<Student> studentList;}
<mapper namespace="com.neu.mapper.TeacherMapper">        <!--    	思路:1.查询指定的老师         	  	     2.根据查询出来的老师的id字段别名是ttid,查找老师下对应的所有学生    -->        <resultMap id="teacherStudentMap" type="Teacher">                <id property="id" column="ttid"></id>                <!--ttid是老师表的id-->               <collection property="studentList" javaType="ArrayList" ofType="Student" select="getStudentByTeacherId" column="ttid"/>        </resultMap>           <!--按照查询嵌套处理-->        <select id="getTeacherById" resultMap="teacherStudentMap">              select t.id ttid,t.*         from teacher t         where id=#{tid}       </select>          <select id="getStudentByTeacherId" resultType="Student">             select *         from student         where tid = #{ttid}      </select>    </mapper>
3.2 按照结果嵌套处理
<mapper namespace="com.neu.mapper.TeacherMapper">         <resultMap id="teacherStudentMap" type="Teacher">             <id property="id" column="tid"/>            <result property="username" column="tname"/>            <!--         	复杂的属性单独处理,集合:collection        	javaType=""指定实体类属性的类型;        	集合中的泛型信息,使用ofType获取。        -->                <collection property="studentList" ofType="Student">                     <id property="id" column="tid"/>                  <result property="username" column="sname"/>              <result property="tid" column="tid"/>            </collection>     </resultMap>           <!--按结果嵌套查询-->       <select id="getTeacherById" resultMap="teacherStudentMap">             select s.id sid,s.username sname,t.id tid,t.username tname         from student s,teacher t         where s.tid=t.id and t.id=#{tid}        </select>    </mapper>

六、日志工厂

1.mybatis 的日志配置

使用哪个日志实现在 mybatis-config.xml 设置中配置
img

  • SLF4J
  • LOG4J(掌握)
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING(掌握:标准日志输出)
  • NO_LOGGING0

2.log4j

  • Log4j 是 Apache 的一个开源项目,通过使用 Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI 组件。
  • 我们也可以控制每一条日志的输出格式。
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
  • 最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

3.mybatis 使用 log4j 步骤

  1. 导入 log4j 的 jar 包。

    <dependency>     <groupId>log4j</groupId>     <artifactId>log4j</artifactId>    <version>1.2.17</version></dependency>
    
  2. 设置 mybatis 配置文件的日志实现类是 LOG4J

    <settings>        <!--指定MyBatis所用日志的具体实现,未指定时将自动查找。默认未指定-->       <setting name="logImpl" value="LOG4J"/></settings>
    
  3. 书写 log4j.properties 配置文件。

    # 将等级为DEBUG的日志信息输出到console和file两个目的地log4j.rootLogger=DEBUG,console,file# 控制台输出相关配置log4j.appender.console=org.apache.log4j.ConsoleAppenderlog4j.appender.Threshold=DEBUGlog4j.appender.console.Target=System.outlog4j.appender.console.layout=org.apache.log4j.PatternLayoutlog4j.appender.console.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c] \:%m%n# 文件输出的相关配置log4j.appender.file=org.apache.log4j.RollingFileAppenderlog4j.appender.file.File=./logs/all.loglog4j.appender.file.MaxFileSize=10mblog4j.appender.file.Threshold=DEBUGlog4j.appender.file.layout=org.apache.log4j.PatternLayoutlog4j.appender.file.layout.ConversionPattern=[%-5p][%d{yyyy-MM-dd HH\:mm\:ss,SSS}][%c] \:%m%n# 日志输出级别log4j.logger.org.mybatis=DEBUGlog4j.logger.java.sql=DEBUGlog4j.logger.java.sql.Statement=DEBUGlog4j.logger.java.sql.ResultSet=DEBUGlog4j.logger.java.sql.PreparedStatement=DEBUG
    

七、分页和注解开发

1.limit 分页

// i : 为查询结果的索引值(默认从0开始)// n : 为查询结果返回的数量select * from user limit i,n;// 传一个参数时,意思是从第一个数据开始查询n个数据。select * from user limit n;

2.RowBounds 分页

// 代码成设置分页@Testpublic void test02(){        SqlSession sqlSession = SqlSessionUtil.getSqlSession();       RowBounds rowBounds = new RowBounds(1, 2);      List<User> userList = sqlSession.selectList("com.neu.mapper.UserMapper.selectList", rowBounds);    }

3.mybatis 的 PageHelper 分页插件。

4. 注解开发

@Select("select * from user")List<User> selectUser();@Insert("")void insertUser(User user);@Update("")void updateUser(User user);@Delete("")void deleteUserById(int id);

八、mybatis 执行流程

img

九、动态 SQL

  • 动态 SQL 是指根据不同的条件生成不同的 SQL 语句。
  • 动态 SQL 本质还是 SQL 语句,只是我们可以在 SQL 层面,执行一个逻辑代码。
  • 动态 SQL 就是在拼接 SQL 语句,我们只要保证 SQL 正确性,按照 SQL 格式去排列组合就可以了。

1.if

<select id="queryBlogIF" paremterType="map" resultType="blog">      select *     from blog     where 1=1       <if test="title != null">               title = #{title}       </if>          <if test="author != null">           and author = #{author}        </if>    </select>

2.choose,when,otherwise

<select id="queryBlogChoose" paremterType="map" resultType="blog">     select *     from blog           <where>              <choose>                             <!--只会选择其中一个去执行-->                 <when test="title != null">                        title = #{title}                    </when>                            <when test="author != null">                 and author = #{author}                   </when>                          <otherwise>                        and views = #{views}               </otherwise>                     </choose>      </where>    </select>

3.trim(where,set)

标签作用:

  • where 标签元素中有子元素返回任何内容的情况下才插入 “where” 子句。
  • 如果子句的开头为”AND” 或”OR”,where 标签元素会将他们去除。

标签作用:

  • 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>
    

4.foreach

<select id="selectPostIn" resultType="User">    select *      from user u    where id in         <foreach item="id" index="index" collection="ids" open="(" separator="," close=")">              #{id}     </foreach>    </select>

5.SQL 片段

  • 可以将一些功能的部分抽取出来,方便复用。

    5.1 使用 SQL 标签抽取公共的部分。
    <sql id="if-title-author">         <if test="title != null">         title = #{title}     </if>         <if test="author != null">         and author = #{author}     </if>    </sql>
    
    5.2 在需要的地方使用 include 标签引用即可。
    <select id="queryBlogIF" paremterType="map" resultType="blog">     select *    from blog        <where>           <include refid="if-title-anthor"></include>      </where>    </select>
    

十、缓存

  1. 什么是缓存 [Cache]?
    • 存在内存中的临时数据。
    • 将用户经常查询的数据放在缓存中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中査询,从而提高査询效率,解决了高并发系统的性能问题。
  2. 为什么使用缓存?
    • 减少和数据库的交互次数,减少系统开销,提高系统效率。
  3. 什么样的数据能使用缓存?
    • 经常査询并且不经常改变的数据。

1.mybatis 缓存

  • mybatis 默认定义了两级缓存:一级缓存和二级缓存
  • 默认情况下,只有一级缓存开启。(SqlSession 级别的缓存)
  • 二级缓存需要手动开启和配置,基于 namespace 级别的缓存。
  • 为了提高扩展性,mybatis 定义了缓存接口 Cache。(我们可以通过实现 Cache 接口来自定义二级缓存)

2. 一级缓存

2.1 测试步骤
  1. 开启日志。
  2. 测试在一个 SqlSession 中查询两次相同的记录。
  3. 查看日志输出。(只查询了一次数据库 SQL,第二次直接从缓存中数据)
2.2 一级缓存失效的情况
  1. 查询不同的东西。
  2. 增删改操作,可能会改变原来的数据,所以必定会刷新缓存。
  3. 查询不同的 mapper.xml
  4. 手动清理缓存。(sqlSession.clearCache ();)
2.3 一级缓存总结
  • 一级缓存默认是开启的。
  • 一级缓存只在一次 SqlSession 中有效,即拿到连接到连接关闭的这个区间。

3. 二级缓存

3.1 二级缓存使用步骤
  1. 开启全局缓存。

    <settings>     <!--默认是true,建议显式的在配置文件中声明-->    <setting name="cacheEnabled" value="true"/></settings>
    
  2. 在要使用二级缓存的 mapper.xml 中开启。

    <!--直接开启使用--><cache/><!--也可以自定义参数开启使用--><cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
    

    LRU – 最近最少使用:移除最长时间不被使用的对象。

    FIFO – 先进先出:按对象进入缓存的顺序来移除它们。

    SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。

    WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。

  3. 测试。

    • 需要把实体类序列化(实体类实现 Serializable 接口),否则可能会报错。
3.2 二级缓存总结
  • 只要开启了二级缓存,在同一个 mapper 下有效。

  • 所有的数据都会先放在一级缓存中。

  • 只有当会话提交或关闭的时候,才会提交到二级缓存中。

  • 可以在 mapper.xml 中的查询语句定义是否使用缓存

    <select id="getUser"resultType="user" userCache="false">     select *     from user</select>
    

4. 缓存原理

img

5. 自定义缓存 - ehcache

Ehcache 是一种广泛使用的开源 Java 分布式缓存。主要面向通用缓存

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

配置一个 ehcache.xml 配置

总结

  1. mybatis 是一款优秀的持久层框架,可以把数据持久化;它支持定制化 sql,存储过程,结果集映射等。
  2. 使用的人多,传统的 jdbc 代码太复杂了,mybatis 框架简化了流程,自动化。
  3. 持久化是数据从瞬时状态转化到持久状态。内存的特性是断电即失,持久化指存到数据库中,io 文件持久化等。
  4. 持久层是完成持久化工作的代码块。

面试题

  1. MySQL 引擎
  2. InnoDB 底层原理
  3. 索引
  4. 索引优化
  5. 读写分离
  6. 主从复制
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值