MyBatis
一、Mybatis 表--实体类--mapper接口--映射文件
1.创建maven工程
1.1打包方式
- jar
1,2引入依赖
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.8</version>
</dependency>
</dependencies>
1.3创建MyBatis的核心配置文件
- MlyBatis核心配置文件中,标签的顺序:
properties?,settings ? ,typeAliases ?,typeHandiers ?,objectFactory ?,objectwrapperFactory ? , reflectorFactory ?,piugins ? ,environments? , databaserdProvider ? , mappers ?
<?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.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
1.4创建Mapper接口
package com.kaiyu.mybatis.mapper;
public interface UserMapper {
/*添加用户信息*/
int insertUser();
}
1.5创建pojo实现类user
package com.kaiyu.mybatis.pojo;
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
private String sex;
private String email;
public User() {
}
public User(Integer id, String username, String password, Integer age, String sex, String email) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
this.sex = sex;
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
", email='" + email + '\'' +
'}';
}
}
1.6创建mapper映射文件 类名+Mapper.xml
- MyBati5面向接口编程的两个一致:
- 1,映射文件的namespace要和napper接口的全茭名保持一致* com.kaiyu.mybatis.mapper.UserMapper
- 2、映射文件中sQL语句的id要和napper接口中的方法名一致* /
<?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.kaiyu.mybatis.mapper.UserMapper">
<!--int insertUser();-->
<insert id="insertUser">
insert into user values(null,'张老三','123',23,'女','123qq.com')
</insert>
</mapper>
1.7创建测试类创建
public class MybatisTest {
@Test
//添加
public void testMybatis() throws IOException {
//加载核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//获取SqlSessionFactoryBuilder
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//获取sqlSessionFactory
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
//获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取Mapper接口对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//测试
int result = mapper.insertUser();
//提交事物
sqlSession.commit();
System.out.println("result:"+result);
}
1.8Mybatis核心配置文件 environments
1.8.1.environments
- environments:配置多个连接数据库的环境
- 属性
- default: 设置默认使用的环境的id
- 属性
- environment:配置某个具体的环境
- 属性
- id:表示连解数据库的环境的唯一标识,不能重复
- 属性
- dataSource:配置数据源
- 属性
- type:设置数据源的 类型
- type="POOLED | UNPOOLED /| JNDI"
- POOLED:表示使用数姻库连接池缓存数据库连接
- UNPOOL ED:表示不使用数据库连接池
- JNDI:表示使用上下文中的数据源
- 属性
1.9 创建jdbc.properties
jdbc.driver = com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mybatis
jdbc.user = root
jdbc.password = root
-
然后在核心配置文件里导入
-
<properties resource="jdbc.properties"/>
-
1.10设置类型别名
- typeAlias :设置某个类型的别名属性:
- type:设置需要设置别名的类型
- alias:设置某个类型的别名,若不设置该属性,那么该类型拥有默认的别名,即类名且不区分大小写
<!--引入typeAliases 设置类型别名 不区分大小写-->
<typeAliases>
<typeAlias type="com.kaiyu.mybatis.pojo.User" alias="User"></typeAlias>
</typeAliases>
- 以包为单位,将包下所有的类型设置默认的类型别名
1.11核心配置文件mapper
<!--引入映射文件--><mappers>
<!--<mapper resource="mapper5/ UserMapper.xmL " / >-->
<!--
以包为单位引入t映射文件要求:
mapper接口所在的包要和映射文件所在的包一致
mapper接口要和映射文件的名字一致
-->
<package name="com.atguigu.mybatis.mapper""/>
二、MyBatis获取参数值的两种方式(重点)
- MyBatis获取参数估的两种方式:${}和#{}
- ${}的本质就是字符串拼接,#{}的本质就是占位符赋值
- ${}使用字符申拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号:但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
1、单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型
此时可以使用${}和#{}以任意的名称获取参数的值,注意${}仍需要手动加单引号
-
package com.kaiyu.mybatis.mapper; import com.kaiyu.mybatis.pojo.User; import java.util.List; public interface SeleteMapper { /*查询用户信息*/ List<User> selectuser(); /*根据用户名查询用户信息*/ User selectUserName(String username); }
<!--User selectUserName();-->
<select id="selectUserName" resultType="user">
select * from USER where username = #{username}
<!--或者-->
select * from user where username = '${username}'
</select>
@Test
public void selectUserName(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
User user = mapper.selectUserName("张三");
//或者 ${}形式
User user = mapper.selectUserName("张三");
System.out.println(user);
}
2、多个字面量类型的参数
若mapper接口中的方法参数为多个时
此时MyBatls会自动将这些参数放在一个map集合中,以arg0.arg1...为键,以参数为值;以param1.,param2..为键,以参数为值;因此只需要通过$份和#)访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
arg0 ,arg1 param1.,param2
/*验证登陆*/
User checkLogin(String username,String password);
<!-- User checkLogin(String username,String password);-->
<select id="checkLogin" resultType="user">
select *
from USER where username = #{arg0} and password = #{arg1};
</select>
@Test
public void checkLogin(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
User zs = mapper.checkLogin("张三", "123");
System.out.println(zs);
}
3、map集合类型的参数
若mapper接口中的方达需要的参数为多个时。此时可以手动创建map集合,将这些数据放在map中只需要通过$和#()访问map集合的键就可以获取相对应的值。注意$需要手动加单引号
User checkLoginMap(Map<String ,Object> map);
<!-- User checkLoginMap(Map String ,Object map);-->
<select id="checkLoginMap" resultType="user">
select * from USER where username = #{username} and #{password}
</select>
@Test
public void checkLoginMap() {
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
Map<String , Object> map = new HashMap<>();
map.put("username","张三");
map.put("password","123");
User user = mapper.checkLoginMap(map);
System.out.println(user);
}
4.mapper接口方法的参数是实体类型的参数
- 只需要通过#{}和${}以属性的方式访问属性值即可,但是需要注意${}的单引号问题
int insertUser(User user);
<!-- int insertUser(User user);-->
<insert id="insertUser">
insert into user values(null,#{username},#{password},#{age},#{sex},#{email})
</insert>
@Test
public void insertUser() {
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
int result = mapper.insertUser(new User(null, "王五", "456", 56, "男", "456@qq.com"));
System.out.println(result);
}
5.使用@Param方式注解命名参数
- 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储
- 以@Param值为键,以参数为值
- 以parm1,parm2..为键,以参数为值
6.MyBatis查询功能
6.1MyBatis的各种查询功能:
- 1、若查询出的数据只有一条,可以通过实体类对象或者集合接收
- 2、若查询出的数据有多条,一定不能通过实体类对象接收,此时会抛异常TooNanyResultsException
/*根据id来查询用户信息*/
User idSelect(@Param("id") Integer id);
/*根据id来查询多个用户*/
List<User> idMoreSelect();
<!--User idSelect(@Param("id") Integer id);-->
<select id="idSelect" resultType="user">
select *
from USER where id = #{id};
</select>
<!-- List<User> idMoreSelect(@Param("id") Integer id);-->
<select id="idMoreSelect" resultType="user">
select *
from USER ;
</select>
@Test
public void idSelect() {
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
System.out.println(mapper.idSelect(3));
}
@Test
public void idMoreSelect() {
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
List<User> list = mapper.idMoreSelect();
list.forEach(user -> System.out.println(user));
}
-
查询数据库条目数
-
/*查询数据库里面的条数 Count*/ Integer count();
-
<!-- Integer count();-->
<select id="count" resultType="int">
select count(*) from USER
</select>
@Test
public void count() {
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class);
Integer count = mapper.count();
System.out.println(count);
}
-
map形式查询数据
-
// 根据id来查询用户信息 map方法 Map<String ,Object> getIdToMap(@Param("id") Integer id);
<!-- Map<String ,Object> getIdToMap();--> <select id="getIdToMap" resultType="map"> select * from USER where id = #{id}; </select>
@Test public void getIdToMap() { SqlSession sqlSession = sqlSessionUtil.getSqlSession(); SeleteMapper mapper = sqlSession.getMapper(SeleteMapper.class); Map<String, Object> idToMap = mapper.getIdToMap(4); System.out.println(idToMap); }
-
6.2MyBatis中设置了默认的类型别名
- java.Lang.Integer-->int, integerint-->_int,_integer
- Map-->map
- string-->string
三.特殊SQL的执行
1.模糊查询
public interface SqlMapper {
/*根据用户名模糊查询用户信息*/
List<User> getUsernameByLike(@Param("username") String username);
/*根据用户名模糊查询*/
List<User> ByLike(@Param("username") String username);
}
<!--List<User> getUsernameByLike(@Param("username") String username);-->
<select id="getUsernameByLike" resultType="user">
select * from USER where username like '%${username}%'
</select>
<!--List<User> ByLike(@Param("username") String username);-->
<select id="ByLike" resultType="user">
select * from USER where username like "%"#{username}"%"
</select>
@Test
public void getUsernameByLike(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
List<User> zs = mapper.getUsernameByLike("张三");
System.out.println(zs);
}
@Test
public void ByLike(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
List<User> s = mapper.ByLike("三");
System.out.println(s);
}
2.批量删除
/*根据id来批量删除数据*/
int deleteId(@Param("ids") String ids);
<!-- List<User> deleteId(@Param("ids") String ids);-->
<delete id="deleteId">
delete from user where id in (${ids})
</delete>
@Test
public void deleteId(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
int result = mapper.deleteId("1,2,3");
System.out.println(result);
}
3.动态设置表名
/*查询指定表中的数据*/
List<User> getUserByTableName(@Param("tableName") String tableName);
/*动态设置表名*/
List<User> getUserTableName(@Param("TableName") String TableName);
<!-- List<User> getUserByTableName(@Param("tableName") String tableName);-->
<select id="getUserByTableName" resultType="user">
select *
from ${tableName};
</select>
<!-- List<User> getUserTableName(@Param("TableName") String TableName);-->
<select id="getUserTableName" resultType="user">
select *
from ${TableName};
</select>
@Test
public void getUserByTableName(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
List<User> user = mapper.getUserByTableName("user");
System.out.println(user);
}
@Test
public void getUserTableName(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
List<User> user = mapper.getUserTableName("user");
System.out.println(user);
}
4.添加功能获取自增的主键
-
- void insertUser(User user )
- useGeneratedKeys :设置当前标签中的sql使用自增的主键
- keyProperty :将自增的主键的值传输到映射文件中的某个属性
/*添加数据*/
void insertUser(User user );
void insert(User user);
<!-- void insertUser(User user );-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into USER
values (null,#{username},#{password},#{age},#{sex},#{email});
</insert>
<!-- void insert(User user);-->
<insert id="insert" keyProperty="id" useGeneratedKeys="true">
insert into user
values (NUll,#{username},#{password},#{age},#{sex},#{email});
</insert>
@Test
public void insertUser(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
User user = new User(null,"码子","899",56,"男","123.qq.com");
mapper.insertUser(user);
System.out.println(user);
}
@Test
public void insert(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
SqlMapper mapper = sqlSession.getMapper(SqlMapper.class);
User user = new User(null,"老六","899",56,"男","123.qq.com");
mapper.insertUser(user);
System.out.println(user);
}
5.工具类Utils
public class mybatisUtils {
public static SqlSession getSqlSession(){
SqlSession sqlSession =null;
try {
InputStream is = Resources.getResourceAsStream("mybatis-config");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSession;
}
}
四、自定义映射resultMap
1.resultMap处理字段和属性的映射关系(级联属性赋值)
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
/*查询所有的员工信息 */
List<Emp> getAllEmp();
<!-- List<Emp> getAllEmp();-->
<select id="getAllEmpId" resultType="emp">
select * from emp;
</select>
<resultMap id="empResultMap" type="emp">
<id property="eid" column="eid"></id>
<result property="emp_name" column="empName"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</resultMap>
<select id="getAllEmp" resultMap="empResultMap">
select *
from emp;
</select>
@Test
public void getAllEmp(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> allEmp = mapper.getAllEmp();
System.out.println(allEmp);
}
2.多对一映射关系
1.通过association解决多对一映射关系
- association:处理多对一的映射关系
- property:需要处理多对的映射关系的属性名
- javaType:该属性的类型
/*查询员工信息和所对应的部门信息*/
Emp getEmpAndDept(@Param("eid") Integer eid);
<resultMap id="getEmpAndDeptTwo" type="emp">
<id property="eid" column="eid"></id>
<result property="emp_name" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<association property="dept" javaType="Dept">
<id property="did" column="did"></id>
<result property="dept_name" column="dept_name"></result>
</association>
</resultMap>
<!-- Emp getEmpAndDept(@Param("eid") Integer eid);-->
<select id="getEmpAndDept" resultMap="getEmpAndDeptTwo">
select * from emp left join dept on emp.did = dept.did where emp.eid = #{eid}
</select>
@Test
public void getEmpAndDept(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
Emp empAndDept = mapper.getEmpAndDept(1);
System.out.println(empAndDept);
}
3.一对多映射关系
/*获取部门以及部门中所有员工信息*/
Dept getDeptAndEmp(@Param("did") Integer did);
<!-- Dept getDeptAndEmp(@Param("did") Integer did);-->
<resultMap id="getDeptAndEmpResultMap" type="Dept">
<id property="did" column="did"></id>
<result property="dept_name" column="dept_name"></result>
<collection property="emps" ofType="Emp">
<id property="eid" column="eid" ></id>
<result property="emp_name" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="age"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<select id="getDeptAndEmp" resultMap="getDeptAndEmpResultMap">
select *
from dept left join emp on dept.did = emp.did where dept.did = #{did}
</select>
@Test
public void getDeptAndEmp(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept deptAndEmp = mapper.getDeptAndEmp(2);
System.out.println(deptAndEmp);
}
五、动态SQL
1.if标签
-
if:根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中
-
<if test="emp_name != null and emp_name != ''"> emp_name = #{emp_name} </if> <if test="age != null and age != ''"> and age = #{age} </if> <if test="sex != null and sex != ''"> and sex = #{sex} </if> <if test="emp_name != null and emp_name != ''"> and email = #{email} </if>
-
2.where 标签
- 当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and或or去掉
- 当where标签中没有内容时,此时where标签没有任何效果
- where不能将内容后多余的and或or去掉
<where>
<if test="emp_name != null and emp_name != ''">
emp_name = #{emp_name}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="emp_name != null and emp_name != ''">
and email = #{email}
</if>
</where>
3, trim 标签
- 若标签中有内容时:
- prefix |suffix:将trim标签中内容前面或后面添加指定内容
- suffixoverrides|prefixoverrides :将trim标签中内容前面或后面去掉指定内容若标签中没有内容时,trim标签也没有任何效果
4. choose, when. otherwise相当于if...else
- if...else*when至少要有一个,otherwise最多只能有一个
5.foreach
- collection:设置需要循环的数组或集合
- item:表示数组或集合中的每一个数据
- separator:循环体之间的分割符
- open:foreach标签所循环的所有内容的开始符
- close:foreach标签所循环的所有内容的结束符
/*批量添加*/
int getEmpByInsert(@Param("emps") List<Emp> emps);
<!-- int getEmpByInsert(List<Emp> emps);-->
<insert id="getEmpByInsert">
insert into emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.emp_name},#{emp.age},#{emp.sex},#{emp.email},null)
</foreach>
</insert>
@Test
public void getEmpByInsert(){
SqlSession sqlSession = sqlSessionUtil.getSqlSession();
DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);
Emp emp3 = new Emp(null, "a3", 12, "男", "123@qq.com", null);
Emp emp1 = new Emp(null, "a1", 12, "男", "123@qq.com", null);
Emp emp2 = new Emp(null, "a2", 12, "男", "123@qq.com", null);
List<Emp> emps = Arrays.asList(emp1, emp2, emp3);
System.out.println(mapper.getEmpByInsert(emps));
6, sqL标签
设置SQL片段:
引用SQL片段:
六、mybatis缓存
1、MyBatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
使一级缓存失效的四种情况:
- 1)不同的SqlSession对应不同的—级缓存
- 2)同一个SqlSession但是查询条件不同
- 3)同一个SqlSession两次查询期间执行了任何一次增删改操作
- 4)同一个SqlSession两次查询期间手动清空了缓存
2、MyBatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
1.二级缓存开启的条件:
- a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
- b>在映射文件中设置标签
- c>二级缓存必须在SqlSession关闭或提交之后有效
2、二级缓存的相关配置
在mapper配置文件中添加的cache标签可以设置—些属性:.
- eviction属性:缓存回收策略
- LRU (Least Recently Used)-最近最少使用的:移除最长时间不被使用的对象。
- FIFO (First in First out)-先进先出:按对象进入缓存的顶序来移除它们。
- SOFT-软引用:移除基于垃圾回收器状态和软引用规则的对象。
- WEAK -弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。默认的是 LRU
- flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新 - size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出 - readOnly属性:只读,true/false
- true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
- false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是false。
3、MyBatis缓存查询的顺序
- ·先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
- ·如果二级缓存没有命中,再查询—级缓存
- 如果—级缓存也没有命中,则查询数据库
- SqlSession关闭之后,—级缓存中的数据会写入二级缓存
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通