广告
返回顶部
首页 > 资讯 > 精选 >Mybatis基础概念与高级应用方法
  • 702
分享到

Mybatis基础概念与高级应用方法

2023-07-02 09:07:19 702人浏览 安东尼
摘要

今天小编给大家分享一下mybatis基础概念与高级应用方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。Mybatis基础回

今天小编给大家分享一下mybatis基础概念与高级应用方法的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

Mybatis基础回顾与高级应用

数据库:mysql5.7

jdk:15

引入依赖

<!--引入依赖-->    <dependencies>        <!--mybatis坐标-->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.4.5</version>        </dependency>        <!--Mysql驱动坐标-->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.6</version>            <scope>runtime</scope>        </dependency>        <!--单元测试坐标-->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>        </dependency>        <dependency>            <groupId>org.projectlombok</groupId>            <artifactId>lombok</artifactId>            <version>1.18.22</version>        </dependency>    </dependencies>

User实体

@Datapublic class User {    private Integer id;    private String username;}

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://127.0.0.1/zdy_mybatisjdbc.username=rootjdbc.passWord=root

sqlMapConfig.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文件-->    <properties resource="jdbc.properties"></properties>    <!--给实体类的全限定类名给别名-->    <typeAliases>        <!--给单独的实体起别名-->     <!--   <typeAlias type="com.yun.pojo.User" alias="user"></typeAlias>-->        <!--批量起别名:该包下所有的类的本身的类名:别名还不区分大小写-->        <package name="com.yun.pojo"/>    </typeAliases>    <!--environments:运行环境-->    <environments default="development">        <environment id="development">            <!--当前事务交由JDBC进行管理-->            <transactionManager type="JDBC"></transactionManager>            <!--当前使用mybatis提供的连接池-->            <dataSource type="POOLED">                <property name="driver" value="${jdbc.driver}"/>                <property name="url" value="${jdbc.url}"/>                <property name="username" value="${jdbc.username}"/>                <property name="password" value="${jdbc.password}"/>            </dataSource>        </environment>    </environments>    <!--引入映射配置文件-->    <mappers>        <mapper resource="UserMapper.xml"></mapper>    </mappers></configuration>

案例一-查询用户

UserMapper.xml

<mapper namespace="user">    <!--select-->    <select id="findAll" resultType="com.yun.pojo.User">        select * from user    </select></mapper>
@Test    public void test1() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession        // 默认开启一个事务,但是该事务不会自动提交        //在进行增删改操作时,要手动提交事务        SqlSession sqlSession = sqlSessionFactory.openSession();        //4.sqlSession调用方法:查询所有selectList  查询单个:selectOne 添加:insert  修改:update 删除:delete        List<User> users = sqlSession.selectList("user.findAll");        users.forEach(item ->{            System.out.println(item);        });        sqlSession.close();    }

输出结果

User(id=1, username=Tom)
User(id=2, username=Jerry)

案例二-添加用户

UserMapper.xml

