mysql 剑法_MyBatis辟邪剑谱

一 MyBatis简介

MyBatis是一个优秀的持久层框架 它对JDBC操作数据库的过程进行封装 开发者只需要关注SQL本身 而不需要花费精力去处理JDBC繁杂的过程代码

MyBatis将要执行的各种Statement配置起来 并通过Java对象和Statement中的SQL进行映射生成最终执行的SQL语句 最后由MyBatis执行SQL并将结果映射成Java对象返回

二 MyBatis优缺点

优点

1. 通过直接编写SQL语句 可以直接对SQL进行性能优化

2. 学习门槛低 学习成本低 只要有SQL基础 就可以学习MyBatis 而且很容易上手

3. 由于直接编写SQL语句 所以灵活多变 代码维护性更好

缺点

1. 不支持数据库无关性 即数据库发生变更 要写多套代码进行支持 移植性不好 比如分页关键字

2. 需要编写结果映射

三 MyBatis框架核心

1. MyBatis配置文件 包括MyBatis全局配置文件和MyBatis映射文件 其中全局配置文件配置了数据源 事务等信息 映射文件配置了SQL执行相关的信息

2. MyBatis通过读取配置文件 构造出SqlSessionFactory 即会话工厂

3. 通过SqlSessionFactory 可以创建SqlSession 即会话 MyBatis是通过SqlSession来操作数据库

4. SqlSession本身不能直接操作数据库 它是通过底层的Executor执行器接口来操作数据库 Executor接口有两个实现类 一个是普通执行器 一个是缓存执行器(默认)

5. Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中 该对象包括SQL语句 输入参数映射信息 输出结果映射信息 其中输入参数和输出结果的映射类型包括HashMap集合对象 POJO对象类型

四 MyBatis初体验

pom.xml

4.0.0

com.hy.mybatis

mybatis-demo

1.0-SNAPSHOT

4.12

1.7.25

8.0.11

3.4.6

junit

junit

${junit.version}

org.slf4j

slf4j-log4j12

${slf4j-log4j12.version}

mysql

mysql-connector-java

${mysql-connector-java.version}

org.mybatis

mybatis

${mybatis.version}

junit

junit

org.slf4j

slf4j-log4j12

mysql

mysql-connector-java

org.mybatis

mybatis

org.apache.maven.plugins

maven-compiler-plugin

3.7.0

1.8

1.8

UTF-8

sql

--用户表

CREATE TABLE user(

idINT PRIMARY KEY AUTO_INCREMENT COMMENT '用户id',

usernameVARCHAR(32) COMMENT '用户名',money DOUBLE COMMENT '用户余额');INSERT INTO user VALUES (1, '曹操', 8000);INSERT INTO user VALUES (2, '孙权', 8000);INSERT INTO user VALUES (3, '刘备', 8000);INSERT INTO user VALUES (4, '诸葛亮', 5000);INSERT INTO user VALUES (5, '司马懿', 5000);INSERT INTO user VALUES (6, '张飞', 0);INSERT INTO user VALUES (7, '关羽', 0);INSERT INTO user VALUES (8, '马超', 1000);INSERT INTO user VALUES (9, '黄忠', 1000);INSERT INTO user VALUES (10, '赵云', 3000);--订单表

CREATE TABLEorder_ (

idINT PRIMARY KEY AUTO_INCREMENT COMMENT '订单id',

create_dateDATETIME COMMENT '订单创建时间',

noteVARCHAR(100) COMMENT '订单备注',

uidINT COMMENT '用户id');ALTER TABLE order_ ADD CONSTRAINT order_fk FOREIGN KEY (uid) REFERENCES user(id);INSERT INTO order_ VALUES (3, '2015-02-04 13:22:35', '配送快一点!', 1);INSERT INTO order_ VALUES (4, '2015-02-03 13:22:41', NULL, 1);INSERT INTO order_ VALUES (5, '2015-02-12 16:13:23', NULL, 10);--商品表

CREATE TABLEitem (

idINT PRIMARY KEY AUTO_INCREMENT COMMENT '商品id',

nameVARCHAR(32) COMMENT '商品名',

priceDOUBLE COMMENT '商品价格',

detailVARCHAR(100) COMMENT '订单描述');INSERT INTO item VALUES (1, '台式机', 3000.0, '该电脑质量非常好');INSERT INTO item VALUES (2, '笔记本', 6000.0, '垃圾货色');INSERT INTO item VALUES (3, '背包', 200.0, '名牌背包');--订单商品关系表

