备注:官方文档
本篇文章通过:b站的狂神说进行学习
第一个程序(简单的实现增删改查):
工程目录
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9urGmvHF-1602072233304)(F:/文档/typora文档/mybatis/img/屏幕截图 2020-09-25 090027.jpg)]
代码
配置文件
<?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"> <!-- 定义环境id--> <environment id="development"> <!-- 事务管理器的配置 JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。 MANAGED(了解) – 这个配置几乎没做什么。(过时了没有)--> <transactionManager type="JDBC"/> <!-- 数据源的配置 UNPOOLED(了解)– 这个数据源的实现会每次请求时打开和关闭连接。(没有池的概念) POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间 备注:数据连接池就是用完可以回收 JNDI(了解) – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--映射器--> <mappers> <mapper resource="com/minjiang/UserMapper.xml"/> </mappers> </configuration>接口
public interface UserMapper { /**查询所有 * * @return */ public List<User> selectAll(); /** * 条件查询 * @param id * @return */ public User selectById(int id); /** * 增加用户 * @param user * @return */ public int addUser(User user); /** * 修改用户 * @param usr * @return */ public int updateUser(User usr); /** * 根据id删除用户 * @param id * @return */ public int deleteUser(int id); } 实体类 public class User { private int id; private String name; private String pwd; public User(){ } public User(int id, String name, String pwd){ this.id = id; this.name = name; this.pwd =pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } } 工具类 /** * 工具类: * 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的 */ public class MybatisUtils { private static String resource = "mybatis-config.xml"; /** * 保证只有一个 */ private static InputStream inputStream; private static SqlSessionFactory sqlSessionFactory; /** * 保证可以直接调用,静态代码块只能用静态类 */ static { try { inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } /**SqlSessionFactory,可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法 * * @return */ public static SqlSession getSession(){ SqlSession session = sqlSessionFactory.openSession(); return session; } } 映射文件 <?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.minjiang.mapper.UserMapper"> <select id="selectAll" resultType="com.minjiang.projo.User"> select * from mybatis.user </select> <select id="selectById" resultType="com.minjiang.projo.User" parameterType="com.minjiang.projo.User"> select * from mybatis.user where id = #{id} </select> <insert id="addUser" parameterType="com.minjiang.projo.User"> insert into mybatis.user value (#{id}, #{name}, #{pwd}) </insert> <update id="updateUser" parameterType="com.minjiang.projo.User"> update mybatis.user set name = #{name}, pwd = #{pwd} where id = #{id} </update> <delete id="deleteUser" parameterType="com.minjiang.projo.User"> delete from mybatis.user where id = #{id} </delete> </mapper> 测试文件 public class MyBtaisTest { SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); @Test public void selectAllTest(){ // 方法1 // List<User> users = session.selectList("com.minjiang.mapper.UserMapper.selectAll"); //方法2(推荐) List<User> users = mapper.selectAll(); for (User user : users){ System.out.println(user); } session.close(); } @Test public void selectById(){ User user =mapper.selectById(1); System.out.println(user); session.close(); } @Test public void addUser(){ int i = mapper.addUser(new User(5, "小红", "456")); if (i > 0){ System.out.println("添加成功"); } //提交事务 session.commit(); session.close(); } @Test public void updateUser(){ User user = mapper.selectById(3); user.setName("小黑"); int i = mapper.updateUser(user); if (i > 0){ System.out.println("修改成功"); } //提交事务 session.commit(); session.close(); } @Test public void deleteUser(){ int i =mapper.deleteUser(5); if (i > 0){ System.out.println("删除成功"); } //提交事务 session.commit(); session.close(); } }注意点:
增删改操作都需要提交事务
备注:可以给用于参数过多使用,当然一直使用这种方式是极好的
查询方法
接口:
/** * 直接通过键值对的方式(这里的对象名可以随意取) * 参数直接传Map * @param map * @return */ public User selectUserByNP2(Map<String,Object> map);映射文件:
<!-- 传递参数为map--> <select id="selectUserByNP2" resultType="com.minjiang.projo.User" parameterType="map"> select * from user where name = #{username} and pwd = #{password} </select>测试文件:
@Test public void selectUserByNP2(){ //创建一个会话 SqlSession session = MybatisUtils.getSession(); //通过会话创获取一个mapper(映射)对象 UserMapper mapper = session.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String, Object>(); map.put("username","小白"); map.put("password","456"); //映射文件中中包含着映射出来的方法 User user = mapper.selectUserByNP2(map); System.out.println(user); //提交事务 session.commit(); //关闭事务 session.close(); }添加方法
接口
/** * 通过键值对进行增加 */ public int addUserByNP2(Map<String,Object> map);映射文件
测试
@Test public void addUserByNP2(){ //创建一个会话 SqlSession session = MybatisUtils.getSession(); //通过会话创获取一个mapper(映射)对象 UserMapper mapper = session.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String, Object>(); map.put("id",3); map.put("userName","红蓝CP"); int i = mapper.addUserByNP2(map); if (i > 0){ System.out.println("添加成功"); } //提交事务 session.commit(); //关闭事务 session.close(); } <!-- 传递参数为map--> <insert id="addUserByNP2" parameterType="map"> insert into user(id,name) value (#{id},#{userName}) </insert>好处:
无需要去改动实体类的东西,提高了效率
配置展示(备注:这也是mybaits的核心配置文件)
<?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"> <!-- 定义环境id--> <environment id="development"> <!-- 事务管理器的配置 JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。 MANAGED(了解) – 这个配置几乎没做什么。(过时了没有)--> <transactionManager type="JDBC"/> <!-- 数据源的配置 UNPOOLED(了解)– 这个数据源的实现会每次请求时打开和关闭连接。(没有池的概念) POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间 备注:数据连接池就是用完可以回收 JNDI(了解) – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,--> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!--映射器--> <mappers> <mapper resource="com/minjiang/UserMapper.xml"/> </mappers> </configuration>MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
configuration(配置) properties(属性)settings(设置)typeAliases(类型别名)typeHandlers(类型处理器)objectFactory(对象工厂)plugins(插件)environments(环境配置) environment(环境变量) transactionManager(事务管理器)dataSource(数据源) databaseIdProvider(数据库厂商标识)mappers(映射器)重点:注意配置文档的顶层结构顺序,顺序不对会报错
mybatis可以配置成适应多种环境
<!-- 默认使用环境--> <environments default="development"> <!-- 定义环境(development)--> <environment id="development"...> </environment> <environment id="test"...> </environment> </environments>切换成不同的环境
<!-- 默认使用环境,可以用于切换,切换成相对应的id就可以了--> <environments default="development">另一种配置方式(配置文件的改变==》请根据配置文档的顶层结构顺序配置):
<properties> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value=" jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8"/> <property name="userName" value="root"/> <property name="password" value="root"/> </properties> <dataSource type="POOLED"> <!-- 可以使用${XXX}进行调用--> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${userName}"/> <property name="password" value="${password}"/> </dataSource>备注:详细看官方文档
简要概括要点:
事务管理器(transactionManager):JDBC、MANAGED(了解) JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作 MANAGED(了解) – 这个配置几乎没做什么。(过时了没有)数据源(dataSource):UNPOOLED(了解)、POOLED(关注点)、JNDI(了解)
UNPOOLED(了解)– 这个数据源的实现会每次请求时打开和关闭连接。(没有池的概念) POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间 备注:数据连接池就是用完可以回收 JNDI(了解) – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,
太多了。。。看官方文档吧(条件:只要有遵守文档的顶层结构顺序配置可以了)
mappers(映射器):定义SQL语句文件
映射文件文件的引用方法
方法1(推荐)
<!--映射器--> <mappers> <mapper resource="com/minjiang/UserMapper.xml"/> </mappers>方法2
<!--映射器--> <mappers> <!-- <mapper resource="com/minjiang/UserMapper.xml"/>--> <mapper class="com.minjiang.mapper.UserMapper"></mapper> </mappers> 注意点:用类去注册
映射文件和接口要放在同一目录下,同时文件要相同
方法3:
<!--映射器--> <mappers> <!-- <mapper resource="com/minjiang/UserMapper.xml"/>--> <package name="com.minjiang.mapper"/> </mappers> 注意点:用类去注册
映射文件和接口要放在同一目录下,同时文件要相同
标注:typeHandlers(类型处理器),objectFactory(对象工厂),plugins(插件)==》推荐(mybatis-Plus)了解即可
可以通过引入外部配置简化外部文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MudAE6Ka-1602072233306)(img/屏幕截图 2020-09-25 152515.jpg)]
外部文件:
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=utf8 userName = root password = root配置文件的改变(请根据配置文档的顶层结构顺序配置):
<!--导入文件properties配置文件--> <properties resource="db.properties"></properties> <dataSource type="POOLED"> <!-- 在导入外部文件后,可以使用${XXX}进行调用--> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${userName}"/> <property name="password" value="${password}"/> </dataSource>配置文件的改变(请根据配置文档的顶层结构顺序配置):
<!-- 类型别名--> <typeAliases> <typeAlias alias="user" type="com.minjiang.projo.User"></typeAlias> </typeAliases>映射文件的改变:
<select id="selectById" resultType="user" parameterType="user"> select * from mybatis.user where id = #{id} </select>简介:
强调!!!!resultMap 元素是 MyBatis 中最重要最强大的元素
1、resultMap 元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBC ResultSets 数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。
2、ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
带问题举例(java的实体类属性和数据库的字段不同)
public class User { private int id; private String name; //passWord和数据库的字段不同 private String passWord; public User() { } public User(int id, String name, String passWord) { this.id = id; this.name = name; this.passWord = passWord; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", passWord='" + passWord + '\'' + '}'; } }解决方法
1、在映射文件中的查询语句添加别名
<mapper namespace="com.minjiang.mapper.UserMapper"> <select id="selectAll" resultType="user"> select id, name, pwd as passWord from mybatis.user </select> </mapper>2、启用结果集映射(推荐)
<mapper namespace="com.minjiang.mapper.UserMapper"> <resultMap id="UserMap" type="user"> <!-- 设置主键--> <id column="id" property="id"></id> <!-- column是数据库表的列名 , property是对应实体类的属性名 --> <result column="name" property="name"></result> <!-- ===================================================================--> <!-- 熟悉之后,只要添加与数据库不同的部分就可以了(这就是自动手动的混合策略)--> <result column="pwd" property="passWord"></result> </resultMap> <select id="selectAll" resultMap="UserMap"> select * from mybatis.user </select> </mapper>在简单的场景下,MyBatis 可以为你自动映射查询结果。
在 ResultSet 出现的列,如果没有设置手动映射,将被自动映射。
<resultMap id="map" type="user"></resultMap> <select id="selectById" resultMap="map"> select * from mybatis.user where id=#{id} </select>但如果遇到复杂的场景,你需要构建一个结果映射。混合使用这两种策略
备注
无论设置的自动映射等级是哪种,你都可以通过在结果映射上设置 autoMapping 属性来为指定的结果映射设置启用/禁用自动映射(mybatis默认autoMapping 属性为true)。
<resultMap id="userResultMap" type="User" autoMapping="false"> <result property="password" column="hashed_password"/> </resultMap> 面对接口编程
根本原因 : 解耦 , 可拓展 , 提高复用 , 分层开发中 , 上层不用管具体的实现 , 大家都遵守共同的标准 , 使得开发变得容易 , 规范性更好
备注:maybatis提供的基于注解的的配置java注解的表达力和灵活性十分有限。mybatis映射并不能用注解来构建
sql 类型主要分成 :
@select ()@update ()@Insert ()@delete ()**注意:**利用注解开发就不需要mapper.xml映射文件了 .
运用注解的查询例子
1、添加接口方法
public interface UserMapper { @Select("select * from user") public List<User> selectAll(); }2、修改核心配置文件
<mappers> <mapper class="com.minjiang.mapper.UserMapper"></mapper> </mappers>3、测试文件
public class TestUserMapper { @Test public void selectAll(){ //获取会话 SqlSession session = MybatisUtils.getSession(); //获取映射文件 UserMapper mapper = session.getMapper(UserMapper.class); //通过映射文件调用方法 List<User> users = mapper.selectAll(); // 遍历得出结果 for(User user : users){ System.out.println(user); } } }作用:测试SQL的时候,有更快的排错效率
Mybatis 通过使用内置的日志工厂提供日志功能
SLF4JApache Commons LoggingLog4j 2Log4jJDK loggingMybatis会(按上面罗列的顺序)使用第一个查找到的实现。当没有找到这些实现时,将会禁用日志功能。
指定 MyBatis 应该使用哪个日志记录实现。如果此设置不存在,则会自动发现日志记录实现。
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>测试,可以看到控制台有大量的输出!我们可以通过这些输出来判断程序到底哪里出了Bug
备注
value可选的值有:SLF4J、LOG4J、LOG4J2、JDK_LOGGING、COMMONS_LOGGING、STDOUT_LOGGING、NO_LOGGING
简介:
Log4j是Apache的一个开源项目通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。1、导入依赖
<dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>2、配置文件编写
#将等级为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/kuang.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 #日志输出级别 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=DEBUG3、在Mybatis的核心配置文件中进行设置(注意:)
<!-- log4j日志输出--> <settings> <setting name="logImpl" value="LOG4J"/> </settings>4、测试:
public class TestUserMapper { //获取当前类的日志 Logger logger = Logger.getLogger(TestUserMapper.class); @Test public void selectAll(){ //可以有选择的输入一些提示信息 logger.info("info:进入selectUser方法"); logger.debug("debug:进入selectUser方法"); logger.error("error: 进入selectUser方法"); } }注意点:导包为org.apache.log4j.Logger
结果:不仅可以在控制台输出,还可以生成一个日志文件【看不到的可以尝试下重新启动软件或是重新生成下目录】
推荐官方文档讲的足够清除的了
重点掌握:if 语句、Where、Set、choose语句、SQL片段
SQL片段
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们需要将这些代码抽取出来,然后使用时直接调用。
提取SQL片段:
<sql id="if-title-author"> <if test="title != null"> title = #{title} </if> <if test="author != null"> and author = #{author} </if> </sql>引用SQL片段:
<select id="queryBlogIf" parameterType="map" resultType="blog"> select * from blog <where> <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace --> <include refid="if-title-author"></include> <!-- 在这里还可以引用其他的 sql 片段 --> </where> </select>注意:
①、最好基于 单表来定义 sql 片段,提高片段的可重用性
②、在 sql 片段中不要包括 where
缓存的认知
缓存定义:存在内存中的临时数据
缓存的目的:将经常查询的数据放在缓存中,用户不用从磁盘上(关系型数据库数据文件)查询
缓存的使用数据:经常查询并且不经常改变的数据。
备注:在mybatis中分为一级缓存和二级缓存
简介
与数据库同一次会话期间查询到的数据会放在本地缓存中(如果获取相同的数据,直接从缓存中拿,没必须再去查询数据库)(在mybatis中默认开启)
实体
public class User { private int id; private String name; private String pwd; public User(){ } public User(int id, String name, String pwd){ this.id = id; this.name = name; this.pwd =pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "com.minjiang.pojo.User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }接口
public interface UserMapper { /** * 条件查询 * @param id * @return */ public User selectById(@Param("id") int id); }映射文件
<?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.minjiang.mapper.UserMapper"> <select id="selectById" parameterType="_int" resultType="user"> select * from mybatis.user where id = #{id} </select> </mapper>工具类
public class MyBatisUtils { private static String resource = "mybatis-config.xml"; private static InputStream inputStream; private static SqlSessionFactory sqlSessionFactory; static { try { inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } public static SqlSession getSession(){ SqlSession session = sqlSessionFactory.openSession(); return session; } }测试
public class CacheTest02 { /** * 开启日志 * */ Logger logger = Logger.getLogger(CacheTest02.class); @Test public void selectById(){ SqlSession session = MyBatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); UserMapper mapper1 = session.getMapper(UserMapper.class); User user = mapper.selectById(1); User user1 = mapper1.selectById(1); System.out.println(user); System.out.println(user1); System.out.println(user == user1); //要记住关闭缓存,不然可能会无法使用 session.close(); } }结果
可以通过显示的日志发现查询语句只执行了一次
备注
默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
为便于以后的维护建议显性表示
1、sqlSession不同(每个sqlSession中的缓存相互独立)
2、sqlSession相同,你要的查询条件不同(缓存会进行刷新)
3、sqlSession相同,两次查询之间执行了增删改操作!(缓存会进行刷新)
4、sqlSession相同,手动清除一级缓存
清除一级缓存
SqlSession session = MybatisUtils.getSession(); session.clearCache();关闭缓存
SqlSession session = MybatisUtils.getSession(); session.close();简介
基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
工作机制
一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;新的会话查询信息,就可以从二级缓存中获取内容;不同的mapper查出的数据会放在自己对应的缓存(map)中;备注
默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件(只作用于一个映射文件)中添加一行:
<cache/>建议同时开启全局缓存 【mybatis-config.xml】(便于维护)
<setting name="cacheEnabled" value="true"/>1、开启全局缓存 【mybatis-config.xml】(官方文档规定)
<setting name="cacheEnabled" value="true"/>2、在映射文件中配置(只作用于一个映射文件)
<!-- 可通过Mybatis观看详细说明--> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>eviction可用的清除策略有:
LRU – 最近最少使用:移除最长时间不被使用的对象。FIFO – 先进先出:按对象进入缓存的顺序来移除它们。SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。flushInterval(刷新间隔)属性可以被设置为任意的正整数
size(引用数目)属性可以被设置为任意正整数
readOnly(只读)属性可以被设置为 true 或 false
条件:使用第三方缓存实现–EhCache:
步骤
1、导入依赖包
<!-- https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache --> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.1.0</version> </dependency>2、在SQL映射文件中填加
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>3、编写ehcache.xml文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <!-- diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下: user.home – 用户主目录 user.dir – 用户当前工作目录 java.io.tmpdir – 默认临时文件路径 --> <diskStore path="./tmpdir/Tmp_EhCache"/> <defaultCache eternal="false" maxElementsInMemory="10000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="259200" memoryStoreEvictionPolicy="LRU"/> <cache name="cloud_user" eternal="false" maxElementsInMemory="5000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" memoryStoreEvictionPolicy="LRU"/> <!-- defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。 --> <!-- name:缓存名称。 maxElementsInMemory:缓存最大数目 maxElementsOnDisk:硬盘最大缓存个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 overflowToDisk:是否保存到磁盘,当系统当机时 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。 FIFO,first in first out,这个是大家最熟的,先进先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。 --> </ehcache>改造MybatisUtils工具类的getSession( ) 方法,重载实现。
//获取SqlSession连接 public static SqlSession getSession(){ return getSession(true); //事务自动提交 } public static SqlSession getSession(boolean flag){ return sqlSessionFactory.openSession(flag); } overflowToDisk:是否保存到磁盘,当系统当机时 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。 FIFO,first in first out,这个是大家最熟的,先进先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。 LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。–>
```改造MybatisUtils工具类的getSession( ) 方法,重载实现。
//获取SqlSession连接 public static SqlSession getSession(){ return getSession(true); //事务自动提交 } public static SqlSession getSession(boolean flag){ return sqlSessionFactory.openSession(flag); }【注意】确保实体类和数据库字段对应