<!--parameterType:参数类型--><insert id="saveUser" parameterType="com.yun.pojo.User">        insert into user Values (#{id},#{username})</insert>
@Test    public void test2() throws IOException {        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        User user = new User();        user.setId(3);        user.setUsername("jack");        sqlSession.insert("user.saveUser",user);        sqlSession.commit();        sqlSession.close();    }

数据库结果:

Mybatis基础概念与高级应用方法

案例三-编辑用户

UserMapper.xml

<update id="updateUser" parameterType="com.yun.pojo.User">        update user set username = #{username} where id = #{id}</update>
@Test    public void test3() throws IOException {        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        User user = new User();        user.setId(3);        user.setUsername("rose");        sqlSession.update("user.updateUser",user);        sqlSession.commit();        sqlSession.close();    }

数据库结果:

Mybatis基础概念与高级应用方法

案例四-删除用户

UserMapper.xml

<delete id="deleteUser" parameterType="java.lang.Integer">        delete from user where id =#{id}</delete>
 @Test    public void test4() throws IOException {        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        User user = new User();        user.setId(3);        sqlSession.delete("user.deleteUser",3);        sqlSession.commit();        sqlSession.close();    }

数据库结果:

Mybatis基础概念与高级应用方法

传统开发方式

public interface IUserDao {    //查询所有用户    List<User> findAll() throws IOException;}

UserDaoImpl

public class UserDaoImpl implements IUserDao {    @Override    public List<User> findAll() throws IOException {        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        List<User> users = sqlSession.selectList("user.findAll");        sqlSession.close();        return users;    }}
@Test    public void test5() throws IOException {        UserDaoImpl dao = new UserDaoImpl();        List<User> users = dao.findAll();        System.out.println(users);    }

打印结果:

[User(id=1, username=Tom), User(id=2, username=Jerry)]

代理开发方式(使用JDK动态代理产生代理对象,由代理对象执行并且操作)

Mapper接口开发需要遵行以下规范:

mapper.xml文件中的namespace与mapper接口的全限定名相同;
2. mapper接口方法名和mapper.xml中定义的每个statement的id相同
3. mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
4. mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

根据上述的规范修改UserMapper.xml

<mapper namespace="com.yun.dao.IUserDao">    <!--select-->    <select id="findAll" resultType="com.yun.pojo.User">        select * from user    </select></mapper>
public interface IUserDao {    //查询所有用户    List<User> findAll() throws IOException;}
@Testpublic void test6() throws IOException {    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);    SqlSession sqlSession = sqlSessionFactory.openSession();    IUserDao mapper = sqlSession.getMapper(IUserDao.class);    List<User> all = mapper.findAll();    all.forEach(item ->{        System.out.println(all);    });}

输出结果:

User(id=1, username=Tom)
User(id=2, username=Jerry)

动态sql语句 if标签

public interface IUserDao {    //多条件组合查询:演示if    public List<User> findByCondition(User user);}
<!--抽取sql片段--><sql id="selectUser">    select * from user</sql><!--多条件组合查询:演示if--><select id="findByCondition" parameterType="user" resultType="user">   <include refid="selectUser"></include>   <where>       <if test="id !=null">           and id = #{id}       </if>       <if test="username !=null">           and username = #{username}       </if>   </where></select>
@Test    public void test7() throws IOException {        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);        SqlSession sqlSession = sqlSessionFactory.openSession();        IUserDao mapper = sqlSession.getMapper(IUserDao.class);        User user1 = new User();        user1.setId(1);        user1.setUsername("Tom");        List<User> all = mapper.findByCondition(user1);        for (User user : all) {            System.out.println(user);        }    }

输出结果:

User(id=1, username=Tom)

动态sql语句 foreach标签

public interface IUserDao {    //多值查询:演示foreach    public List<User> findByIds(int[] ids);}
<!--多值查询:演示foreach--><select id="findByIds" parameterType="list" resultType="user">   <include refid="selectUser"></include>   <where>       <foreach collection="array" open="id in (" close=")" item="id" separator=",">           #{id}       </foreach>   </where></select>
@Testpublic void test8() throws IOException {   InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");   SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);   SqlSession sqlSession = sqlSessionFactory.openSession();   IUserDao mapper = sqlSession.getMapper(IUserDao.class);   int[] arr = {1,2};   List<User> all = mapper.findByIds(arr);   for (User user : all) {       System.out.println(user);   }}

输出结果:

User(id=1, username=Tom)
User(id=2, username=Jerry)

Mybatis复杂映射

一对一

User实体

@Datapublic class User {    private Integer id;    private String username;    //该用户所具有的订单信息    private List<Order> orders;    //该用户所具有的角色信息    private List<Role> roles;}

Order实体

@Datapublic class Order {    private Integer id;    private String orderTime;    private BigDecimal total;    //表明该订单属于哪个用户    private User user;}

Role实体

@Datapublic class Role {    private Integer id;    private String roleName;}
public interface IOrderMapper {        public List<Order> findOrderAndUser();}
<resultMap id="orderMap" type="com.yun.pojo.Order">    <result property="id" column="id"></result>    <result property="orderTime" column="order_time"></result>    <result property="total" column="total"></result>    <association property="user" javaType="com.yun.pojo.User">        <result property="id" column="uid"></result>        <result property="username" column="username"></result>    </association></resultMap><!--resultMap:手动来配置实体属性与表字段的映射关系--><select id="findOrderAndUser" resultMap="orderMap">    select * from orders o,user u  where o.uid = u.id</select>
@Testpublic void test1() throws IOException {    //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流    InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");    //2.解析了配置文件,并创建了sqlSessionFactory工厂    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    //3.生产sqlSession    SqlSession sqlSession = sqlSessionFactory.openSession();    IOrderMapper mapper = sqlSession.getMapper(IOrderMapper.class);    List<Order> orderAndUser = mapper.findOrderAndUser();    orderAndUser.forEach(order -> {        System.out.println(order);    });}

运行结果:

Order(id=1, orderTime=2022-05-01, total=1000.00, user=User(id=1, username=Tom, orders=null, roles=null))
Order(id=2, orderTime=2022-05-10, total=2000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
Order(id=3, orderTime=2022-05-20, total=3000.00, user=User(id=2, username=Jerry, orders=null, roles=null))

一对多

public interface IUserMapper {        public List<User> findAll();}
<resultMap id="userMap" type="com.yun.pojo.User">    <id property="id" column="id"></id>    <result property="username" column="username"></result>    <collection property="orders" ofType="com.yun.pojo.Order">        <id property="id" column="oid"></id>        <result property="orderTime" column="order_time"></result>        <result property="total" column="total"></result>    </collection></resultMap><!--resultMap:手动来配置实体属性与表字段的映射关系--><select id="findAll" resultMap="userMap">    select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid</select>
@Test    public void test2() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession        SqlSession sqlSession = sqlSessionFactory.openSession();        IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);        List<User> users = mapper.findAll();        users.forEach(user -> {            System.out.println(user.getUsername());            System.out.println(user.getOrders());        });    }

运行结果:

Tom
[Order(id=1, orderTime=2022-05-01, total=1000.00, user=null)]
Jerry
[Order(id=2, orderTime=2022-05-10, total=2000.00, user=null), Order(id=3, orderTime=2022-05-20, total=3000.00, user=null)]

多对多

public interface IUserMapper {        public List<User> findUserAndRole();}
<resultMap id="userAndRoleMap" type="com.yun.pojo.User">    <result property="id" column="userId"></result>    <result property="username" column="username"></result>    <collection property="roles" ofType="com.yun.pojo.Role">        <result property="id" column="roleId"></result>        <result property="roleName" column="rolename"></result>    </collection></resultMap><select id="findUserAndRole" resultMap="userAndRoleMap">    SELECT * FROM USER u    LEFT JOIN sys_user_role sur ON u.id = sur.user_id    LEFT JOIN sys_role sr ON sur.role_id = sr.id</select>
@Testpublic void test3() throws IOException {    //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流    InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");    //2.解析了配置文件,并创建了sqlSessionFactory工厂    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);    //3.生产sqlSession    SqlSession sqlSession = sqlSessionFactory.openSession();    IUserMapper mapper = sqlSession.getMapper(IUserMapper.class);    List<User> users = mapper.findUserAndRole();    users.forEach(user -> {        System.out.println(user.getUsername());        System.out.println(user.getRoles());    });}

运行结果:

Tom
[Role(id=null, roleName=董事长), Role(id=null, roleName=经理)]
Jerry
[Role(id=null, roleName=董事长), Role(id=null, roleName=经理)]

Mybatis注解开发

Mybasits常用注解:
@Insert: 实现新增@Update: 实现更新@Delete: 实现删除@Select: 实现查询@Result: 实现结果集封装;他代替的是标签<resultMap>,该注解中可以使用单个@Result注解,也可以使用@Result集合,         使用格式:@Results({@Result(),@Result()}) 或 @Results(@Result())@Results: 可以与@Result一起使用,封装多个结果集@One: 实现一对一结果集封装@Many: 实现一对多结果集封装

测试案例

public interface IUserMapper {    //添加用户    @Insert("insert into user values(#{id},#{username})")    public void addUser(User user);    //更新用户    @Update("update user set username = #{} where id = #{id}")    public void updateUser(User user);    //查询用户    @Select("select * from user")    public List<User> getAllUser();    //删除用户    @Delete("delete from user where id=#{id}")    public void delUser(Integer id);}
private IUserMapper mapper;    @Before    public void before() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession                                     true:事务自动提交        SqlSession sqlSession = sqlSessionFactory.openSession(true);        mapper = sqlSession.getMapper(IUserMapper.class);    }    @Test    public void addUser(){        User user = new User();        user.setId(3);        user.setUsername("jack");        mapper.addUser(user);    }    @Test    public void updateUser(){        User user = new User();        user.setId(3);        user.setUsername("rose");        mapper.updateUser(user);    }    @Test    public void getAllUser(){        List<User> userList = mapper.getAllUser();        userList.forEach(item -> {            System.out.println(item);        });    }    @Test    public void delUser(){        mapper.delUser(3);    }

运行结果:

Mybatis基础概念与高级应用方法

Mybatis注解实现复杂映射开发

一对一

public interface IOrderMapper {        @Results({            @Result(property = "id",column = "id"),            @Result(property = "orderTime",column = "order_time"),            @Result(property = "total",column = "total"),            @Result(property = "user",column = "uid",javaType = User.class,                    one = @One(select = "com.yun.mapper.IUserMapper.getUserById")),    })    @Select("select * from orders")    public List<Order> findOrderAndUser();}public interface IUserMapper {    @Select("select * from user where id = #{id}")    public User getUserById(Integer id);}
@Test    public void oneToOne(){        List<Order> orderAndUser = orderMapper.findOrderAndUser();        orderAndUser.forEach(item -> {            System.out.println(item);        });    }

运行结果:

Order(id=1, orderTime=2022-05-01, total=1000.00, user=User(id=1, username=Tom, orders=null, roles=null))
Order(id=2, orderTime=2022-05-10, total=2000.00, user=User(id=2, username=Jerry, orders=null, roles=null))
Order(id=3, orderTime=2022-05-20, total=3000.00, user=User(id=2, username=Jerry, orders=null, roles=null))

一对多

public interface IUserMapper {        @Select("select * from user")    @Results({            @Result(property = "id",column = "id"),            @Result(property = "username",column = "username"),            @Result(property = "orders",column = "id",javaType = List.class,                    many = @Many(select = "com.yun.mapper.IOrderMapper.getOrderByUid"))    })    public List<User> findAll();}public interface IOrderMapper {    @Select("select * from orders where uid = #{uid}")    public List<Order> getOrderByUid(Integer uid);}
@Test    public void oneToMore(){        List<User> users = mapper.findAll();        users.forEach(item -> {            System.out.println(item);        });    }

运行结果:

User(id=1, username=Tom, orders=[Order(id=1, orderTime=null, total=1000.00, user=null)], roles=null)
User(id=2, username=Jerry, orders=[Order(id=2, orderTime=null, total=2000.00, user=null), Order(id=3, orderTime=null, total=3000.00, user=null)], roles=null)

多对多

public interface IUserMapper {            @Select("select * from user")    @Results({            @Result(property = "id",column = "id"),            @Result(property = "username",column = "username"),            @Result(property = "roles",column = "id",javaType = List.class,                    many = @Many(select ="com.yun.mapper.IRoleMapper.getAll"))    })    public List<User> findUserAndRole();}public interface IRoleMapper {    @Select("select * from sys_role sr,sys_user_role sur where sr.id = sur.role_id and sur.user_id = #{uid}")    public List<Role> getAll(Integer uid);}
@Testpublic void moreToMore(){        List<User> users = mapper.findUserAndRole();    users.forEach(item -> {        System.out.println(item);    });}

运行结果:

User(id=1, username=Tom, orders=null, roles=[Role(id=1, roleName=董事长), Role(id=2, roleName=经理)])
User(id=2, username=Jerry, orders=null, roles=[Role(id=1, roleName=董事长), Role(id=2, roleName=经理)])

Mybatis缓存

基础概念

Mybatis基础概念与高级应用方法

缓存就是内存中的数据,常常来自对数据库查询结果的保存,使用缓存,我们可以避免频繁的与数据库进行交互,进而提高响应速度.

一级缓存是SqlSession,在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据.不同的sqlSession之间互不影响.

二级缓存是mapper级别的缓存,多个sqlSession去操作同一个mapper的sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨sqlSession的.

一级缓存

demo

public class CacheTest {    private IUserMapper mapper;    private SqlSession sqlSession;    @Before    public void before() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession                          true:事务自动提交        sqlSession = sqlSessionFactory.openSession(true);        mapper = sqlSession.getMapper(IUserMapper.class);    }    @Test    public void test1() {        //第一次查询id为1的用户        User user1 = mapper.getUserById(1);        //第二次查询id为1的用户        User user2 = mapper.getUserById(1);        System.out.println(user1 == user2);    }}
返回结果为 true ;测试一级缓存是默认开启的
结论:第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户,如果没有,则从数据库查询用户信息,得到用户信息并且将用户信息存储到一级缓存中,第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户,如果缓存中有,直接从缓存中获取用户信息;

现在我们变换一下上面的demo

public class CacheTest {    private IUserMapper mapper;    private SqlSession sqlSession;    @Before    public void before() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession                          true:事务自动提交        sqlSession = sqlSessionFactory.openSession();        mapper = sqlSession.getMapper(IUserMapper.class);    }    @Test    public void test1() {        //第一次查询id为1的用户        User user1 = mapper.getUserById(1);        User user = new User();        user.setId(1);        user.setUsername("Lucy");        mapper.updateUser(user);        sqlSession.commit();        //第二次查询id为1的用户        User user2 = mapper.getUserById(1);        System.out.println(user1 == user2);    }}
返回结果为 false

结论:做增删改操作,并进行了事物的提交,就会刷新以及缓存;或者还可以通过 sqlSession.clearCache()清楚缓存;这样做的目的就是为了让缓存中存储的是最新的信息,避免脏读;

二级缓存

二级缓存的原理和一级缓存原理一样,第一次查询会将数据放入缓存中,然后第二次查询则会直接从缓存中获取,但是一级缓存是基于sqlSession的,而二级缓存是基于mapper文件的namespace,也就是说,多个sqlSession可以共享一个mapper中的二级缓存,并且如果两个mapper的namespace相同,即使是两个mapper,那么这两个mapper执行sql查询到的数据也将存在相同的二级缓存区域中.

Mybatis基础概念与高级应用方法

如何使用二级缓存

首先在全局配置文件sqlMapconfig.xml文件加入如下代码

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

注意,该配置需要放在properties标签下,具体顺序,可百度了解

其次,在xxxMapper.xml文件中开启缓存(如果当前操作时基于注解开发的话,使用注解@CacheNamespace)

<cache></cache>

demo2

public class CacheTest {    private IUserMapper mapper;    private SqlSession sqlSession;    private SqlSessionFactory sqlSessionFactory;    @Before    public void before() throws IOException {        //1.Resources工具类,配置文件的加载,把配置文件加载成字节输入流        InputStream inputStream = Resources.getResourceAsStream("sqlMApConfig.xml");        //2.解析了配置文件,并创建了sqlSessionFactory工厂        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        //3.生产sqlSession        sqlSession = sqlSessionFactory.openSession();        mapper = sqlSession.getMapper(IUserMapper.class);    }    @Test    public void test2() {        SqlSession sqlSession1 = sqlSessionFactory.openSession();        SqlSession sqlSession2 = sqlSessionFactory.openSession();        SqlSession sqlSession3 = sqlSessionFactory.openSession();        IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class);        IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class);        IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class);        User user1 = mapper1.getUserById(1);        //清空一级缓存        sqlSession1.close();        User user2 = mapper2.getUserById(1);        System.out.println(user1 == user2);    }}

运行结果为 false

结论:通过debug断点显示,实际上,第二次查询则会直接从缓存中获取用户信息了,不过二级缓存缓存的不是对象,而是缓存的对象中的数据,所以查询结果为false;

注意,二级缓存底层还是HashMap结构,所以 po类需要实现序列化接口 ;因为二级缓存数据存储介质多种多样,不一定只存在内存中,有可能存在硬盘中,如果我们要在取这个缓存的话,就需要反序列化了,所以mybatis中的pojo都去实现Serializable接口;

变换一下demo2

@Test    public void test2() {        SqlSession sqlSession1 = sqlSessionFactory.openSession();        SqlSession sqlSession2 = sqlSessionFactory.openSession();        SqlSession sqlSession3 = sqlSessionFactory.openSession();        IUserMapper mapper1 = sqlSession1.getMapper(IUserMapper.class);        IUserMapper mapper2 = sqlSession2.getMapper(IUserMapper.class);        IUserMapper mapper3 = sqlSession3.getMapper(IUserMapper.class);        User user1 = mapper1.getUserById(1);        //清空一级缓存        sqlSession1.close();        User user = new User();        user.setId(1);        user.setUsername("Tom");        mapper3.updateUser(user);        sqlSession3.commit();        User user2 = mapper2.getUserById(1);        System.out.println(user1 == user2);    }
返回结果为 false

结论:做增删改操作,并进行了事物的提交,就会刷新以及缓存;这样做的目的就是为了让缓存中存储的是最新的信息,避免脏读;

此外mybatis中还可以配置useCache和flushCache等配置项;

useCache

是用来设置是否禁用二级缓存的,在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会会发出sql去查询,默认情况是true,即该sql使用二级缓存,例如

<select id="findAll" useCache = "false" resultMap="userMap">        select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid</select>

使用sql注解方式可以使用@Options(useCache = false)的方式

flushCache

在mapper的同一个namespace中,如果有其他的insert,update,delete操作数据后需要刷新缓存,如果不执行刷新缓存会出现脏读,设置statememt配置中的

flushCache = "true"属性,默认情况下为true,即刷新缓存,如果改成false则不会刷新,使用缓存时如果手动修改数据库表中的查询数据会出现脏读 例如

<select id="findAll" flushCache = "true" useCache = "false" resultMap="userMap">        select u.*,o.id oid,o.order_time,o.total,o.uid from user u left join orders o on u.id = o.uid</select>

一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读,所以我们不用设置,默认即可

以上就是“Mybatis基础概念与高级应用方法”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注编程网精选频道。

--结束END--

本文标题: Mybatis基础概念与高级应用方法

本文链接: https://www.lsjlt.com/news/340855.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作