Mybatis
环境:jdk mysql maven idea
SSM框架、配置文件的。
一、简介
1.1、什么是Mybatis?
Mysbatis是一款优秀的持久化框架
它支持制定化SQL,存储过以及高级映射
Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集
Mybatis可以使用简单的XML或注解来配置和映射原生类型,接口和POJO为数据库中的记录
Mybatis原本是apache的一个开源项目Batis2010年这个项目由apache software foundation迁移到了Google code,并改名为Mybati
2013年11月迁移到Github如何获得mybatis?
Maven厂库:
Maven下载网址:https://www.mybatis.org/mybatis-3Maven - <dependency> <br><br>• <groupId>org.mybatis</groupId><br><br>• <artifactId>mybatis</artifactId> <br><br>• <version>3.5.11</version><br><br> </dependency>
复制代码 Github网址: https://github.com/mybatis/mybatis-3中午网:https://mybatis.net.cn/
1.2、持久化
数据持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
内存断电即失数据库(jdbc)、io文件持久化
为什么需要持久化?
有一些对象,不能丢内存太贵了
13、持久层
Dao层、Service层、Controller层
完成持久化工作的代码块
层界十分明显
1.4、为什么需要Mybatis?
帮助程序员将数据存入数据库中
方便
传统的jdbc太复杂了、简化、框架、自动化
不用mybatis也可以,更容易上手优点:
简单易学
灵活
Sql和代码的分离,提高了可维护性
提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系标签,支持对象关系组建维护
提供xml标签,支持编写动态sql
*使用的人多
二、创建一个Mybatis项目
1、创建maven项目
2、导入依赖包- <dependencies><br><dependency><br><groupId>mysql</groupId><br><artifactId>mysql-connector-java</artifactId><br><version>5.1.47</version><br></dependency><br><dependency><br><groupId>org.mybatis</groupId><br><artifactId>mybatis</artifactId><br><version>3.5.10</version><br></dependency><br><dependency><br><groupId>junit</groupId><br><artifactId>junit</artifactId><br><version>4.13.2</version><br></dependency><br></dependencies>
复制代码 这里的mybatis就是mybatis的依赖
3、创建工具类- package com.zeng.mybatis.utils;<br><br>import org.apache.ibatis.io.Resources;<br>import org.apache.ibatis.session.SqlSession;<br>import org.apache.ibatis.session.SqlSessionFactory;<br>import org.apache.ibatis.session.SqlSessionFactoryBuilder;<br><br>import java.io.IOException;<br>import java.io.InputStream;<br><br>public class MybatisUtils {<br>public static SqlSessionFactory sqlSessionFactory;<br>static {<br>try {<br>String resource = "mybatis-config.xml";<br>InputStream inputStream = Resources.getResourceAsStream(resource);<br>sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);<br>} catch (IOException e) {<br>e.printStackTrace();<br>}<br>}<br>public static SqlSession getSqlSession(){<br>return sqlSessionFactory.openSession();<br>}<br>}
复制代码 4、创建实体类- package com.zeng.mybatis.pojo;<br><br>public class User {<br>private int id;<br>private String name;<br>private String pwd;<br><br>public User() {<br>}<br><br>public User(int id, String name, String pwd) {<br>this.id = id;<br>this.name = name;<br>this.pwd = pwd;<br>}<br><br>public int getId() {<br>return id;<br>}<br><br>public void setId(int id) {<br>this.id = id;<br>}<br><br>public String getName() {<br>return name;<br>}<br><br>public void setName(String name) {<br>this.name = name;<br>}<br><br>public String getPwd() {<br>return pwd;<br>}<br><br>public void setPwd(String pwd) {<br>this.pwd = pwd;<br>}<br><br>@Override<br>public String toString() {<br>return "User{" +<br>"id=" + id +<br>", name='" + name + '\'' +<br>", pwd='" + pwd + '\'' +<br>'}';<br>}<br>}
复制代码 5、创建Mapper接口- package com.zeng.mybatis.dao;<br><br>import com.zeng.mybatis.pojo.User;<br><br>import java.util.List;<br><br>public interface UserDao {<br>List<User> getUserList();<br>User getUserId(int id);<br>int addUser(User user);<br>int updateUser(User user);<br>int deleteUser(int id);<br>}
复制代码 6、创建Mapper接口对应的xml文件- <?xml version="1.0" encoding="UTF-8" ?><br><!DOCTYPE mapper<br>PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"<br>"http://mybatis.org/dtd/mybatis-3-mapper.dtd"><br><mapper namespace="com.zeng.mybatis.dao.UserDao"><br><select id="getUserList" resultType="com.zeng.mybatis.pojo.User"><br>select * from User<br></select><br></mapper>
复制代码 7、在resources包下创建连接数据库的对应信息.xml- <?xml version="1.0" encoding="UTF-8" ?><br><!DOCTYPE configuration<br>PUBLIC "-//mybatis.org//DTD Config 3.0//EN"<br>"http://mybatis.org/dtd/mybatis-3-config.dtd"><br><configuration><br><environments default="development"><br><environment id="development"><br><transactionManager type="JDBC"/><br><dataSource type="POOLED"><br><property name="driver" value="com.mysql.jdbc.Driver"/><br><property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=UTC&useSSL=false"/><br><property name="username" value="root"/><br><property name="password" value="12345678"/><br></dataSource><br></environment><br></environments><br><mappers><br><mapper resource="com/zeng/mybatis/dao/UserMapper.xml"/><br></mappers><br></configuration>
复制代码 三、CRUD
1、namespace
namespace中的包名要和Dao/mapper接口中的包名一致
2、select
选择、查询语句
id:就是对应的namespace中的方法名
resultType:Sql语句执行的返回值!
parameterType:参数类型
2.1、对应例子
Mapper.xml对应标签- <select id="getUserId" resultType="com.zeng.mybatis.pojo.User" parameterType="int"><br>select * from User where id = #{id}<br></select>
复制代码 @Text测试方法- @Test<br>public void getUserIdTest(){<br>SqlSession sqlSession = MybatisUtils.getSqlSession();<br>UserDao mapper = sqlSession.getMapper(UserDao.class);<br>User user = mapper.getUserId(1);<br>System.out.println(user);<br>}
复制代码 3、insert增加标签
Mapper.xml对应标签- <insert id="addUser" parameterType="com.zeng.mybatis.pojo.User"><br>insert into User (id,name,pwd)<br>values (#{id},#{name},#{pwd});<br></insert>
复制代码 @Text测试方- @Test<br>public void addUserTest(){<br>SqlSession sqlSession = MybatisUtils.getSqlSession();<br>UserDao mapper = sqlSession.getMapper(UserDao.class);<br>int row = mapper.addUser(new User(4, "丁钰", "85200"));<br>sqlSession.commit();<br>if (row>0){<br>System.out.println("插入成功");<br>}<br>sqlSession.close();<br>}
复制代码 4、update修改标签
Mapper.xml对应标签- <update id="updateUser" parameterType="com.zeng.mybatis.pojo.User"><br>update User<br>set name = #{name},pwd = #{pwd}<br>where id = #{id};<br></update>
复制代码 @Text测试方法- @Test<br>public void updateUserTest(){<br>SqlSession sqlSession = MybatisUtils.getSqlSession();<br>UserDao mapper = sqlSession.getMapper(UserDao.class);<br>int row = mapper.updateUser(new User(4, "丁钰儿", "7894"));<br>sqlSession.commit();<br>if (row>0){<br>System.out.println("修改成功");<br>}<br>sqlSession.close();<br>}
复制代码 5、delete删除标签
Mapper.xml对应标签- <delete id="deleteUser" parameterType="int"><br>delete<br>from User<br>where id = #{id};<br></delete>
复制代码 @Text测试方法- @Test<br>public void deleteUserTest(){<br>SqlSession sqlSession = MybatisUtils.getSqlSession();<br>UserDao mapper = sqlSession.getMapper(UserDao.class);<br>int row = mapper.deleteUser(4);<br>sqlSession.commit();<br>if (row>0){<br>System.out.println("删除成功");<br>}<br>sqlSession.close();<br>}
复制代码 一定要记住增删改的时候一定要增加事务
四、配置设置
configuration(配置)
properties(属性)(重点)
settings(设置)(重点)
typeAliases(类型别名)(重点)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)(重点)
1、properties:
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。
例如:- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
复制代码 设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值。比如:- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
复制代码 2、setting
- cacheEnabled:全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。true | falsetrue<br>lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。<br>logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
复制代码 3、typeAliases:
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties><properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
复制代码 当这样配置时,Blog 可以用在任何使用 domain.blog.Blog 的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:- 每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>@Alias("author")
- public class Author {
- ...
- }
复制代码 4、mappers:
例如: 用户查找资源(包括 file:/// 形式的 URL)- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
复制代码- <br><mappers><br> <mapper url="file:///var/mappers/AuthorMapper.xml"/><br> <mapper url="file:///var/mappers/BlogMapper.xml"/><br> <mapper url="file:///var/mappers/PostMapper.xml"/><br></mappers>
复制代码- <br><mappers><br> <mapper url="file:///var/mappers/AuthorMapper.xml"/><br> <mapper url="file:///var/mappers/BlogMapper.xml"/><br> <mapper url="file:///var/mappers/PostMapper.xml"/><br></mappers>
复制代码- <br><mappers><br> <package name="org.mybatis.builder"/><br></mappers>
复制代码 5、生命周期和作用域
生命周期,和作用域,之至关重要的,因为错误的使用会导致非常严重的并发问题
SqlSessionFactoryBuilder:
一旦创建了SqlSessionFactory,就不再需要它了
定义局部变量、
SqlSessionFactory:
说白了就是可以想象为:数据库连接池
一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。
因此SqlSessionFactory的最佳作用域是应用作用域。
最简单的就是使用单例模式或者静态单例模式。
SqlSession:
连接到连接池的一个请求!
SqlSession的实例不是线程安全的,因此是不能被共享的,所以他的最佳作用域是请求或方法作用域。
用完之后需要赶紧关闭,否则资源被占用!
五、解决字段名和属性名不一致问题
- package com.zeng.mybatis.pojo;<br><br>import org.apache.ibatis.type.Alias;<br><br>public class User {<br> private int id;<br> private String name;<br> private String password;<br><br> public User() {<br> }<br><br> public User(int id, String name, String password) {<br> this.id = id;<br> this.name = name;<br> this.password = password;<br> }<br><br> public int getId() {<br> return id;<br> }<br><br> public void setId(int id) {<br> this.id = id;<br> }<br><br> public String getName() {<br> return name;<br> }<br><br> public void setName(String name) {<br> this.name = name;<br> }<br><br> public String getPassword() {<br> return password;<br> }<br><br> public void setPassword(String pwd) {<br> this.password = pwd;<br> }<br><br> @Override<br> public String toString() {<br> return "User{" +<br> "id=" + id +<br> ", name='" + name + '\'' +<br> ", pwd='" + password + '\'' +<br> '}';<br> }<br>}
复制代码
这里可以看到数据库的字段名为pwd而实体类的属性名为password
查询结果:

解决方法:
1、更改sql语句
没改之前- <select id="getUserId" resultType="com.zeng.mybatis.pojo.User" parameterType="int"><br> select * from User where id = #{id}<br> </select>
复制代码 改之后- <select id="getUserId" resultType="com.zeng.mybatis.pojo.User" parameterType="int"><br> select id,name,pwd as password from User where id = #{id}<br> </select>
复制代码
这里我们通过给字段名取别名可以解决这个问题
2、使用resultMap
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings><settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> <select id="getUserId" resultType="com.zeng.mybatis.pojo.User" parameterType="int"><br> select * from User where id = #{id}<br> </select>
复制代码
这里我们使用resultMap也能查询出来
resultMap 元素是 MyBatis 中最重要最强大的元素。
六、日志工厂
logImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING 1、STDOUT_LOGGING
只需要配置一些文件即可:- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 运行方法进行测试:

2、LOG4J
1、导包:
- <br><dependency><br> <groupId>log4j</groupId><br> <artifactId>log4j</artifactId><br> <version>1.2.17</version><br></dependency>
复制代码 2、创建配置文件log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码 log4j.rootLogger=DEBUG,console,file
#控制台输出的相关设置 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
#文件输出的相关设置 log4j.appender.file = org.apache.log4j.RollingFileAppender log4j.appender.file.File=./log/logFile.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[%c]%m%n
#日志输出级别 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、设置资源文件
- <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 4、使用Logger类
- @Test<br> public void log4jTest(){<br> Logger logger = Logger.getLogger(daoTest.class);<br> logger.info("info:进入了log4jTest");<br> logger.error("error:进入了log4jTest");<br> logger.debug("debug:进入了log4jTest");<br> }
复制代码

七、分页
1、limit
1、接口
- List<User> getUserLimit(Map<String, Integer> map);
复制代码 2、接口对应的mapper
- <select id="getUserLimit" parameterType="map" resultMap="userMap"><br> select * from User limit #{start},#{end}<br> </select>
复制代码 3、测试类
- @Test<br> public void getUserLimit(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> Map<String, Integer> limit = new HashMap<>();<br> limit.put("start",1);<br> limit.put("end",2);<br> List<User> userLimit = mapper.getUserLimit(limit);<br> for (User user : userLimit) {<br> System.out.println(user);<br> }<br> sqlSession.close();<br> }
复制代码 4、结果

2、RowBounds
1、接口
- List<User> getUserRowBounds();
复制代码 2、实现类
- <select id="getUserRowBounds" resultMap="userMap"><br> select * from User<br> </select>
复制代码 3、测试
- @Test<br> public void getUserRowBounds(){<br> RowBounds rowBounds = new RowBounds(1,2);<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> List<User> userList = sqlSession.selectList("com.zeng.mybatis.dao.UserDao.getUserRowBounds", null, rowBounds);<br> for (User user : userList) {<br> System.out.println(user);<br> }<br> sqlSession.close();<br> }
复制代码 3、分页工具
网址:https://pagehelper.github.io/

八、使用注解开发
1、select查询批量数据
1、接口
- public interface UserDao {<br> @Select("select * from User")<br> List<User> getUserList();<br>}
复制代码 2、核心xml配置
(使用注解的核心配置都在这里)- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码
3、测试
- public class daoTest {<br> @Test<br> public void getUserList(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> List<User> userList = mapper.getUserList();<br> for (User user : userList) {<br> System.out.println(user);<br> }<br> sqlSession.close();<br> }<br>}
复制代码
2、select根据id查询
1、接口
- @Select("select * from User where id = #{uid}")<br> User getUserById(@Param("uid")int id);
复制代码 这里的@Param注解是用与有多个基本类型的参数时加上,但是只要时基本数据类型建议都加上
2、测试
- @Test<br> public void getUserById(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> User userById = mapper.getUserById(1);<br> System.out.println(userById);<br> sqlSession.close();<br> }
复制代码
3、insert
1、接口
- @Insert("insert into User (id,name,pwd) values(#{id},#{name},#{pwd})")<br> int addUser(User user);
复制代码 2、测试
- @Test<br> public void addUser(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> mapper.addUser(new User(6, "赵云", "8520"));<br> sqlSession.close();<br> }
复制代码
4、update
1、接口
- @Update("update User set name=#{name},pwd=#{pwd} where id=#{id}")<br> int updataUser(User user);
复制代码 2、测试
- @Test<br> public void updataUser(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> mapper.updataUser(new User(5,"叶凡","987654321"));<br> sqlSession.close();<br> }
复制代码
5、delete
1、接口
- @Delete("delete from User where id=#{id}")<br> int delete(@Param("id")int id);
复制代码 2、测试
- @Test<br> public void deleteUser(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> UserDao mapper = sqlSession.getMapper(UserDao.class);<br> mapper.delete(6);<br> sqlSession.close();<br> }
复制代码
九、Lombok
- 官方介绍:<br>Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.<br><br>Project Lombok是一个java库,可以自动插入编辑器和构建工具,为您的java增添趣味。永远不要再写另一个getter或equals方法,一个注释你的类就有了一个功能齐全的构建器,自动化你的日志变量,等等。
复制代码 1、IDEA中安装Lombok插件

里面的注解有:- @Getter and @Setter<br>@FieldNameConstants<br>@ToString<br>@EqualsAndHashCode<br>@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor<br>@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog<br>@Data<br>@Builder<br>@SuperBuilder<br>@Singular<br>@Delegate<br>@Value<br>@Accessors<br>@Wither<br>@With<br>@SneakyThrows<br>@StandardException<br>@val<br>@var<br>experimental @var<br>@UtilityClass
复制代码 2、添加Maven依赖
- <br><dependency><br> <groupId>org.projectlombok</groupId><br> <artifactId>lombok</artifactId><br> <version>1.18.24</version><br> <scope>provided</scope><br></dependency>
复制代码 3、使用
- package com.zeng.mybatis.pojo;<br><br>import lombok.*;<br><br>@EqualsAndHashCode //equals和hashcode方法<br>@ToString //toString方法<br>@AllArgsConstructor //所有属性的有参构造方法<br>@NoArgsConstructor //无参构造方法<br>@Data //注解在类,生成setter/getter、equals、canEqual、hashCode、toString方法,如为final属性,则不会为该属性生成setter方法<br>@Getter //加在类上面就是所有属性的get方法加在属性上面可以生成单个get方法<br>@Setter //加在类上面就是所有属性的set方法加在属性上面可以生成单个set方法<br>public class User {<br> private int id;<br> private String name;<br> private String pwd;<br><br>}
复制代码 上面的代码等于下面的代码- package com.zeng.mybatis.pojo;<br><br>public class User {<br> private int id;<br> private String name;<br> private String password;<br><br> public User() {<br> }<br><br> public User(int id, String name, String password) {<br> this.id = id;<br> this.name = name;<br> this.password = password;<br> }<br><br> public int getId() {<br> return id;<br> }<br><br> public void setId(int id) {<br> this.id = id;<br> }<br><br> public String getName() {<br> return name;<br> }<br><br> public void setName(String name) {<br> this.name = name;<br> }<br><br> public String getPassword() {<br> return password;<br> }<br><br> public void setPassword(String pwd) {<br> this.password = pwd;<br> }<br><br> @Override<br> public String toString() {<br> return "User{" +<br> "id=" + id +<br> ", name='" + name + '\'' +<br> ", pwd='" + password + '\'' +<br> '}';<br> }<br>}
复制代码 十、多表查询
1、多对一
1、第一种方式
1、实体类
- package com.zeng.mybatis.pojo;<br><br>import lombok.Data;<br><br>@Data<br>public class Student {<br> private int id;<br> private String name;<br> private Teacher teacher;<br>}
复制代码- package com.zeng.mybatis.pojo;<br><br>import lombok.Data;<br><br>@Data<br>public class Teacher {<br> private int id;<br> private String name;<br>}
复制代码
2、接口
- package com.zeng.mybatis.dao;<br><br>import com.zeng.mybatis.pojo.Student;<br><br>import java.util.List;<br><br>public interface studentMapper {<br> public List<Student> getStudent();<br>}
复制代码- package com.zeng.mybatis.dao;<br><br>import com.zeng.mybatis.pojo.Teacher;<br><br>public interface teacherMapper {<br> public Teacher getTeacher(int id);<br>}
复制代码 3、核心配置文件
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties> <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
-
-
-
-
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 特别注意
mapper是映射接口的时候和mapper映射文件时的区别
接口映射时:
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
复制代码 mapper映射文件
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
复制代码 4、接口映射文件
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
- <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> select * from Student<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings><settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> select * from teacher where id = #{id}<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 5、测试类
- @Test<br> public void getStudentList(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> studentMapper mapper = sqlSession.getMapper(studentMapper.class);<br> List<Student> student = mapper.getStudent();<br> for (Student s : student) {<br> System.out.println(s);<br> }<br> sqlSession.close();<br> }
复制代码 2、按照结果嵌套查询
1、接口
- public List<Student> getStudent2();
复制代码 2、接口映射文件
- select s.id sid,s.name sname,t.name tname from student s,teacher t where s.tid = t.id<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 3、测试类
- @Test<br> public void getStudentList2(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> studentMapper mapper = sqlSession.getMapper(studentMapper.class);<br> List<Student> studentList = mapper.getStudent2();<br> for (Student student : studentList) {<br> System.out.println(student);<br> }<br> sqlSession.close();<br> }
复制代码
1、一对多
1、联合查询ResultMap映射
1、实体类
教师类- package com.mybatis.pojo;<br><br>import java.util.List;<br>public class teacher {<br> private int id;<br> private String name;<br> private List<student> students;<br><br> public teacher() {<br> }<br><br> public teacher(int id, String name, List<student> students) {<br> this.id = id;<br> this.name = name;<br> this.students = students;<br> }<br><br> public int getId() {<br> return id;<br> }<br><br> public void setId(int id) {<br> this.id = id;<br> }<br><br> public String getName() {<br> return name;<br> }<br><br> public void setName(String name) {<br> this.name = name;<br> }<br><br> public List<student> getStudents() {<br> return students;<br> }<br><br> public void setStudents(List<student> students) {<br> this.students = students;<br> }<br><br> @Override<br> public String toString() {<br> return "teacher{" +<br> "id=" + id +<br> ", name='" + name + '\'' +<br> ", students=" + students +<br> '}';<br> }<br>}
复制代码 学生类- package com.mybatis.pojo;<br><br>public class student {<br> private int id;<br> private String name;<br> private int tid;<br><br> public student() {<br> }<br><br> public student(int id, String name, int tid) {<br> this.id = id;<br> this.name = name;<br> this.tid = tid;<br> }<br><br> public int getId() {<br> return id;<br> }<br><br> public void setId(int id) {<br> this.id = id;<br> }<br><br> public String getName() {<br> return name;<br> }<br><br> public void setName(String name) {<br> this.name = name;<br> }<br><br> public int getTid() {<br> return tid;<br> }<br><br> public void setTid(int tid) {<br> this.tid = tid;<br> }<br><br> @Override<br> public String toString() {<br> return "student{" +<br> "id=" + id +<br> ", name='" + name + '\'' +<br> ", tid=" + tid +<br> '}';<br> }<br>}
复制代码 2、接口
教师接口- package com.mybatis.dao;<br><br>import com.mybatis.pojo.teacher;<br>import org.apache.ibatis.annotations.Param;<br><br>import java.util.List;<br><br>public interface teacherMapper {<br> public List<teacher> getAllTS(@Param("stid") int sid);<br>}
复制代码 学生接口- package com.mybatis.dao;<br><br>import com.mybatis.pojo.student;<br><br>import java.util.List;<br><br>public interface studentMapper {<br> public List<student> getStudent();<br>}
复制代码 3、核心配置文件
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
-
-
-
-
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 接口映射文件
teacherMapper- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings><settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> select t.id tis,t.name tname,s.id sid,s.name sname from teacher t,student s where t.id = s.tid and t.id = #{stid}<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 4、测试类
- @org.junit.Test<br> public void getAllTS(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> teacherMapper mapper = sqlSession.getMapper(teacherMapper.class);<br> List<teacher> allTS = mapper.getAllTS(1);<br> for (teacher teacher : allTS) {<br> System.out.println(teacher);<br> }<br> sqlSession.close();<br> }
复制代码
2、子查询映射
1、接口
- List<teacher> getTeacherS(@Param("tid") int tid);
复制代码 2、接口映射文件
- select * from teacher where id=#{tid}<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings><settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> select * from student where tid=#{tid}
-
复制代码 3、测试类
- @org.junit.Test<br> public void getTeacherS(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> teacherMapper mapper = sqlSession.getMapper(teacherMapper.class);<br> List<teacher> teachers = mapper.getTeacherS(1);<br> for (teacher teacher : teachers) {<br> System.out.println(teacher);<br> }<br> sqlSession.close();<br> }
复制代码
十一、动态SQL
1、动态SQL环境搭建
1、创建数据库
- CREATE TABLE `blog` (<br>`id` VARCHAR(50) NOT NULL COMMENT '博客id',<br>`title` VARCHAR(100) NOT NULL COMMENT '博客标题',<br>`author` VARCHAR(30) NOT NULL COMMENT '博客作者',<br>`create_time` DATETIME NOT NULL COMMENT '创建时间',<br>`views` INT(30) NOT NULL COMMENT '浏览量'<br>)ENGINE=INNODB DEFAULT CHARSET=utf8;`blog`
复制代码 2、创建实体类
- package com.zeng.mybatis.pojo;<br><br>import lombok.Data;<br><br>import java.util.Date;<br>@Data<br>public class Blog {<br> private String id;<br> private String title;<br> private String author;<br> private Date create_time;<br> private int views;<br>}
复制代码 3、db.properties
- driver=com.mysql.jdbc.Driver<br>jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=UTC&useSSL=false<br>username=root<br>password=12345678
复制代码 4、mybatis-config.xml
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> <settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
-
-
-
-
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 5、工具类MybatisUtil
- package com.zeng.mybatis.utils;
- 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;
- public class MybatisUtils {
- public static SqlSessionFactory sqlSessionFactory;
- static {
- try {
- String resource = "mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- } catch (IOException e) {
- e.printStackTrace();
- }<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties> }
- public static SqlSession getSqlSession(){
- return sqlSessionFactory.openSession(true);
- }
- }
复制代码 6、生成ID工具类IDUtil
- package com.zeng.mybatis.utils;<br><br>import java.util.UUID;<br><br>public class IDUtil {<br> public static String getId(){<br> return UUID.randomUUID().toString().replaceAll("-","");<br> }<br>}
复制代码 7、接口- package com.zeng.mybatis.dao;<br><br>import com.zeng.mybatis.pojo.Blog;<br><br>import java.util.List;<br><br>public interface BlogMapper {<br> int addBlog(Blog blog);<br><br>}
复制代码 8、接口映射
- <properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties><settings><br> <setting name="logImpl" value="LOG4J"/><br></settings> insert into blog (id,title,author,create_time,views) values (#{id},#{title},#{author},#{create_time},#{views})<settings><br> <setting name="logImpl" value="LOG4J"/><br></settings>
复制代码 9、生成数据
- package com.zeng.mybatis.dao;<br><br>import com.zeng.mybatis.pojo.Blog;<br>import com.zeng.mybatis.utils.IDUtil;<br>import com.zeng.mybatis.utils.MybatisUtils;<br>import org.apache.ibatis.session.SqlSession;<br><br>import java.util.Date;<br><br>public class Test {<br> @org.junit.Test<br> public void addtest(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> Blog blog = new Blog();<br> blog.setId(IDUtil.getId());<br> blog.setTitle("Mybatis学习");<br> blog.setAuthor("曾老师");<br> blog.setCreate_time(new Date());<br> blog.setViews(9000);<br> mapper.addBlog(blog);<br><br> Blog blog1 = new Blog();<br> blog1.setId(IDUtil.getId());<br> blog1.setTitle("java学习");<br> blog1.setAuthor("曾老师");<br> blog1.setCreate_time(new Date());<br> blog1.setViews(8000);<br> mapper.addBlog(blog1);<br><br> Blog blog2 = new Blog();<br> blog2.setId(IDUtil.getId());<br> blog2.setTitle("javaWeb学习");<br> blog2.setAuthor("曾老师");<br> blog2.setCreate_time(new Date());<br> blog2.setViews(100000);<br> mapper.addBlog(blog2);<br><br> Blog blog3 = new Blog();<br> blog3.setId(IDUtil.getId());<br> blog3.setTitle("单片机");<br> blog3.setAuthor("曾老师");<br> blog3.setCreate_time(new Date());<br> blog3.setViews(4000);<br> mapper.addBlog(blog3);<br><br> Blog blog4 = new Blog();<br> blog4.setId(IDUtil.getId());<br> blog4.setTitle("人工智能学习");<br> blog4.setAuthor("曾老师");<br> blog4.setCreate_time(new Date());<br> blog4.setViews(500);<br> mapper.addBlog(blog4);<br><br> Blog blog5 = new Blog();<br> blog5.setId(IDUtil.getId());<br> blog5.setTitle("大数据");<br> blog5.setAuthor("曾老师");<br> blog5.setCreate_time(new Date());<br> blog5.setViews(1500);<br> mapper.addBlog(blog5);<br> sqlSession.close();<br> }<br>}
复制代码 2、IF标签
1、接口
- List<Blog> getBlogIF(Map map);
复制代码 2、接口映射
- select * from blog where 1=1<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> and title = #{title}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 3、测试类
- @org.junit.Test<br> public void getBlogIF(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> HashMap map = new HashMap<>();<br> map.put("title","单片机");<br> List<Blog> blogs = mapper.getBlogIF(map);<br> for (Blog blog : blogs) {<br> System.out.println(blog);<br> }<br> sqlSession.close();<br> }
复制代码
3、choose(when、otherwise)
1、接口
- List<Blog> getBlogChoose(Map map);
复制代码 2、接口映射
- select * from blog where 1=1
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> and title = #{title}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- and author = #{author}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- and views >= #{views}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
复制代码 3、测试类
- @org.junit.Test<br> public void getBlogChoose(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> HashMap Map = new HashMap<>();<br> Map.put("author","曾老师");<br> Map.put("views",8000);<br> List<Blog> blogs = mapper.getBlogChoose(Map);<br> for (Blog blog : blogs) {<br> System.out.println(blog);<br> }<br> sqlSession.close();<br> }
复制代码
4、trim(where、set)
1、where
1、接口
- List<Blog> getBlogWhere(Map map);
复制代码 2、接口映射
- select * from blog<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
- title = #{title}
-
-
- and author = #{author}
-
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 3、测试类
- @org.junit.Test<br> public void getBlogWhere(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> HashMap map = new HashMap<>();<br> map.put("title","人工智能学习");<br> List<Blog> blogs = mapper.getBlogWhere(map);<br> for (Blog blog : blogs) {<br> System.out.println(blog);<br> }<br> sqlSession.close();<br> }
复制代码
2、set
1、接口
- int modifyBlogSet(Map map);
复制代码
2、接口映射
- update blog
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> title = #{title},<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- author = #{author}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings> id = #{id}<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
复制代码
3、测试类
- @org.junit.Test<br> public void modifyBlog(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> HashMap map = new HashMap<>();<br> map.put("id","49aa2e7503434b86a33c527cf520e6a9");<br> map.put("title","单片机1");<br> map.put("author","超级大帅哥");<br> mapper.modifyBlogSet(map);<br> sqlSession.close();<br> }
复制代码
3、trim
1、接口
- List<Blog> getBlogTrim(Map map);
复制代码 2、接口映射
- select * from blog<settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
- title = #{title}
-
-
- and author = #{author}
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
复制代码 3、测试
- @org.junit.Test<br> public void getBlogTrim(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);<br> HashMap map = new HashMap<>();<br> map.put("title","单片机1");<br> map.put("author","超级大帅哥");<br> List<Blog> blogs = mapper.getBlogTrim(map);<br> for (Blog blog : blogs) {<br> System.out.println(blog);<br> }<br> sqlSession.close();<br> }
复制代码
十二、缓存
1、缓存简介
缓存(cache),原始意义是指访问速度比一般随机存取存储器(RAM)快的一种高速存储器,通常它不像系统主存那样使用DRAM技术,而使用昂贵但较快速的SRAM技术。缓存的设置是所有现代计算机系统发挥高性能的重要因素之一。
1、什么是缓存?
存在内存中的临时数据
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题
2、为什么使用缓存?
减少和数据库的交互次数,减少系统开销,提高系统效率
3、什么样的数据能使用缓存?
经常查询并且不经常改变的数据
2、一级缓存
一级缓存也叫本地缓存:Sqlsession
与数据库同一次会话期间查询到的数据会放在本地缓存中
以后如果需要获取相同的数据,直接从缓存中拿,没必要再去查询数据库
测试步骤:
1、开启日志!
导入log4j依赖- <dependency><br> <groupId>log4j</groupId><br> <artifactId>log4j</artifactId><br> <version>1.2.12</version><br> <scope>test</scope><br> </dependency>
复制代码 配置日志文件- log4j.rootLogger=DEBUG,console,file<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>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<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>log4j.appender.file = org.apache.log4j.RollingFileAppender
- log4j.appender.file.File=./log/logFile.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<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties>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
复制代码 2、测试在一个Session中查询两次相同记录
- @Test<br>public void getUserById(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> userMapper mapper = sqlSession.getMapper(userMapper.class);<br> user user = mapper.getUserById(1);<br> System.out.println(user);<br> System.out.println("<==========================================================>");<br> user user2 = mapper.getUserById(1);<br> System.out.println(user2);<br> sqlSession.close();<br>}
复制代码 3、查看日志输出

可以清楚的看见只运行了一次sql语句
缓存失效的情况:
1、查询不同的东西
这里分别查询id为1和2的两条记录- @Test<br> public void getUserById(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> userMapper mapper = sqlSession.getMapper(userMapper.class);<br> user user = mapper.getUserById(1);<br> System.out.println(user);<br> System.out.println("<==========================================================>");<br> user user2 = mapper.getUserById(2);<br> System.out.println(user2);<br> sqlSession.close();<br> }
复制代码
这里可以看见运行了两次sql语句
2、增删改操作,可能会改变原来的数据,所以必定会刷新缓存!
这里我们更改了第一条记录,并且对id为1的记录查询两次- @Test<br>public void getUserById(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> userMapper mapper = sqlSession.getMapper(userMapper.class);<br> user user = mapper.getUserById(1);<br> System.out.println(user);<br> System.out.println("<==========================================================>");<br> user setUser = new user();<br> setUser.setId(1);<br> setUser.setName("张三(改)");<br> setUser.setPwd("8520");<br> mapper.updateUser(setUser);<br> System.out.println("<==========================================================>");<br> user user1 = mapper.getUserById(1);<br> System.out.println(user1);<br> sqlSession.close();<br>}
复制代码
这里可以清楚的看见在第一次查询过后,对记录进行更改,然后再次查询也会再执行一次sql语句,所以我们在执行增删改的时候会更新数据,因此会重新连接查询
3、查询不同的Mapper.xml
4、手动清除缓存
这里我们使用clearCache()方法来手动清除缓存- @Test<br>public void getUserById(){<br> SqlSession sqlSession = MybatisUtils.getSqlSession();<br> userMapper mapper = sqlSession.getMapper(userMapper.class);<br> user user = mapper.getUserById(1);<br> System.out.println(user);<br> System.out.println("<==========================================================>");<br> sqlSession.clearCache();//手动清楚缓存<br> user user1 = mapper.getUserById(1);<br> System.out.println(user1);<br> sqlSession.close();<br>}
复制代码
这里我们可以看到在使用clearCache()方法,手动清除缓存后就会对数据就行第二次连接查询
3、二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低,所以诞生了二级缓存
基于namespace级别的缓存,一个名称空间,对应一个二级缓存
工作机制
一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据会被保存到二级缓存中;
新的会话查询信息,就可以从二级缓存中获取内容;
不同的mapper查出的数据会放在自己对应的缓存(map)中
步骤:
1、开启全局缓存
- <settings><br> <setting name="logImpl" value="STDOUT_LOGGING"/><br> </settings>
-
复制代码 2、在要使用二级缓存的Mapper中开启
- [/code]直接加一个标签就可以开启二级缓存了
- [code]
复制代码 当然里面可以配置各种参数,参数可以自行配置
3、测试
- @Test
- public void getUserById(){
- SqlSession sqlSession = MybatisUtils.getSqlSession();
- SqlSession sqlSession2 = MybatisUtils.getSqlSession();
- userMapper mapper = sqlSession.getMapper(userMapper.class);
- user user = mapper.getUserById(2);
- System.out.println(user);
- sqlSession.close();
- System.out.println("");
- userMapper mapper2 = sqlSession2.getMapper(userMapper.class);
- user user1 = mapper2.getUserById(2);
- System.out.println(user1);<properties resource="org/mybatis/example/config.properties"><br><property name="username" value="dev_user"/><br><property name="password" value="F2Fa3!33TYyg"/><br></properties> sqlSession2.close();
- }
复制代码 问题- org.apache.ibatis.cache.CacheException: Error serializing object. Cause: java.io.NotSerializableException: com.mybatis.pojo.user
复制代码 没有参数就要序列化实体类

可以看出在会话一关闭后,数据就存入了二级缓存,所有第二次查询相同数据的时候没有走数据库,而是直接在二级缓存中取出
只要开启了二级缓存,在同一个Mapper下就有效
所有的数据都会先放在一级缓存中;
只有当会话提交,或者关闭的时候,才会提交到二级缓冲中!
4、缓存原理
一级缓存是SqlSession级别的缓存,默认开启。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
二级缓存是mapper级别的缓存,基于mapper文件的namespace,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

一级缓存先在数据库中查询数据,然后存入二级缓存中,如果二级缓存中没有再从数据库中查找
5、Ehcahe
什么是EhCache?
EhCache 是一个纯Java的进程内缓存框架,具有快速、精干等特点,是Hibernate中默认的CacheProvider。他和mybatis当中的二级缓存唯一的区别就是,他是存储于硬盘当中的,也就是他是可以用来做分布式缓存的。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |