zoukankan      html  css  js  c++  java
  • MyBatis原理

    The MyBatis SQL mapper framework makes it easier to use a relational database with object-oriented applications. MyBatis couples objects with stored procedures or SQL statements using a XML descriptor or annotations. Simplicity is the biggest advantage of the MyBatis data mapper over object relational mapping tools.

    MyBatis SQL mapper框架使面向对象应用程序更容易使用关系数据库。MyBatis使用XML描述符或注释将对象与存储过程或SQL语句耦合起来。简单性是MyBatis数据映射器相对于对象关系映射工具的最大优势。

    MyBatis是一个支持普通SQL查询存储过程高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录

    http://www.mybatis.org/mybatis-3/configuration.html

     

    mybatis的加载有几种方式?哪种优先级最高?

     

    mybatis一级缓存默认是开启还是关闭?

    mybatis的执行器有几种?

    DefaultSqlSession线程安全,还是非线程安全的?

     

    1.基于xml文件的实现

    为这个mapper指定一个唯一的namespace,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后缀)

    在select标签中编写查询的SQL语句, 设置select标签的id属性,id属性值必须是唯一的,不能够重复
    使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
    resultType="me.gacl.domain.User"就表示将查询结果封装成一个User类的对象返回
    比如User类就是users表所对应的实体类
    <?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
    例如namespace="me.gacl.mapping.userMapper"就是me.gacl.mapping(包名)+userMapper(userMapper.xml文件去除后缀)
     -->
    <mapper namespace="me.gacl.mapping.userMapper">
        <!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复
        使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
        resultType="me.gacl.domain.User"就表示将查询结果封装成一个User类的对象返回
        User类就是users表所对应的实体类
        -->
        <!-- 
            根据id查询得到一个user对象
         -->
        <select id="getUser" parameterType="int" 
            resultType="me.gacl.domain.User">
            select * from users where id=#{id}
        </select>
        
        <!-- 创建用户(Create) -->
        <insert id="addUser" parameterType="me.gacl.domain.User">
            insert into users(name,age) values(#{name},#{age})
        </insert>
        
        <!-- 删除用户(Remove) -->
        <delete id="deleteUser" parameterType="int">
            delete from users where id=#{id}
        </delete>
        
        <!-- 修改用户(Update) -->
        <update id="updateUser" parameterType="me.gacl.domain.User">
            update users set name=#{name},age=#{age} where id=#{id}
        </update>
        
        <!-- 查询全部用户-->
        <select id="getAllUsers" resultType="me.gacl.domain.User">
            select * from users
        </select>
        
    </mapper>
    

      

     

    2.基于注解的实现

     定义sql映射的接口,使用注解进行实现,比如常见的CRUD

    //使用@Insert注解指明add方法要执行的SQL
        @Insert("insert into users(name, age) values(#{name}, #{age})")
        public int add(User user);
        
        //使用@Delete注解指明deleteById方法要执行的SQL
        @Delete("delete from users where id=#{id}")
        public int deleteById(int id);
        
        //使用@Update注解指明update方法要执行的SQL
        @Update("update users set name=#{name},age=#{age} where id=#{id}")
        public int update(User user);
        
        //使用@Select注解指明getById方法要执行的SQL
        @Select("select * from users where id=#{id}")
        public User getById(int id);
        
        //使用@Select注解指明getAll方法要执行的SQL
        @Select("select * from users")
        public List<User> getAll();
    

      

    Mybatis

    一、MyBatis缓存介绍

      正如大多数持久层框架一样,MyBatis 同样提供了一级缓存二级缓存的支持

    1. 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush  close 之后,该Session中的所有 Cache 就将清空

      2. 二级缓存与一级缓存其机制相同,默认也是采用 PerpetualCache,HashMap存储,不同在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。

      3. 对于缓存数据更新机制,当某一个作用域(一级缓存Session/二级缓存Namespaces)的进行了 C/U/D 操作后,默认该作用域下所有 select 中的缓存将被clear。

    1.1、Mybatis一级缓存测试

    package me.gacl.test;
    
    import me.gacl.domain.User;
    import me.gacl.util.MyBatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    /**
     * @author gacl
     * 测试一级缓存
     */
    public class TestOneLevelCache {
        
        /*
         * 一级缓存: 也就Session级的缓存(默认开启)
         */
        @Test
        public void testCache1() {
            SqlSession session = MyBatisUtil.getSqlSession();
            String statement = "me.gacl.mapping.userMapper.getUser";
            User user = session.selectOne(statement, 1);
            System.out.println(user);
            
            /*
             * 一级缓存默认就会被使用
             */
            user = session.selectOne(statement, 1);
            System.out.println(user);
            session.close();
            /*
             1. 必须是同一个Session,如果session对象已经close()过了就不可能用了 
             */
            session = MyBatisUtil.getSqlSession();
            user = session.selectOne(statement, 1);
            System.out.println(user);
            
            /*
             2. 查询条件是一样的
             */
            user = session.selectOne(statement, 2);
            System.out.println(user);
            
            /*
             3. 没有执行过session.clearCache()清理缓存
             */
            //session.clearCache(); 
            user = session.selectOne(statement, 2);
            System.out.println(user);
            
            /*
             4. 没有执行过增删改的操作(这些操作都会清理缓存)
             */
            session.update("me.gacl.mapping.userMapper.updateUser",
                    new User(2, "user", 23));
            user = session.selectOne(statement, 2);
            System.out.println(user);
            
        }
    }
    

      

    1.2、Mybatis二级缓存测试

      1、开启二级缓存,在userMapper.xml文件中添加如下配置

    <mapper namespace="me.gacl.mapping.userMapper">
    <!-- 开启二级缓存 -->
    <cache/>

      2、测试二级缓存

    package me.gacl.test;
    
    import me.gacl.domain.User;
    import me.gacl.util.MyBatisUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.junit.Test;
    
    /**
     * @author gacl
     * 测试二级缓存
     */
    public class TestTwoLevelCache {
        
        /*
         * 测试二级缓存
         * 使用两个不同的SqlSession对象去执行相同查询条件的查询,第二次查询时不会再发送SQL语句,而是直接从缓存中取出数据
         */
        @Test
        public void testCache2() {
            String statement = "me.gacl.mapping.userMapper.getUser";
            SqlSessionFactory factory = MyBatisUtil.getSqlSessionFactory();
            //开启两个不同的SqlSession
            SqlSession session1 = factory.openSession();
            SqlSession session2 = factory.openSession();
            //使用二级缓存时,User类必须实现一个Serializable接口===> User implements Serializable
            User user = session1.selectOne(statement, 1);
            session1.commit();//不懂为啥,这个地方一定要提交事务之后二级缓存才会起作用
            System.out.println("user="+user);
            
            //由于使用的是两个不同的SqlSession对象,所以即使查询条件相同,一级缓存也不会开启使用
            user = session2.selectOne(statement, 1);
            //session2.commit();
            System.out.println("user2="+user);
        }
    }
    

      

    1.3、二级缓存补充说明

      1. 映射语句文件中的所有select语句将会被缓存。

      2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。

      3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。

      4. 缓存会根据指定的时间间隔来刷新。

      5. 缓存会存储1024个对象

    cache标签常用属性:

    <cache 
    eviction="FIFO"  <!--回收策略为先进先出-->
    flushInterval="60000" <!--自动刷新时间60s-->
    size="512" <!--最多缓存512个引用对象-->
    readOnly="true"/> <!--只读-->

     

     

  • 相关阅读:
    9.12 其他样式;JS
    9.11 样式表
    9.9 样式表
    PHP延迟几秒后执行,PHP延迟执行,PHP停顿几毫秒后执行 usleep() 和 sleep()
    PHP 去除url参数中出现+、空格、=、%、&、#等字符的解决办法, PHP去除影响url路径的字符
    java第一堂课-常用的电脑快捷键操作和重要的dos命令
    常用第三方接口,支付宝支付,微信支付,软著,IOS开发者账号
    苹果开发者账号申请流程完整版 https://www.jianshu.com/p/655380201685
    thinkphp 去重查询
    将数据导【入】【excel表】格式 前端页面
  • 原文地址:https://www.cnblogs.com/qianjinyan/p/10895719.html
Copyright © 2011-2022 走看看