CREATE TABLEorder_detail (

idINT PRIMARY KEY AUTO_INCREMENT COMMENT 'id',count INT COMMENT '购买数量',

oidINT COMMENT '订单id',

iidINT COMMENT '商品id');ALTER TABLE order_detail ADD CONSTRAINT order_detail_order_fk FOREIGN KEY (oid) REFERENCESorder_ (id);ALTER TABLE order_detail ADD CONSTRAINT order_detail_item_fk FOREIGN KEY (iid) REFERENCESitem (id);INSERT INTO order_detail VALUES (1, 1, 3, 1);INSERT INTO order_detail VALUES (2, 2, 3, 2);INSERT INTO order_detail VALUES (3, 3, 4, 3);INSERT INTO order_detail VALUES (4, 4, 4, 2);--一个用户可以创建多个订单 用户表和订单表是一对多的关系--一个订单可以包含多个商品 一个商品可以拥有多个订单 订单表和商品表是多对多的关系

2. 配置日志输出 resources/log4j.properties

### 输出到控制台 ###

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.Target=System.err

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### 输出到文件 ###

log4j.appender.file=org.apache.log4j.FileAppender

log4j.appender.file.File=//Users/HUANGYI/Downloads/x-log.txt

log4j.appender.file.layout=org.apache.log4j.PatternLayout

log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### 日志级别: fatal > error > warn > info > debug > trace ###

### 输出到哪里: stdout|file ###

#log4j.rootLogger=info, stdout

### 输出所有日志 ###

log4j.rootLogger=all, stdout

### 不输出日志 ###

#log4j.rootLogger=off, stdout

3. 配置数据源 resources/database.properties

url=jdbc:mysql://localhost:3306/demo_hy?characterEncoding=utf8&useSSL=false

driverClassName=com.mysql.cj.jdbc.Driver

username=root

password=root

4. 创建实体类 com.hy.mybatis.model.User

public class User implementsSerializable {privateInteger id;privateString username;privateDouble money;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicString getUsername() {returnusername;

}public voidsetUsername(String username) {this.username =username;

}publicDouble getMoney() {returnmoney;

}public voidsetMoney(Double money) {this.money =money;

}

@OverridepublicString toString() {return "User{" +

"id=" + id +

", username='" + username + '\'' +

", money=" + money +

'}';

}

}

5. 创建mapper接口 com.hy.mybatis.mapper.UserMapper

/*** mapper动态代理开发 MyBatis会自动为mapper接口生成动态代理实现类

* 必须遵循四个原则

* 1. mapper接口的全限定名要和mapper映射文件的namespace相同

* 2. mapper接口的方法名要和mapper映射文件的statement#id相同

* 3. mapper接口的方法参数只能有一个 且类型要和mapper映射文件的statement#parameterType相同

* 4. mapper接口的返回值类型要和mapper映射文件的statement#resultType或statement#resultMap#type相同

* Created by Hy on 2020/7/29.*/

public interfaceUserMapper {

User selectUserById(Integer id);

ListselectUserListByUsername(String username);

ListselectUserListByMoney(Map map);

Integer selectUserCount();

Integer insertUser(User user);

Integer deleteUserById(Integer id);

Integer updateUserById(User user);

}

6. 创建mapper映射文件 com.hy.mybatis.mapper.UserMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT *

FROM user

WHERE id = #{value}

SELECT *

FROM user

WHERE username LIKE '%${value}%'

SELECT *

FROM user

LIMIT #{index}, #{count}

SELECT COUNT(id)

FROM user

SELECT LAST_INSERT_ID()INSERT INTO user (username, money)

