一惩妇、MyBatis的開始
從官方文檔開始
MyBatis是什么
- 持久層框架
- 支持定制化 SQL搪哪、存儲(chǔ)過程以及高級(jí)映射
- 避免幾乎所有的JDBC代碼和手動(dòng)設(shè)置參數(shù)以及獲得結(jié)果集
- 可以使用簡(jiǎn)單的xml或者注釋來配置和映射原生類型猾愿、接口和Java的pojo(Plain Old Java Object嗅榕,普通老式Java對(duì)象)為數(shù)據(jù)庫中的記錄窥突。
MyBatis的Maven配置
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
持久化
- 程序數(shù)據(jù)在持久狀態(tài)和瞬時(shí)狀態(tài)轉(zhuǎn)化的過程
- 內(nèi)存特點(diǎn):斷電即失
- 數(shù)據(jù)庫、io文件實(shí)現(xiàn)數(shù)據(jù)持久化
持久層
- 完成持久化工作的代碼塊
MyBatis的優(yōu)點(diǎn)
- 對(duì)數(shù)據(jù)庫進(jìn)行增刪改查
- 簡(jiǎn)單、靈活
- sql和代碼的分離经备,提高可維護(hù)性
- 提供映射標(biāo)簽拭抬,支持對(duì)象與數(shù)據(jù)庫的orm字段關(guān)系映射
- 提供對(duì)象關(guān)系映射標(biāo)簽,支持對(duì)象關(guān)系組建維護(hù)
- 提供xml標(biāo)簽侵蒙,支持編寫動(dòng)態(tài)sql
第一個(gè)MyBatis程序
1. 配置pom.xml
- 父工程
- 在一個(gè)maven項(xiàng)目中創(chuàng)建一個(gè)model
- 導(dǎo)入依賴造虎,子工程也可以使用這些依賴,而不用在子工程的xml中再次導(dǎo)入依賴
<!--父工程-->
<groupId>com.vigil</groupId>
<artifactId>Mybatis_Study</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<!--子工程-->
<modules>
<module>mybatis-01</module>
</modules>
<!--導(dǎo)入依賴-->
<dependencies>
<!--mysql驅(qū)動(dòng)-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
error:資源導(dǎo)出問題
- 處理方式:在項(xiàng)目配置文件中加入下面的代碼
<!-- 在build中配置resources纷闺,來防止我們資源導(dǎo)出失敗的問題-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
2. 子工程項(xiàng)目配置
- 這里使用默認(rèn)生成的就行
<parent>
<artifactId>Mybatis_Study</artifactId>
<groupId>com.vigil</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mybatis-01</artifactId>
3. 數(shù)據(jù)庫
- 用于查詢的簡(jiǎn)單數(shù)據(jù)庫
create table user
(
id int(20) not null comment 'id'
primary key,
name varchar(20) not null comment 'name',
pwd varchar(20) not null comment 'password'
)
charset = utf8;
- idea連接數(shù)據(jù)庫
4. 編寫對(duì)應(yīng)數(shù)據(jù)庫的JavaBean:User類
5. 編寫MyBatis的配置文件
XML 配置文件中包含了對(duì) MyBatis 系統(tǒng)的核心設(shè)置算凿,包括獲取數(shù)據(jù)庫連接實(shí)例的數(shù)據(jù)源(DataSource):需要對(duì)應(yīng)自己的數(shù)據(jù)庫進(jìn)行配置
以及決定事務(wù)作用域和控制方式的事務(wù)管理器(TransactionManager)。
<?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?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="20201123"/>
</dataSource>
</environment>
</environments>
<!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
<mappers>
<mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
</mappers>
</configuration>
6. 編寫獲得數(shù)據(jù)庫連接的工具類
每個(gè)基于 MyBatis 的應(yīng)用都是以一個(gè) SqlSessionFactory 的實(shí)例為核心的犁功。SqlSessionFactory 的實(shí)例可以通過 SqlSessionFactoryBuilder 獲得氓轰。而 SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個(gè)預(yù)先配置的 Configuration 實(shí)例來構(gòu)建出 SqlSessionFactory 實(shí)例。
package com.vigil.util;
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;
//SqlSessionFactory ---> SqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//獲取SqlSessionFactory對(duì)象
// 要先獲得SqlSessionFactoryBuilder對(duì)象浸卦,在數(shù)據(jù)庫資源文件中獲得
//從 XML 文件中構(gòu)建 SqlSessionFactory 的實(shí)例非常簡(jiǎn)單署鸡,建議使用類路徑下的資源文件進(jìn)行配置。 但也可以使用任意的輸入流(InputStream)實(shí)例限嫌,比如用文件路徑字符串或 file:// URL 構(gòu)造的輸入流靴庆。MyBatis 包含一個(gè)名叫 Resources 的工具類,它包含一些實(shí)用方法怒医,使得從類路徑或其它位置加載資源文件更加容易炉抒。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了 SqlSessionFactory,顧名思義裆熙,我們可以從中獲得 SqlSession 的實(shí)例端礼。
// SqlSession 提供了在數(shù)據(jù)庫執(zhí)行 SQL 命令所需的所有方法。你可以通過 SqlSession 實(shí)例來直接執(zhí)行已映射的 SQL 語句入录。
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
7. 編寫Mapper接口(對(duì)應(yīng)javaweb的dao接口蛤奥,操作數(shù)據(jù)庫)
public interface UserDao {
List<User> getUserList();
}
8. 編寫Mapper的對(duì)應(yīng)xml文件
類似javaweb里面的DaoImpl類
需要注意的是:
1、namespace(命名空間)=綁定一個(gè)對(duì)應(yīng)的Dao\Mapper接口名:com.vigil.dao.UserDao
2僚稿、重寫方法 --> select查詢語句凡桥,id對(duì)應(yīng)mapper中方法名字,resultType對(duì)應(yīng)返回類型
全限定名:映射-->com.vigil.dao.UserDao.getUserList
<?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">
<!--1蚀同、namespace(命名空間)=綁定一個(gè)對(duì)應(yīng)的Dao\Mapper接口-->
<mapper namespace="com.vigil.dao.UserDao">
<!--2缅刽、重寫方法 -->
<!--select查詢語句,id對(duì)應(yīng)方法名字蠢络,resultType對(duì)應(yīng)返回類型(全限定名) -->
<select id="getUserList" resultType="com.vigil.pojo.User">
select * from mybatis.user
</select>
</mapper>
9. 注冊(cè)mapper.xml(尤其重要)
每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)
<!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
<mappers>
<mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
</mappers>
10. 測(cè)試Mapper
package com.vigil.dao;
import com.vigil.pojo.User;
import com.vigil.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoText {
@Test
public void text() {
// 獲得SqlSession對(duì)象衰猛,從而執(zhí)行sql語句
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 執(zhí)行sql
//方式一:getMapper
// userDao是在web時(shí)對(duì)數(shù)據(jù)層操作的一個(gè)叫法,Data Access Object數(shù)據(jù)庫訪問對(duì)象
// 而在Mybatis中則叫mapper刹孔,通過類名得到這個(gè)類的一個(gè)實(shí)例啡省,反射和多態(tài)性
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
//方式二,方法后不用加括號(hào),
// 對(duì)于結(jié)果的返回是要確切知道方法的返回類型卦睹,然后需要選擇對(duì)應(yīng)的sqlsession方法并且進(jìn)行強(qiáng)制轉(zhuǎn)換
// List<User> userList = sqlSession.selectList("com.vigil.dao.UserDao.getUserList");
for (User user : userList) {
System.out.println(user.toString());
}
//關(guān)閉SqlSession
sqlSession.close();
}
}
方式一(優(yōu)先選擇):在對(duì)應(yīng)的映射器接口調(diào)用方法畦戒。
命名就可以直接映射到在命名空間中同名的映射器類,并將已映射的 select 語句匹配到對(duì)應(yīng)名稱结序、參數(shù)和返回類型的方法障斋。
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> userList = userDao.getUserList();
方式二:用全限定名 “com.vigil.dao.UserDao.getUserList” 來調(diào)用映射語句,風(fēng)險(xiǎn)在于:對(duì)于結(jié)果的返回是要確切知道方法的返回類型徐鹤,然后需要選擇對(duì)應(yīng)的sqlsession方法并且進(jìn)行強(qiáng)制轉(zhuǎn)換
List<User> userList = sqlSession.selectList("com.vigil.dao.UserDao.getUserList");
mapper.xml的注意項(xiàng):
- id:對(duì)應(yīng)命名空間的接口的方法名
- resultType:sql語句執(zhí)行的返回值類型
- parameterType:傳入方法中參數(shù)的類型
- 對(duì)象中的屬性垃环,可以直接根據(jù)變量名取出來
- 標(biāo)簽名和sql語句要一一匹配,是select的sql語句就對(duì)應(yīng)select標(biāo)簽凳干,是update的sql語句就對(duì)應(yīng)update標(biāo)簽
- 在mybatis配置文件中注冊(cè)時(shí)晴裹,mapper標(biāo)簽對(duì)應(yīng)的 resource 標(biāo)簽要使用mapper的相對(duì)類路徑(com/vigil/dao/UserMapper.xml)注意是用的" / "
- 取值符號(hào):#{}被济,括號(hào)內(nèi)填寫變量名
- 參數(shù)取出關(guān)聯(lián)著設(shè)置:
(1)Map傳遞參數(shù)救赐,直接在sql中取出key即可!【parameterType="Map"】
(2)對(duì)象傳遞參數(shù)只磷,直接在sql中取對(duì)象的屬性即可经磅!【parameterType="Object"】
(3)只有一個(gè)基本參數(shù)的情況下,可以直接在sql中取到【可以不寫】
(4)多個(gè)參數(shù)建議用Map钮追,或者是注解
CRUD
1. namespace(命名空間)
命名空間的作用有兩個(gè)预厌,一個(gè)是利用更長(zhǎng)的全限定名來將不同的語句隔離開來,同時(shí)也實(shí)現(xiàn)了你上面見到的接口綁定元媚。
- 全限定名(比如 "com.vigil.dao.UserDao.getUserList")將被直接用于查找及使用轧叽。
編寫步驟
- 編寫接口
- 編寫對(duì)應(yīng)的mapper中的sql語句
- 測(cè)試:增刪改需要提交事務(wù)
2. select
- interface
//根據(jù)id查詢用戶
User getUserById(int id);
- mapper.xml
<select id="getUserById" parameterType="int" resultType="com.vigil.pojo.User">
select * from mybatis.user where id = #{id}
</select>
- test
@Test
public void getUserById() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.getUserById(1);
System.out.println(user.toString());
sqlSession.close();
}
3. Insert
- interface
//插入一個(gè)新用戶
int addUser(User user);
- mapper.xml
<!--對(duì)象中的屬性,可以直接根據(jù)變量名取出來-->
<insert id="addUser" parameterType="com.vigil.pojo.User">
insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd})
</insert>
- test
@Test
public void addUser() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.addUser(new User(4,"23","144352543"));
System.out.println(i);
//事務(wù)提交
sqlSession.commit();
sqlSession.close();
}
4. update
- interface
//修改用戶
int updateUser(User user);
- mapper.xml
<update id="updateUser" parameterType="com.vigil.pojo.User">
update mybatis.user set name = #{name}, pwd = #{pwd} where id = #{id}
</update>
- test
@Test
public void updateUser() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.updateUser(new User(4, "扯一扯", "12323"));
System.out.println(i);
//事務(wù)提交
sqlSession.commit();
sqlSession.close();
}
5. delete
- interface
//刪除一個(gè)用戶
int deleteUser(int id);
- mapper.xml
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id = #{id}
</delete>
- test
@Test
public void deleteUser() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int i = mapper.deleteUser(4);
System.out.println(i);
//事務(wù)提交
sqlSession.commit();
sqlSession.close();
}
Map
前提:實(shí)體類刊棕、或者數(shù)據(jù)庫中的表炭晒,字段或者參數(shù)過多,考慮使用Map傳參
- interface
//根據(jù)id查詢用戶
User getUserByIdMap(Map<String,Object> map);
- mapper.xml
<select id="getUserByIdMap" parameterType="map" resultType="com.vigil.pojo.User">
select * from mybatis.user where id = #{userid}
</select>
- test
public void getUserByIdMap() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("userid",1);
User user = mapper.getUserByIdMap(map);
System.out.println(user);
sqlSession.close();
}
模糊查詢
- Java代碼執(zhí)行時(shí)甥角,傳遞通配符% %
- 在sql拼接中使用通配符
模糊查詢的4種實(shí)現(xiàn)方式
二网严、MyBatis配置簡(jiǎn)單解析
(一)、核心配置文件
- mybatis-config.xml
- MyBatis 的配置文件包含了會(huì)深深影響 MyBatis 行為的設(shè)置和屬性信息
configuration(配置)
properties(屬性)
settings(設(shè)置)
typeAliases(類型別名)
typeHandlers(類型處理器)
objectFactory(對(duì)象工廠)
plugins(插件)
environments(環(huán)境配置)
environment(環(huán)境變量)
transactionManager(事務(wù)管理器)
dataSource(數(shù)據(jù)源)
databaseIdProvider(數(shù)據(jù)庫廠商標(biāo)識(shí))
mappers(映射器)
(二)嗤无、環(huán)境變量(environment)
- MyBatis 可以配置適應(yīng)多種環(huán)境
- 盡管可以配置多個(gè)環(huán)境震束,但每個(gè) SqlSessionFactory 實(shí)例只能選擇一種環(huán)境。
- MyBatis 默認(rèn)的事務(wù)管理器是jdbc当犯,連接池:POOLED
(三)垢村、屬性(properties)
通過properties屬性來實(shí)現(xiàn)引入配置文件
這些屬性可以在外部進(jìn)行配置,并可以進(jìn)行動(dòng)態(tài)替換嚎卫。你既可以在典型的 Java 屬性文件中配置這些屬性嘉栓,也可以在 properties 元素的子元素中設(shè)置。
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
username=root
password=20201123
在配置文件中引入
-
xml中標(biāo)簽位置有限定image
<!--引入外部配置文件-->
<properties resource="db.properties">
<property name="password" value="20201123"/>
</properties>
<environments default="development">
<environment id="development">
<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>
- 可以直接引入外部文件
- 可以在其中增加一些屬性配置
- 如果兩個(gè)文件中同名的字段,最后讀取作為方法參數(shù)傳遞的屬性胸懈,并覆蓋之前讀取過的同名屬性担扑。
(四)、類型別名(typeAliases)
- 類型別名可為 Java 類型設(shè)置一個(gè)縮寫名字趣钱。
- 僅用于 XML 配置涌献,意在降低冗余的全限定類名書寫。
第一種方法
<typeAliases>
<typeAlias type="com.vigil.pojo.User" alias="User"></typeAlias>
</typeAliases>
第二種方法
指定一個(gè)包名首有,MyBatis 會(huì)在包名下面搜索需要的 Java Bean燕垃,比如掃描一個(gè)實(shí)體類的包,他的默認(rèn)別名就為這個(gè)類的 類名井联,首字母小寫
<typeAliases>
<package name="com.vigil.pojo"/>
</typeAliases>
- 在實(shí)體類比較少的時(shí)候卜壕,使用第一種方式
- 如果實(shí)體類比較多,使用第二種方式
- 還可以使用注解的方式結(jié)合第二種方式起別名:
@Alias("User) public class User{}
(五)烙常、設(shè)置(settings)
設(shè)置名 | 描述 | 有效值 | 默認(rèn)值 |
---|---|---|---|
cacheEnabled | 全局性地開啟或關(guān)閉所有映射器配置文件中已配置的任何緩存 | true \ false | true |
lazyLoadingEnabled | 延遲加載的全局開關(guān)轴捎。當(dāng)開啟時(shí),所有關(guān)聯(lián)對(duì)象都會(huì)延遲加載蚕脏。 特定關(guān)聯(lián)關(guān)系中可通過設(shè)置 fetchType 屬性來覆蓋該項(xiàng)的開關(guān)狀態(tài)侦副。 | true \ false | false |
logImpl | 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找 | SLF4J \ LOG4J \ LOG4J2 \ JDK_LOGGING \ COMMONS_LOGGING \ STDOUT_LOGGING \ NO_LOGGING | 未設(shè)置 |
(六)驼鞭、映射器(mappers)
MapperRegistry:注冊(cè)綁定我們的mapper文件
方式一: 使用相對(duì)于類路徑的資源引用 -
<!--每一個(gè)Mapper.xml文件都需要到mybatis的配置文件下注冊(cè)-->
<mappers>
<mapper resource="com/vigil/dao/UserMapper.xml"></mapper>
</mappers>
方式二: 使用class文件綁定注冊(cè)(使用映射器接口實(shí)現(xiàn)類的完全限定類名)
<mappers>
<mapper class="com.vigil.dao.UserMapper"></mapper>
</mappers>
方式三: 使用掃描包進(jìn)行注入綁定(將包內(nèi)的映射器接口實(shí)現(xiàn)全部注冊(cè)為映射器)
<mappers>
<!-- <mapper resource="com/vigil/dao/UserMapper.xml"></mapper>-->
<!-- <mapper class="com.vigil.dao.UserMapper"></mapper>-->
<package name="com.vigil.dao"/>
</mappers>
方式二和方式三必須的注意點(diǎn)
- 接口和他的Mapper配置文件必須同名
- 接口和他的Mapper配置文件必須在同一個(gè)包下
(七)秦驯、 生命周期和作用域
作用域、生命周期挣棕,是至關(guān)重要的译隘,因?yàn)殄e(cuò)誤的使用會(huì)導(dǎo)致非常嚴(yán)重的并發(fā)問題。
SqlSessionFactoryBuilder
- 一旦創(chuàng)建了 SqlSessionFactory洛心,就不再需要它了
- 局部方法變量
SqlSessionFactory
- 可以想象為:數(shù)據(jù)庫連接池
- SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在固耘,沒有任何理由丟棄它或重新創(chuàng)建另一個(gè)實(shí)例。
- 因此 SqlSessionFactory 的最佳作用域是應(yīng)用作用域
- 最簡(jiǎn)單的就是使用單例模式或者靜態(tài)單例模式
SqlSession
- 連接到連接池的一個(gè)請(qǐng)求
- SqlSession 的實(shí)例不是線程安全的皂甘,因此是不能被共享的玻驻,所以它的最佳的作用域是請(qǐng)求或方法作用域
-
用完之后需要趕緊關(guān)閉,否則資源被占用偿枕!
image
這里面的每一個(gè)mapper璧瞬,就代表一個(gè)具體的業(yè)務(wù)
三、解決MyBatis_屬性名和字段名不一致
屬性名和字段名不一致導(dǎo)致查詢結(jié)果為空的問題
表中的字段名:對(duì)應(yīng)的JavaBean實(shí)體類
public class User {
private int id;
private String name;
private String password;
}
密碼的字段是不一致的
最后測(cè)試渐夸,返回的User對(duì)象的password屬性是空的
原因:列名不匹配
select * from mybatis.user where id = #{id}
--類型處理器
select id,name,pwd from mybatis.user where id = #{id}
解決方法:
(一)嗤锉、起別名(更改的是:sql語句)
MyBatis 會(huì)在幕后自動(dòng)創(chuàng)建一個(gè) ResultMap,再根據(jù)屬性名來映射列到 JavaBean 的屬性上墓塌。如果列名和屬性名不能匹配上瘟忱,可以在 SELECT 語句中設(shè)置列別名(這是一個(gè)基本的 SQL 特性)來完成匹配奥额。
<select id="getUserById" parameterType="int" resultType="User">
select id,name,pwd as password from mybatis.user where id = #{id}
</select>
(二)、使用resultMap
上面沒有一個(gè)需要顯式配置 ResultMap访诱,完全可以不用顯式地配置它們垫挨。
顯式使用外部的 resultMap,是解決列名不匹配的另外一種方式触菜。
<!--結(jié)果集映射-->
<resultMap id="UserMap" type="User">
<!--column數(shù)據(jù)庫中的字段九榔,property實(shí)體類中的屬性-->
<result column="id" property="id"></result>
<result column="name" property="name"></result>
<result column="pwd" property="password"></result>
</resultMap>
在引用它的語句中設(shè)置 resultMap 屬性就行了(注意去掉了 resultType 屬性)。
<select id="getUserById" resultMap="UserMap">
select id,name,pwd from mybatis.user where id = #{id}
</select>
官方文檔_結(jié)果映射
四涡相、MyBatis日志簡(jiǎn)單使用
日志工廠
數(shù)據(jù)庫操作的錯(cuò)誤通過日志來查找是比較方便的
- 過去:sout哲泊、debug
- 現(xiàn)在:日志工廠
logImpl: 指定 MyBatis 所用日志的具體實(shí)現(xiàn),未指定時(shí)將自動(dòng)查找
- SLF4J
- LOG4J
- LOG4J2
- JDK_LOGGING
- COMMONS_LOGGING
- STDOUT_LOGGING
- NO_LOGGING
使用日志工廠
- 默認(rèn)情況下催蝗,日志工廠是 沒設(shè)置 的
- 在MyBatis中具體使用哪一個(gè)日志切威,在核心配置文件中,配置
- STDOUT_LOGGING標(biāo)準(zhǔn)日志輸出
<!--STDOUT_LOGGING標(biāo)準(zhǔn)日志輸出-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
- 日志輸出的重要信息
Opening JDBC Connection
Created connection 1263793464.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
==> Preparing: select * from mybatis.user where id = ?
==> Parameters: 2(Integer)
<== Columns: id, name, pwd
<== Row: 2, 李四, 324332
<== Total: 1
User{id=2, name='李四', pwd='324332'}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4b53f538]
Returned connection 1263793464 to pool.
LOG4J
什么是LOG4J丙号?
- log for Java:Java的日志
- 使用Log4j可以控制日志信息輸送的目的地是控制臺(tái)先朦、文件、GUI組件
- 可以控制每一條日志的輸出格式
- 通過定義每一條日志信息的級(jí)別
- 通過一個(gè)配置文件來靈活地進(jìn)行配置槽袄,而不需要修改應(yīng)用的代碼烙无。
使用LOG4J
1. 導(dǎo)入jar包
<dependencies>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
2. log4j.properties
#將等級(jí)為DEBUG的日志信息輸出到console和file這兩個(gè)目的地锋谐,console和file的定義在下面的代碼
log4j.rootLogger=DEBUG,console,file
#控制臺(tái)輸出的相關(guān)設(shè)置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
#文件輸出的相關(guān)設(shè)置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/vigil.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志輸出級(jí)別
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
3. 配置log4j為日志的實(shí)現(xiàn)
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
4. 日志輸出重要信息
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Opening JDBC Connection
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Created connection 306206744.
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[com.vigil.dao.UserMapper.getUserById]-==> Preparing: select * from mybatis.user where id = ?
[com.vigil.dao.UserMapper.getUserById]-==> Parameters: 2(Integer)
[com.vigil.dao.UserMapper.getUserById]-<== Total: 1
User{id=2, name='李四', pwd='324332'}
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[org.apache.ibatis.transaction.jdbc.JdbcTransaction]-Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@12405818]
[org.apache.ibatis.datasource.pooled.PooledDataSource]-Returned connection 306206744 to pool.
在類里的簡(jiǎn)單應(yīng)用
- 在要使用LOG4J的類中遍尺,導(dǎo)入包:import.org.apache.log4j.Logger;
- 日志對(duì)象,參數(shù)為當(dāng)前類的class
static Logger logger = Logger.getLogger(UserDaoText.class);
- 日志級(jí)別
logger.info("info");
logger.debug("debug");
logger.error("error");
五涮拗、MyBatis簡(jiǎn)單分頁
分頁作用:==減少數(shù)據(jù)的處理量==
(一)乾戏、 使用LImit分頁(物理分頁)
//語法:select * from 表名 limit startIndex,pageSize
select * from user limit 3; #[0,3)-->0,1,2,從0開始拿3個(gè)數(shù)據(jù)
使用MyBatis實(shí)現(xiàn)分頁三热,核心是sql語句
- 接口
//分頁鼓择,查詢用戶,傳參是map就漾,壞處是不規(guī)范
List<User> getUserByLimit(Map<String,Integer> map);
- Mapper.xml
<!--結(jié)果集映射-->
<resultMap id="UserMap" type="User">
<!--column數(shù)據(jù)庫中的字段呐能,property實(shí)體類中的屬性-->
<!-- <result column="id" property="id"></result>-->
<!-- <result column="name" property="name"></result>-->
<result column="pwd" property="password"></result>
</resultMap>
<select id="getUserByLimit" parameterType="map" resultMap="UserMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
</select>
- 測(cè)試
@Test
public void testLimit() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",0);
map.put("pageSize",2);
List<User> users = mapper.getUserByLimit(map);
for(User user : users) {
System.out.println(user);
}
sqlSession.close();
}
(二)、使用RowBounds分頁(邏輯分頁)
- 不使用sql實(shí)現(xiàn)分頁
- 接口
//使用RowBounds分頁
List<User> getUserByRowBounds();
- Mapper.xml
<!--結(jié)果集映射-->
<resultMap id="UserMap" type="User">
<!--column數(shù)據(jù)庫中的字段抑堡,property實(shí)體類中的屬性-->
<!-- <result column="id" property="id"></result>-->
<!-- <result column="name" property="name"></result>-->
<result column="pwd" property="password"></result>
</resultMap>
<select id="getUserByRowBounds" resultMap="UserMap">
select * from mybatis.user
</select>
- 測(cè)試
@Test
public void getUserByRowBounds() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
//使用RowBounds實(shí)現(xiàn)
RowBounds rowBounds = new RowBounds(1, 2);
//使用Java代碼層面實(shí)現(xiàn)分頁
List<User> userList = sqlSession.selectList("com.vigil.dao.UserMapper.getUserByRowBounds", null, rowBounds);
for(User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
limit 和 rowbounds 的區(qū)別
limit |
---|
limit.png
|
rowbounds |
---|
rowbounds.png
|
(三)摆出、PageHelper
(四)、面向接口編程
六首妖、MyBatis復(fù)雜查詢_簡(jiǎn)單實(shí)現(xiàn)
復(fù)雜查詢環(huán)境搭建
數(shù)據(jù)庫文件
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO teacher(`id`, `name`) VALUES (1, '魚佬');
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小紅', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小張', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
項(xiàng)目搭建
- 導(dǎo)入mybatis
- 編寫資源文件
- 編寫mybatis核心配置文件
- 引入外部資源文件:properties
- 日志:settings
- 起別名:typeAliases
- 環(huán)境(數(shù)據(jù)庫資源):environments-->transactionManager偎漫、dataSource
- 編寫實(shí)體類
- 編寫Mapper接口
- 編寫Mapper.xml
- mapper標(biāo)簽的命名空間:綁定接口
- 選擇sql對(duì)應(yīng)的標(biāo)簽,綁定方法
- 書寫sql語句
- 到MyBatis的核心配置文件中注冊(cè)mapper
- 測(cè)試
多對(duì)一處理(association)
查詢學(xué)生信息以及對(duì)應(yīng)老師的信息
思路: 1.查詢學(xué)生信息 有缆;2.根據(jù)tid查找相對(duì)應(yīng)的老師
一象踊、按照結(jié)果嵌套處理(類似聯(lián)表查詢)
<select id="getStudentsByResult" resultMap="StudentWithTeacherByResult">
select s.id sid,s.name sname,t.name tname,tid
from mybatis.teacher t , mybatis.student s
where t.id = s.tid
</select>
<resultMap id="StudentWithTeacherByResult" type="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"></result>
<result property="id" column="tid"></result>
</association>
</resultMap>
二温亲、按照查詢嵌套處理(類似子查詢)
<select id="getStudents" resultMap="StudentWithTeacher">
select * from mybatis.student
</select>
<select id="getTeacher" resultType="Teacher">
select * from mybatis.teacher where id = #{tid}
</select>
<resultMap id="StudentWithTeacher" type="Student">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<!--復(fù)雜的屬性,單獨(dú)處理杯矩,對(duì)象:association 集合:collection-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"></association>
</resultMap>
一對(duì)多處理
一栈虚、按照結(jié)果嵌套處理(類似聯(lián)表查詢)
<select id="getTeacherByResult" parameterType="int" resultMap="teacher">
select s.id sid,s.name sname,t.id tid,t.name tname
from mybatis.teacher t , mybatis.student s
where t.id = s.tid and t.id = #{id}
</select>
<resultMap id="teacher" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<!--復(fù)雜的屬性,我們需要單獨(dú)處理 對(duì)象:association 集合:collection
javaType=""指定的屬性的類型
集合中的泛型信息史隆,使用ofType獲取
-->
<collection property="students" ofType="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
</collection>
</resultMap>
二节芥、按照查詢嵌套處理(類似子查詢)
<select id="getTeacher" resultMap="TeacherWithStudent">
select * from mybatis.teacher where id = #{id}
</select>
<select id="getStudent" resultType="Student">
select * from mybatis.student where tid = #{id}
</select>
<resultMap id="TeacherWithStudent" type="Teacher">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<collection property="students" column="id" javaType="List" ofType="Student" select="getStudent"></collection>
</resultMap>
小結(jié)
- 關(guān)聯(lián) - association【多對(duì)一】
- 集合 - collection【一對(duì)多】
- javaType:用來指定實(shí)體類中屬性的類型
- ofType:用來指定映射到List或者集合中的pojo類型,泛型中的約束類型
注意
- 保證SQL的可讀性
- 字段和屬性名問題
- 日志查看
七逆害、MyBatis動(dòng)態(tài)SQL
- 動(dòng)態(tài)SQL:根據(jù)不同的條件生成不同的SQL語句
- 本質(zhì)還是sql語句头镊,但卻可以在sql層面上,執(zhí)行一個(gè)邏輯代碼
動(dòng)態(tài) SQL 元素和 JSTL 或基于類似 XML 的文本處理器相似魄幕。
- if
- choose(when相艇,otherwise)
- trim(where,set)
- foreach
環(huán)境搭建
- 數(shù)據(jù)庫
CREATE TABLE `blog`(
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客標(biāo)題',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '創(chuàng)建時(shí)間',
`views` INT(30) NOT NULL COMMENT '瀏覽量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
新建工程
編寫資源文件
編寫MyBatis核心文件
- 引入外部資源文件
- 日志設(shè)置
- 駝峰命名轉(zhuǎn)化設(shè)置
- 起別名
- 數(shù)據(jù)庫環(huán)境配置
- 當(dāng)編寫好mapper要記得注冊(cè)
- 編寫工具類
- 獲得SqlSession的工具類
- 獲得隨機(jī)字符串的工具類
實(shí)體類:JavaBean
實(shí)體類接口
編寫對(duì)應(yīng)接口的mapper
- namespace
- 選擇對(duì)應(yīng)sql語句標(biāo)簽
- 編寫sql語句
- 測(cè)試
IF
- 接口
//查詢博客
List<Blog> queryBlogIf(Map map);
- Mapper.xml
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</select>
- 測(cè)試
@Test
public void queryBlogIf() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","會(huì)議廳");
List<Blog> blogs = mapper.queryBlogIf(map);
for(Blog blog : blogs) {
System.out.println(blog);
}
sqlSession.close();
}
choose(when纯陨,otherwise)
- 類似switch語句
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
title = #{title}
</when>
<when test="author != null">
author = #{author}
</when>
<otherwise>
views >= #{views}
</otherwise>
</choose>
</where>
</select>
trim(where坛芽,set)
-
where 標(biāo)簽,會(huì)識(shí)別追加語句的出現(xiàn)翼抠,是否過濾and或or
這也說明了咙轩,追加語句最好都加上and或or
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</where>
</select>
- set標(biāo)簽,動(dòng)態(tài)設(shè)置set關(guān)鍵字阴颖,同時(shí)會(huì)刪掉無關(guān)的逗號(hào)(where語句前面的逗號(hào))
<update id="updateBlog" parameterType="map">
update mybatis.blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author},
</if>
</set>
where id = #{id}
</update>
自定義 trim 元素來定制 where 元素的功能活喊。比如,和 where 元素等價(jià)的自定義 trim 元素為
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
set 元素等價(jià)的自定義 trim 元素
<trim prefix="SET" suffixOverrides=",">
...
</trim>
SQL片段
這個(gè)元素可以用來定義可重用的 SQL 代碼片段量愧,以便在其它語句中使用钾菊。 參數(shù)可以靜態(tài)地(在加載的時(shí)候)確定下來,并且可以在不同的 include 元素中定義不同的參數(shù)值偎肃。
- 將復(fù)用高的sql語句抽取出來放到一個(gè)標(biāo)簽里煞烫,在其他sql便簽中使用id關(guān)聯(lián)使用
- 使用sql便簽將其抽取
<sql id="if-title-author">
<if test="title != null">
and title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
- 使用include標(biāo)簽和sql便簽的id將其引用
<select id="queryBlogIf" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
- 注意:
- 最好基于單表來定義SQL片段
- 不要加上where或者set語句,因?yàn)槠涮厥?/li>
Foreach
動(dòng)態(tài) SQL :對(duì)集合進(jìn)行遍歷(尤其是在構(gòu)建 IN 條件語句的時(shí)候)累颂。
(1)指定一個(gè)集合滞详,聲明可以在元素體內(nèi)使用的集合項(xiàng)(item)和索引(index)變量。指定開頭與結(jié)尾的字符串以及集合項(xiàng)迭代之間的分隔符紊馏。這個(gè)元素也不會(huì)錯(cuò)誤地添加多余的分隔符料饥。
- 注意: 可以將任何可迭代對(duì)象(如 List、Set 等)瘦棋、Map 對(duì)象或者數(shù)組對(duì)象作為集合參數(shù)傳遞給 foreach稀火。當(dāng)使用可迭代對(duì)象或者數(shù)組時(shí),index 是當(dāng)前迭代的序號(hào)赌朋,item 的值是本次迭代獲取到的元素凰狞。當(dāng)使用 Map 對(duì)象(或者 Map.Entry 對(duì)象的集合)時(shí)篇裁,index 是鍵,item 是值赡若。
<select id="queryBlogForeach" parameterType="map" resultType="Blog">
select * from mybatis.blog
<where>
<foreach collection="ids" item="id" open="and id in (" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
==> Preparing: select * from mybatis.blog WHERE id in ( ? )
==> Parameters: 1(Integer)
動(dòng)態(tài)sql核心:拼接sql
保證正確性:sql語句最好先在數(shù)據(jù)庫測(cè)試成功了达布,再去拼接sql語句
八、MyBatis緩存_簡(jiǎn)單了解
簡(jiǎn)介(了解)
- 緩存(cache)是什么
- 存在內(nèi)存中的臨時(shí)數(shù)據(jù)
- 將用戶經(jīng)常查詢的數(shù)據(jù)放在緩存(內(nèi)存)中逾冬,用戶去查詢數(shù)據(jù)就不用從磁盤上(關(guān)系型數(shù)據(jù)庫數(shù)據(jù)文件)查詢黍聂,從緩存中查詢,從而提高查詢效率身腻,解決了高并發(fā)系統(tǒng)的性能問題
- 為什么使用緩存
- 減少和數(shù)據(jù)庫的交互次數(shù)产还,減少系統(tǒng)開銷,提高系統(tǒng)效率
- 什么樣的數(shù)據(jù)使用緩存
- 經(jīng)常查詢并且不經(jīng)常改變的數(shù)據(jù)
MyBatis緩存
- MyBatis包含一個(gè)非常強(qiáng)大的查詢緩存特性嘀趟,可以非常方便地定制和配置緩存脐区。緩存可以極大的提升查詢xiaolv
- MyBatis系統(tǒng)中默認(rèn)定義了兩級(jí)緩存:一級(jí)緩存和二級(jí)緩存
- 默認(rèn)情況下,只有一級(jí)緩存開啟(SqlSession級(jí)別的緩存她按,也稱為本地緩存)
- 二級(jí)緩存需要手動(dòng)開啟和配置牛隅,基于namespace級(jí)別的緩存
- 為了提高擴(kuò)展性,MyBatis定義了緩存接口Cache酌泰,通過實(shí)現(xiàn)Cache接口自定義二級(jí)緩存
一級(jí)緩存
- 一級(jí)緩存也叫本地緩存:SqlSession
- 與數(shù)據(jù)庫同一次會(huì)話期間查詢到的數(shù)據(jù)會(huì)放到本地緩存中
- 下一次如果需要獲得相同的數(shù)據(jù)媒佣,則直接從緩存中拿,除非緩存中沒有才會(huì)去查詢數(shù)據(jù)庫
緩存失效的情況:
- 查詢不同的東西
- 增刪改操作陵刹,可能會(huì)改變?cè)瓉淼臄?shù)據(jù)默伍,必定會(huì)刷新緩存
- 查詢不同的Mapper.xml
- 手動(dòng)清理緩存
小結(jié):
一級(jí)緩存是默認(rèn)開啟的,只在一次SqlSession中有效授霸,也就是拿到數(shù)據(jù)庫連接到關(guān)閉數(shù)據(jù)庫連接的這個(gè)區(qū)間段(一級(jí)緩存就是一個(gè)Map)
二級(jí)緩存
- 二級(jí)緩存也叫全局緩存巡验,一級(jí)緩存作用域太低
- 基于namespace級(jí)別的緩存,一個(gè)名稱空間碘耳,對(duì)應(yīng)一個(gè)二級(jí)緩存
- 工作機(jī)制:
- 一個(gè)會(huì)話查詢一條數(shù)據(jù),這個(gè)數(shù)據(jù)會(huì)被放在當(dāng)前會(huì)話的一級(jí)緩存中
- 如果當(dāng)前會(huì)話關(guān)閉了框弛,這個(gè)會(huì)話對(duì)應(yīng)的一級(jí)緩存就沒了辛辨,但是開啟二級(jí)緩存后,這個(gè)一級(jí)緩存中的數(shù)據(jù)就會(huì)保存到二級(jí)緩存中
- 新的會(huì)話查詢信息瑟枫,會(huì)到二級(jí)緩存中獲取信息(假如沒有就到一級(jí)緩存斗搞,還是沒有則查詢數(shù)據(jù)庫)
- 不同的mapper查出的數(shù)據(jù)會(huì)放到自己對(duì)應(yīng)的緩存(map)中
使用二級(jí)緩存的步驟
- 開啟全局緩存
<!--顯式的開啟全局緩存-->
<setting name="cacheEnabled" value="true"/>
- 在要使用二級(jí)緩存的Mapper中開啟
<!--在當(dāng)前Mapper.xml中使用二級(jí)緩存-->
<cache/>
- 自定義參數(shù)
<!--在當(dāng)前Mapper.xml中使用二級(jí)緩存-->
<cache eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true" />
- error
實(shí)體類需要序列化
小結(jié):
- 只要開啟了二級(jí)緩存,在同一個(gè)Mapper下就有效
- 所有的數(shù)據(jù)都會(huì)先放在一級(jí)緩存中
- 只有當(dāng)會(huì)話提交慷妙,或者關(guān)閉的時(shí)候僻焚,一級(jí)緩存中的數(shù)據(jù)才會(huì)提交到二級(jí)緩存中
緩存原理
基于內(nèi)存的數(shù)據(jù)庫:Redis實(shí)現(xiàn)緩存