VALUES (#{username}, #{money})

DELETE FROM user

WHERE id = #{value}

UPDATE user

SET username = #{username}, money = #{money}

WHERE id = #{id}

7. 创建全局配置文件 resources/mybatis.xml

/p>

PUBLIC "-//mybatis.org//DTD Config 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-config.dtd">

8. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test01() throwsIOException {

UserMapper mapper= mSession.getMapper(UserMapper.class);

User user= mapper.selectUserById(1);

System.out.println(user.toString());

}

@Testpublic void test02() throwsIOException {

UserMapper mapper= mSession.getMapper(UserMapper.class);

List userList = mapper.selectUserListByUsername("马");for(User user : userList) {

System.out.println(user.toString());

}

}

@Testpublic void test03() throwsIOException {int page = 1;int count = 5;int index = (page - 1) *count;

Map map = new HashMap<>();

map.put("index", index);

map.put("count", count);

UserMapper mapper= mSession.getMapper(UserMapper.class);

List userList =mapper.selectUserListByMoney(map);for(User user : userList) {

System.out.println(user.toString());

}

}

@Testpublic void test04() throwsIOException {

UserMapper mapper= mSession.getMapper(UserMapper.class);

Integer count=mapper.selectUserCount();

System.out.println("count = " +count);

}

@Testpublic void test05() throwsIOException {

User user= newUser();

user.setUsername("貂蝉");

user.setMoney(10.0);

UserMapper mapper= mSession.getMapper(UserMapper.class);//返回受影响的行数

Integer count =mapper.insertUser(user);

System.out.println("受影响的行数 = " +count);//增删改需要提交事务

mSession.commit();

System.out.println("id = " +user.getId());

}

@Testpublic void test06() throwsIOException {

UserMapper mapper= mSession.getMapper(UserMapper.class);//返回受影响的行数

Integer count = mapper.deleteUserById(12);

System.out.println("受影响的行数 = " +count);//增删改需要提交事务

mSession.commit();

}

@Testpublic void test07() throwsIOException {

User user= newUser();

user.setId(13);

user.setUsername("黄盖");

user.setMoney(99.9);

UserMapper mapper= mSession.getMapper(UserMapper.class);//返回受影响的行数

Integer count =mapper.updateUserById(user);

System.out.println("受影响的行数 = " +count);//增删改需要提交事务

mSession.commit();

}

}

五 动态SQL

使用示例

1. 创建实体类 com.hy.mybatis.model.Item

public class Item implementsSerializable {privateInteger id;privateString name;privateDouble price;privateString detail;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicString getName() {returnname;

}public voidsetName(String name) {this.name =name;

}publicDouble getPrice() {returnprice;

}public voidsetPrice(Double price) {this.price =price;

}publicString getDetail() {returndetail;

}public voidsetDetail(String detail) {this.detail =detail;

}

@OverridepublicString toString() {return "Item{" +

"id=" + id +

", name='" + name + '\'' +

", price=" + price +

", detail='" + detail + '\'' +

'}';

}

}

2. 创建mapper接口 com.hy.mybatis.mapper.ItemMapper

public interfaceItemMapper {

Integer insertItem(Item item);

Integer updateItem(Item item);

ListselectItemListByNameAndPrice(Item item);

List selectItemListByIdArray(int[] array);

ListselectItemListByIdList(List list);

}

3. 创建mapper映射文件 com.hy.mybatis.mapper.ItemMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

INSERT INTO item

id,

name,

price,

detail,

#{id},

#{name},

#{price},

#{detail},

UPDATE item

name = #{name},

price = #{price},

detail = #{detail},

WHERE id = #{id}

SELECT *

FROM item

AND name LIKE '%${name}%'

AND price<#{price}

SELECT *

FROM item

0">

#{value}

SELECT *

FROM item

0">

#{value}

4. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test09() throwsIOException {

Item item= newItem();

item.setName("自行车");

item.setPrice(800.0);

ItemMapper mapper= mSession.getMapper(ItemMapper.class);//返回受影响的行数

Integer count =mapper.insertItem(item);

System.out.println("受影响的行数 = " +count);//增删改需要提交事务

mSession.commit();

}

@Testpublic void test10() throwsIOException {

Item item= newItem();

item.setId(4);

item.setName("H2");

item.setPrice(400000.0);

item.setDetail("川崎");

ItemMapper mapper= mSession.getMapper(ItemMapper.class);//返回受影响的行数

Integer count =mapper.updateItem(item);

System.out.println("受影响的行数 = " +count);//增删改需要提交事务

mSession.commit();

}

@Testpublic void test11() throwsIOException {

Item item= newItem();

item.setName("包");

item.setPrice(300.0);

ItemMapper mapper= mSession.getMapper(ItemMapper.class);

List itemList =mapper.selectItemListByNameAndPrice(item);for(Item i : itemList) {

System.out.println(i.toString());

}

}

@Testpublic void test12() throwsIOException {int[] array = new int[]{1, 2};

ItemMapper mapper= mSession.getMapper(ItemMapper.class);

List itemList =mapper.selectItemListByIdArray(array);for(Item i : itemList) {

System.out.println(i.toString());

}

}

@Testpublic void test13() throwsIOException {

List list = new ArrayList<>();

list.add(1);

list.add(3);

ItemMapper mapper= mSession.getMapper(ItemMapper.class);

List itemList =mapper.selectItemListByIdList(list);for(Item i : itemList) {

System.out.println(i.toString());

}

}

}

六 resultMap功能

1. 如果查询出来的列名和实体类属性名不一致 通过定义一个resultMap将列名和实体类属性名绑定

a. 创建实体类 com.hy.mybatis.model.Order

public class Order implementsSerializable {privateInteger id;privateDate createDate;privateString note;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicDate getCreateDate() {returncreateDate;

}public voidsetCreateDate(Date createDate) {this.createDate =createDate;

}publicString getNote() {returnnote;

}public voidsetNote(String note) {this.note =note;

}

@OverridepublicString toString() {return "Order{" +

"id=" + id +

", createDate=" + createDate +

", note='" + note + '\'' +

'}';

}

}

b. 创建mapper接口 com.hy.mybatis.mapper.OrderMapper

public interfaceOrderMapper {

ListselectOrderList();

}

c. 创建mapper映射文件 com.hy.mybatis.mapper.OrderMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT *

FROM order_

d. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test08() throwsIOException {

OrderMapper mapper= mSession.getMapper(OrderMapper.class);

List orderList =mapper.selectOrderList();for(Order order : orderList) {

System.out.println(order.toString());

}

}

}

2. 一对一查询 根据订单id查找订单包括用户信息

a. 创建实体类 com.hy.mybatis.model.OrderAndUser

public class OrderAndUser implementsSerializable {privateInteger id;privateDate createDate;privateString note;privateUser user;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicDate getCreateDate() {returncreateDate;

}public voidsetCreateDate(Date createDate) {this.createDate =createDate;

}publicString getNote() {returnnote;

}public voidsetNote(String note) {this.note =note;

}publicUser getUser() {returnuser;

}public voidsetUser(User user) {this.user =user;

}

@OverridepublicString toString() {return "OrderAndUser{" +

"id=" + id +

", createDate=" + createDate +

", note='" + note + '\'' +

", user=" + user +

'}';

}

}

b. 创建mapper接口 com.hy.mybatis.mapper.OrderMapper

public interfaceOrderMapper {

OrderAndUser selectOrderAndUserById(Integer id);

}

c. 创建mapper映射文件 com.hy.mybatis.mapper.OrderMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT o.*, u.id AS uid, u.username AS uusername, u.money AS umoney

FROM order_ o, user u

WHERE o.uid = u.id

AND o.id = #{value}

d. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test14() throwsIOException {

OrderMapper mapper= mSession.getMapper(OrderMapper.class);

OrderAndUser orderAndUser= mapper.selectOrderAndUserById(3);

System.out.println(orderAndUser.toString());

}

}

3. 一对多查询 根据订单id查找订单包括订单明细信息

a. 创建实体类 com.hy.mybatis.model.OrderDetail com.hy.mybatis.model.OrderAndOrderDetail

public class OrderDetail implementsSerializable {privateInteger id;privateInteger count;privateItem item;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicInteger getCount() {returncount;

}public voidsetCount(Integer count) {this.count =count;

}publicItem getItem() {returnitem;

}public voidsetItem(Item item) {this.item =item;

}

@OverridepublicString toString() {return "OrderDetail{" +

"id=" + id +

", count=" + count +

", item=" + item +

'}';

}

}

public class OrderAndOrderDetail implementsSerializable {privateInteger id;privateDate createDate;privateString note;private ListorderDetailList;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicDate getCreateDate() {returncreateDate;

}public voidsetCreateDate(Date createDate) {this.createDate =createDate;

}publicString getNote() {returnnote;

}public voidsetNote(String note) {this.note =note;

}public ListgetOrderDetailList() {returnorderDetailList;

}public void setOrderDetailList(ListorderDetailList) {this.orderDetailList =orderDetailList;

}

@OverridepublicString toString() {return "OrderAndOrderDetail{" +

"id=" + id +

", createDate=" + createDate +

", note='" + note + '\'' +

", orderDetailList=" + orderDetailList +

'}';

}

}

b. 创建mapper接口 com.hy.mybatis.mapper.OrderMapper

public interfaceOrderMapper {

OrderAndOrderDetail selectOrderAndOrderDetailById(Integer id);

}

c. 创建mapper映射文件 com.hy.mybatis.mapper.OrderMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT o.*, od.id AS odid, od.count AS odcount

FROM order_ o, order_detail od

WHERE o.id = od.oid

AND o.id = #{value}

d. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test15() throwsIOException {

OrderMapper mapper= mSession.getMapper(OrderMapper.class);

OrderAndOrderDetail orderAndOrderDetail= mapper.selectOrderAndOrderDetailById(3);

System.out.println(orderAndOrderDetail.toString());

}

}

4. 多对多查询 查询所有用户信息及用户购买的商品信息

a. 创建实体类 com.hy.mybatis.model.UserAndOrderDetail

public class UserAndOrderDetail implementsSerializable {privateInteger id;privateString username;privateDouble money;private ListorderAndOrderDetailList;publicInteger getId() {returnid;

}public voidsetId(Integer id) {this.id =id;

}publicString getUsername() {returnusername;

}public voidsetUsername(String username) {this.username =username;

}publicDouble getMoney() {returnmoney;

}public voidsetMoney(Double money) {this.money =money;

}public ListgetOrderAndOrderDetailList() {returnorderAndOrderDetailList;

}public void setOrderAndOrderDetailList(ListorderAndOrderDetailList) {this.orderAndOrderDetailList =orderAndOrderDetailList;

}

@OverridepublicString toString() {return "UserAndOrderDetail{" +

"id=" + id +

", username='" + username + '\'' +

", money=" + money +

", orderAndOrderDetailList=" + orderAndOrderDetailList +

'}';

}

}

b. 创建mapper接口 com.hy.mybatis.mapper.UserMapper

public interfaceUserMapper {

ListselectUserAndOrderDetail();

}

c. 创建mapper映射文件 com.hy.mybatis.mapper.UserMapper.xml

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT u.*, o.id o0, o.create_date o1, o.note o2, od.id od0, od.count od1, i.id i0, i.name i1, i.price i2, i.detail i3

FROM user u, order_ o, order_detail od, item i

WHERE u.id = o.uid

AND o.id = od.oid

AND od.iid = i.id;

d. 测试

public classXTest {

SqlSession mSession;

@Beforepublic void before() throwsIOException {//读取配置文件

InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");//创建会话工厂

SqlSessionFactory factory = newSqlSessionFactoryBuilder().build(inputStream);//创建SqlSession

mSession =factory.openSession();

}

@Afterpublic voidafter() {if (null != mSession) mSession.close(); //关闭SqlSession

}

@Testpublic void test16() throwsIOException {

UserMapper mapper= mSession.getMapper(UserMapper.class);

List userAndOrderDetailList =mapper.selectUserAndOrderDetail();for(UserAndOrderDetail detail : userAndOrderDetailList) {

System.out.println(detail.toString());

}

}

}

七 MyBatis缓存

和大多数的持久化框架一样 MyBatis也提供了缓存策略 通过缓存策略来减少数据库的查询次数 从而提高性能 MyBatis中缓存分为一级缓存 二级缓存

cbf1f34282f6b55e281f2d0b7d5dfcd5.png

1. 一级缓存

默认开启

一级缓存是SqlSession级别的缓存 当调用SqlSession的增删改等方法时 就会清空一级缓存

836e461f79e99a4f7b154eba86032af5.png

第一次发起查询用户id为1的用户信息 先去找缓存中是否有id为1的用户信息 如果没有 从数据库查询用户信息 得到用户信息 将用户信息存储到一级缓存中

如果SqlSession去执行增删改 清空SqlSession中的一级缓存 这样做可以让缓存中存储的是最新信息 避免脏读

第二次发起查询用户id为1的用户信息 先去找缓存中是否有id为1的用户信息 缓存中有 直接从缓存中获取用户信息

2. 二级缓存

需要手动开启

二级缓存是Mapper级别的缓存 同一个Mapper下 多个SqlSession可以共用二级缓存 当调用其中某个SqlSession的增删改等方法时 就会清空二级缓存

62aa3912496adbc47f58008cfe325d22.png

SqlSession1去查询用户信息 查询到用户信息会将查询数据存储到二级缓存中

如果SqlSession3去执行增删改 将会清空该Mapper映射下的二级缓存区域的数据 这样做可以让缓存中存储的是最新信息 避免脏读

SqlSession2去查询与SqlSession1相同的用户信息 首先会去缓存中找是否存在数据 如果存在直接从缓存中取出数据

二级缓存的开启与关闭

a. resources/mybatis.xml 节点和节点之间配置

b. 配置相关的mapper映射文件

/p>

PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"

"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

SELECT *

FROM user

WHERE id = #{value}

SELECT *

FROM user

WHERE username LIKE '%${value}%'

二级缓存的注意事项

a. 使用二级缓存时 所缓存的类一定要实现java.io.Serializable接口 这种就可以使用序列化方式来保存对象

b. 默认的二级缓存不支持分布式

c. 二级缓存对细粒度的数据 缓存实现不好 比如对商品信息进行缓存 由于商品信息访问量大 但是要求用户每次查询都是最新的商品信息 此时如果使用二级缓存 就无法实现当一个商品发生变化只刷新该商品缓存信息而不刷新其他商品缓存信息 因为二级缓存是Mapper级别 当一个商品信息更新 所有的商品信息缓存数据都会清空 解决此类问题 需要在业务层根据需要对数据有针对性的缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值