Mybatis

打印 上一主题 下一主题

主题 1068|帖子 1068|积分 3204

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
Mybatis

视频:2、第一个Mybatis程序_哔哩哔哩_bilibili
文档:狂神SSM教程- 专栏 -KuangStudy
   一.什么是Mybatis 

  1.什么是MyBatis



  • MyBatis 是一款良好的持久层框架
  • MyBatis 制止了几乎所有的 JDBC 代码和手动设置参数以及获取结果集的过程
  • MyBatis 可以利用简单的 XML 或注解来设置和映射原生信息,将接口和 Java 的 实体类 【Plain Old Java Objects,普通的 Java对象】映射成数据库中的记录。
  • MyBatis 本是apache的一个开源项目ibatis, 2010年这个项目由apache 迁徙到了google code,而且改名为MyBatis 。
  • 2013年11月迁徙到Github .
  • Mybatis官方文档 : http://www.mybatis.org/mybatis-3/zh/index.html
  • GitHub : GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java

2.持久化



  • 持久化是将程序数据在持久状态和瞬时状态间转换的机制。

    • 即把数据(如内存中的对象)生存到可永久生存的存储设备中(如磁盘)。持久化的重要应用是将内存中的对象存储在数据库中,或者存储在磁盘文件中、XML数据文件中等等。
    • JDBC就是一种持久化机制。文件IO也是一种持久化机制。
    • 在生存中 : 将鲜肉冷藏,吃的时候再解冻的方法也是。将水果做成罐头的方法也是。

  • 为什么需要持久化服务呢?那是由于内存本身的缺陷引起的

    • 内存断电后数据会丢失,但有一些对象是无论如何都不能丢失的,比如银行账号等,遗憾的是,人们还无法保证内存永不掉电。
    • 内存过于昂贵,与硬盘、光盘等外存相比,内存的代价要高2~3个数目级,而且维持本钱也高,至少需要不停供电吧。所以即使对象不需要永久生存,也会由于内存的容量限制不能不停呆在内存中,需要持久化来缓存到外存。


3.持久层



  • 什么是持久层?

    • 完成持久化工作的代码块 . ——> dao层 【DAO (Data Access Object) 数据访问对象】
    • 大多数环境下特别是企业级应用,数据持久化往往也就意味着将内存中的数据生存到磁盘上加以固化,而持久化的实现过程则大多通过各种关系数据库来完成。
    • 不外这里有一个字需要特别夸大,也就是所谓的“层”。对于应用系统而言,数据持久功能大多是必不可少的组成部门。也就是说,我们的系统中,已经自然的具备了“持久层”概念?大概是,但大概实际环境并非如此。之所以要独立出一个“持久层”的概念,而不是“持久模块”,“持久单位”,也就意味着,我们的系统架构中,应该有一个相对独立的逻辑层面,专著于数据持久化逻辑的实现.
    • 与系统其他部门相对而言,这个层面应该具有一个较为清楚和严酷的逻辑边界。 【说白了就是用来操纵数据库存在的!】




4.为什么需要Mybatis



  • Mybatis就是帮助程序猿将数据存入数据库中 , 和从数据库中取数据 .
  • 传统的jdbc操纵 , 有很多重复代码块 .比如 : 数据取出时的封装 , 数据库的建立毗连等等… , 通过框架可以淘汰重复代码,进步开辟效率 .
  • MyBatis 是一个半主动化的ORM框架 (Object Relationship Mapping) —>对象关系映射
  • 所有的事情,不消Mybatis依旧可以做到,只是用了它,所有实现会更加简单!技术没有高低之分,只有利用这个技术的人有高低之别
  • MyBatis的长处

    • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+设置几个sql映射文件就可以了,易于学习,易于利用,通过文档和源代码,可以比较完全的把握它的设计思路和实现。
    • 机动:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于同一管理和优化。通过sql语句可以满足操纵数据库的所有需求。
    • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清楚,更易维护,更易单位测试。sql和代码的分离,进步了可维护性。
    • 提供xml标签,支持编写动态sql。
    • …….


   二.第一个Mybatis程序 

  思路流程:搭建环境—>导入Mybatis—->编写代码—->测试 
1.搭建实验数据库 

  1. CREATE DATABASE `mybatis`;
  2. USE `mybatis`;
  3. DROP TABLE IF EXISTS `user`;
  4. CREATE TABLE `user` (
  5.   `id` int(20) NOT NULL PRIMARY KEY,
  6.   `name` varchar(30) DEFAULT NULL,
  7.   `pwd` varchar(30) DEFAULT NULL,
  8. ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  9. insert  into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),(2,'张三','abcdef'),(3,'李四','987654');
复制代码


2.导入Mybatis 

 Maven Repository: org.mybatis » mybatis » 3.5.6 (mvnrepository.com)
Maven Repository: mysql » mysql-connector-java (mvnrepository.com)
Maven Repository: junit » junit (mvnrepository.com)
 Maven Repository: org.projectlombok » lombok (mvnrepository.com)

 3.编写代码

创建一个普通的maven项目
设置pom.xml
  1.   <build>
  2.     <resources>
  3.       <resource>
  4.         <directory>src/main/java</directory>
  5.         <includes>
  6.           <include>**/*.properties</include>
  7.           <include>**/*.xml</include>
  8.         </includes>
  9.         <filtering>false</filtering>
  10.       </resource>
  11.       <resource>
  12.         <directory>src/main/resources</directory>
  13.         <includes>
  14.           <include>**/*.properties</include>
  15.           <include>**/*.xml</include>
  16.         </includes>
  17.         <filtering>false</filtering>
  18.       </resource>
  19.     </resources>
  20.   </build>
复制代码
在resource下编写MyBatis核心设置文件mybatis-config.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!--核心配置文件-->
  6. <configuration>
  7.    
  8.     <environments default="development">
  9.         <environment id="development">
  10.             <!--事务作用域和控制方式的事务管理器(TransactionManager)-->
  11.             <transactionManager type="JDBC"/>
  12.             <!--数据库连接实例的数据源(DataSource)-->
  13.             <dataSource type="POOLED">
  14.             <!--配置driver,url,username,password-->
  15.                 <property name="driver" value="com.mysql.jdbc.Driver"/>
  16.                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
  17.                 <property name="username" value="root"/>
  18.                 <property name="password" value="123456"/>
  19.             </dataSource>
  20.         </environment>
  21.     </environments>
  22.    
  23. </configuration>
复制代码
编写编写MyBatis工具类读取设置
  1. package com.utils;
  2. import org.apache.ibatis.io.Resources;
  3. import org.apache.ibatis.session.SqlSession;
  4. import org.apache.ibatis.session.SqlSessionFactory;
  5. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  6. import java.io.IOException;
  7. import java.io.InputStream;
  8. public class MybatisUtils {
  9.     private static SqlSessionFactory sqlSessionFactory;
  10.     static {
  11.         try {
  12.             // 从 XML 文件中构建 SqlSessionFactory 的实例
  13.             String resource = "mybatis-config.xml";
  14.             InputStream inputStream = Resources.getResourceAsStream(resource);
  15.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  16.         } catch (IOException e) {
  17.             e.printStackTrace();
  18.         }
  19.     }
  20.     //获取SqlSession连接
  21.     public static SqlSession getSession(){
  22.         return sqlSessionFactory.openSession();
  23.     }
  24. }
复制代码
 创建实体类
  1. package com.pojo;
  2. import lombok.AllArgsConstructor;
  3. import lombok.Data;
  4. import lombok.NoArgsConstructor;
  5. @Data
  6. @NoArgsConstructor
  7. @AllArgsConstructor
  8. public class User {
  9.     private int id;  //id
  10.     private String name;   //姓名
  11.     private String pwd;   //密码
  12. }
复制代码
编写Mapper接口类
  1. package com.dao;
  2. import com.pojo.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5.     List<User> selectUser();
  6. }
复制代码
编写Mapper.xml设置文件
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5.         <!--namespace绑定一个Dao/Mapper接口-->
  6. <mapper namespace="com.dao.UserMapper">
  7.         <!--select查询语句 id绑定接口方法 resultType是返回值类型,resultMap是返回值集合-->
  8.     <select id="selectUser" resultType="com.pojo.User">
  9.         select * from user
  10.     </select>
  11. </mapper>
复制代码
去MyBatis核心设置文件注册Mapper.xml设置文件
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!--核心配置文件-->
  6. <configuration>
  7.     <environments default="development">
  8.         <environment id="development">
  9.             <!--事务作用域和控制方式的事务管理器(TransactionManager)-->
  10.             <transactionManager type="JDBC"/>
  11.             <!--数据库连接实例的数据源(DataSource)-->
  12.             <dataSource type="POOLED">
  13.             <!--配置driver,url,username,password-->
  14.                 <property name="driver" value="com.mysql.jdbc.Driver"/>
  15.                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
  16.                 <property name="username" value="root"/>
  17.                 <property name="password" value="123456"/>
  18.             </dataSource>
  19.         </environment>
  20.     </environments>
  21.     <!--注册Mapper.xml配置文件-->
  22.     <mappers>
  23.         <mapper resource="com/dao/Mapper.xml"/>
  24.     </mappers>
  25. </configuration>
复制代码
编写测试类
  1. package com.dao;
  2. import com.pojo.User;
  3. import com.utils.MybatisUtils;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.junit.Test;
  6. import java.util.List;
  7. public class UserMapperTest {
  8.     @Test
  9.     public void selectUser(){
  10.         // 获取SqlSession
  11.         SqlSession session = MybatisUtils.getSession();
  12.         // getMapper()
  13.         // List<User> users = session.selectList("com.dao.mapper.UserMapper.selectUser");老方式
  14.         UserMapper userMapper = session.getMapper(UserMapper.class);
  15.         List<User> users = userMapper.selectUser();
  16.         for (User user: users) {
  17.             System.out.println(user);
  18.         }
  19.         // 关闭SqlSession
  20.         session.close();
  21.     }
  22. }
复制代码

 改善
  1. package com.dao;
  2. import com.pojo.User;
  3. import com.utils.MybatisUtils;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.junit.Test;
  6. import java.util.List;
  7. public class UserMapperTest {
  8.     @Test
  9.     public void selectUser(){
  10.         // 获取SqlSession
  11.         SqlSession session = MybatisUtils.getSession();
  12.         try {
  13.             // getMapper()
  14.             // List<User> users = session.selectList("com.dao.mapper.UserMapper.selectUser");老方式
  15.             UserMapper userMapper = session.getMapper(UserMapper.class);
  16.             List<User> users = userMapper.selectUser();
  17.             for (User user: users) {
  18.                 System.out.println(user);
  19.             }
  20.         } catch (Exception e) {
  21.             throw new RuntimeException(e);
  22.         } finally {
  23.             // 关闭SqlSession
  24.             session.close();
  25.         }
  26.     }
  27. }
复制代码

4.错误 

1. java.lang.NoClassDefFoundError: org/hamcrest/SelfDescribing
导入以下结包Maven Repository: org.hamcrest » hamcrest » 2.2 (mvnrepository.com) 

2.org.apache.ibatis.binding.BindingException: Type interface com.Dao.UserMapper is not known to the MapperRegistry.
去MyBatis核心设置文件注册Mapper.xml设置文件

   三.CRUD操纵 

   1.查找

(1).id查询 
  1. package com.dao;
  2. import com.pojo.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5.     //查询全部用户
  6.     List<User> selectUser();
  7.     //根据id查询用户
  8.     User selectUserById(int id);
  9. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5.         <!--namespace绑定一个Dao/Mapper接口-->
  6. <mapper namespace="com.dao.UserMapper">
  7.         <!--select查询语句 id绑定接口方法 resultType是返回值类型,resultMap是返回值集合-->
  8.     <select id="selectUser" resultType="com.pojo.User">
  9.         select * from user
  10.     </select>
  11.         <!--parameterType参数类型-->
  12.     <select id="selectUserById" parameterType="int" resultType="com.pojo.User">            
  13.         <!--#{id}获取id-->
  14.         select * from user where id = #{id}
  15.     </select>
  16. </mapper>
复制代码
  1.     @Test
  2.     public void selectUserById() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         UserMapper userMapper = session.getMapper(UserMapper.class);
  5.         User user = userMapper.selectUserById(1);
  6.         try {
  7.             System.out.println(user);
  8.         } catch (Exception e) {
  9.             throw new RuntimeException(e);
  10.         } finally {
  11.             session.close();
  12.         }
  13.     }
复制代码
(2).模糊查询,两种方式
第1种:在Java代码中添加sql通配符。
  1.    SqlSession session = MybatisUtils.getSession();
  2.    UserMapper userMapper = session.getMapper(UserMapper.class);
  3.    User user = userMapper.selectUserName("%李%);
复制代码
第2种:在sql语句中拼接通配符,会引起sql注入 
  1.         <!--parameterType参数类型-->
  2.     <select id="selectUserById" parameterType="String" resultType="com.pojo.User">
  3.         select * from user where name like "%"#{name}"%";
  4.     </select>
复制代码

2. 增删改

 

  1. package com.dao;
  2. import com.pojo.User;
  3. import java.util.List;
  4. public interface UserMapper {
  5.     //查询全部用户
  6.     List<User> selectUser();
  7.     //根据id查询用户
  8.     User selectUserById(int id);
  9.     // 添加用户
  10.     int addUser(User user);
  11.     // 删除用户
  12.     int deleteUser(int id);
  13.     // 更改用户
  14.     int updateUser(User user);
  15. }
复制代码
 Mapper.xml
  1. <!--添加返回值类型可以不写-->
  2.     <insert id="addUser" parameterType="com.pojo.User" >
  3. --         对象中的属性可以直接取出
  4.         insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
  5.     </insert>
  6.    
  7.     <delete id="deleteUser" parameterType="int">
  8.         delete from user where id = #{id}
  9.     </delete>
  10.     <update id="updateUser" parameterType="com.pojo.User">
  11.         update user set pwd = #{pwd} where id = #{id}
  12.     </update>
复制代码
  1.     @Test
  2.     public void addUser() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         UserMapper userMapper = session.getMapper(UserMapper.class);
  5.         int add = userMapper.addUser(new User(4,"lisa","452423423"));
  6.         if(add > 0) {
  7.             System.out.println("添加成功");
  8.         }
  9.         // 增删改需要提交事务
  10.         session.commit();
  11.         session.close();
  12.     }
  13.     @Test
  14.     public void deleteUser() {
  15.         SqlSession session = MybatisUtils.getSession();
  16.         UserMapper userMapper = session.getMapper(UserMapper.class);
  17.         int delete = userMapper.deleteUser(1);
  18.         if(delete > 0) {
  19.             System.out.println("删除成功");
  20.         }
  21.         session.commit();
  22.         session.close();
  23.     }
  24.     @Test
  25.     public void updateUser() {
  26.         SqlSession session = MybatisUtils.getSession();
  27.         UserMapper userMapper = session.getMapper(UserMapper.class);
  28.         int update = userMapper.updateUser(new User(2,"张三","111111"));
  29.         if(update > 0) {
  30.             System.out.println("修改成功");
  31.         }
  32.         session.commit();
  33.         session.close();
  34.     }
复制代码


3.利用全能的Map 

假如参数过多,我们可以考虑直接利用Map实现,假如参数比较少,直接传递参数即可 
接口UserMapper
  1.     // 添加用户
  2.     int addUser(User user);
  3.     // 使用Map为参数,添加用户
  4.     int addUser2(Map<String,Object> map);
复制代码
 Mapper.xml
  1.          <!--添加返回值类型可以不写-->
  2.     <insert id="addUser" parameterType="com.pojo.User" >
  3.         <!--对象中的属性可以直接取出-->
  4.         insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
  5.     </insert>
  6.     <insert id="addUser2" parameterType="com.pojo.User" >
  7.            <!--这里的#{}对应的Map的键,使用可以随意写,不用对应实体类与数据库字段-->
  8.         insert into user (id,name,pwd) values (#{helloId},#{manehello},#{p})
  9.     </insert>
复制代码
测试
  1.   @Test
  2.     public void addUser() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         UserMapper userMapper = session.getMapper(UserMapper.class);
  5.         int add = userMapper.addUser(new User(4,"lisa","452423423"));
  6.         if(add > 0) {
  7.             System.out.println("添加成功");
  8.         }
  9.         // 增删改需要提交事务
  10.         session.commit();
  11.         session.close();
  12.     }
  13.     @Test
  14.     public void addUser2() {
  15.         SqlSession session = MybatisUtils.getSession();
  16.         try {
  17.             UserMapper userMapper = session.getMapper(UserMapper.class);
  18.             Map<String,Object> map = new HashMap<String, Object>();
  19.             // 对应Mapping配置的key,放入数据库字段对应的值
  20.             map.put("helloId",1);
  21.             map.put("manehello","you");
  22.             map.put("p","555555");
  23.             userMapper.addUser2(map);
  24.             // 增删改需要提交事务
  25.             session.commit();
  26.         } catch (Exception e) {
  27.             throw new RuntimeException(e);
  28.         } finally {
  29.             session.close();
  30.         }
  31.     }
复制代码



   四.MyBatis设置解析 

   1.解析核心设置文件mybatis-config.xml

  1. <!-- 注意元素节点的顺序!顺序不对会报错 -->
  2.     configuration(配置)
  3.     properties(属性)
  4.     settings(设置)
  5.     typeAliases(类型别名)
  6.     typeHandlers(类型处理器)
  7.     objectFactory(对象工厂)
  8.     plugins(插件)
  9.     environments(环境配置)
  10.         environment(环境变量)
  11.             transactionManager(事务管理器)
  12.             dataSource(数据源)
  13.     databaseIdProvider(数据库厂商标识)
  14.     mappers(映射器)
复制代码
注意元素节点的次序!次序不对会报错 


2.environments,properties

db.properties 
  1. driver = com.mysql.jdbc.Driver
  2. url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
  3. username = root
  4. password = 123456
复制代码
mybatis-config.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3.         PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <!--核心配置文件-->
  6. <configuration>
  7.     <!-- 引入配置文件,也可以使用property标签在properties标签中配置,优先顺序外先内后-->
  8. <properties resource="db.properties">
  9.     <property name="password" value="123456"/>
  10. </properties>
  11.     <!--
  12.     environments:环境配置
  13.     default:默认环境变量
  14.     这里默认的环境变量是development,也可以选择下面的text
  15.      -->
  16.     <environments default="development">
  17.         <!--
  18.         environment:环境变量
  19.         id:此环境变量的id是什么,这里的id是development
  20.         -->
  21.         <environment id="development">
  22.             <!--
  23.             TransactionManager:事务作用域和控制方式的事务管理器
  24.             type:类型,总共有两种type="[JDBC|MANAGED]"
  25.             1.JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
  26.             2.MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。
  27.               默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
  28.              -->
  29.             <transactionManager type="JDBC"/>
  30.             <!--
  31.             DataSource:数据库连接实例的数据源
  32.             type:类型,总共有三种 type="[UNPOOLED|POOLED|JNDI]"
  33.             1.UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接
  34.             2.POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。
  35.               这种处理方式很流行,能使并发 Web 应用快速响应请求。
  36.             3.JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。
  37.             -->
  38.             <dataSource type="POOLED">
  39.             <!--配置driver,url,username,password-->
  40.                 <property name="driver" value="${driver}"/>
  41.                 <property name="url" value="${url}"/>
  42.                 <property name="username" value="${username}"/>
  43.                 <property name="password" value="${password}"/>
  44.             </dataSource>
  45.         </environment>
  46.         <environment id="text">
  47.             <!--事务作用域和控制方式的事务管理器(TransactionManager)-->
  48.             <transactionManager type="JDBC"/>
  49.             <!--数据库连接实例的数据源(DataSource)-->
  50.             <dataSource type="POOLED">
  51.                 <!--配置driver,url,username,password-->
  52.                 <property name="driver" value="com.mysql.jdbc.Driver"/>
  53.                 <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
  54.                 <property name="username" value="root"/>
  55.                 <property name="password" value="123456"/>
  56.             </dataSource>
  57.         </environment>
  58.     </environments>
  59. </configuration>
复制代码


3.typeAliases(别名)

下面是刚才在UserMapper.xml设置的sql语句,其中resultType的返回值类型非常长,我们可以通过别名把它减短
  1. <select id="selectUser" resultType="com.pojo.User">
  2.         select * from user
  3. </select>
复制代码
在mybatis-config.xml中设置
方式一:
  1.     <typeAliases>
  2.         <typeAlias type="com.pojo.User" alias="user"/>
  3.     </typeAliases>
复制代码
方式二:
  1.   <typeAliases>
  2.         <!--默认为包名小写,如果要自定义可以在具体的实体类中加注解-->
  3.         <package name="com.pojo"/>
  4.    </typeAliases>
复制代码
  1. @Alias("user")
  2. public class User {
  3.     ...
  4. }
复制代码
 简化后的UserMapper.xml设置的sql语句
  1.      <select id="selectUser" resultType="user">
  2.         select * from user
  3.     </select>
复制代码

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的定名重复,采取了特殊的定名风格。
别名映射的类型_bytebyte_longlong_shortshort_intint_integerint_doubledouble_floatfloat_booleanbooleanstringStringbyteBytelongLongshortShortintIntegerintegerIntegerdoubleDoublefloatFloatbooleanBooleandateDatedecimalBigDecimalbigdecimalBigDecimalobjectObjectmapMaphashmapHashMaplistListarraylistArrayListcollectionCollectioniteratorIterator
 4.settings(设置)

  1. <settings>
  2.   <setting name="cacheEnabled" value="true"/>
  3.   <setting name="lazyLoadingEnabled" value="true"/>
  4.   <setting name="multipleResultSetsEnabled" value="true"/>
  5.   <setting name="useColumnLabel" value="true"/>
  6.   <setting name="useGeneratedKeys" value="false"/>
  7.   <setting name="autoMappingBehavior" value="PARTIAL"/>
  8.   <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  9.   <setting name="defaultExecutorType" value="SIMPLE"/>
  10.   <setting name="defaultStatementTimeout" value="25"/>
  11.   <setting name="defaultFetchSize" value="100"/>
  12.   <setting name="safeRowBoundsEnabled" value="false"/>
  13.   <setting name="mapUnderscoreToCamelCase" value="false"/>
  14.   <setting name="localCacheScope" value="SESSION"/>
  15.   <setting name="jdbcTypeForNull" value="OTHER"/>
  16.   <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
  17. </settings>
复制代码
只要记着下面三个 
cacheEnabled全局性地开启或关闭所有映射器设置文件中已设置的任何缓存。true | falsetrue
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。true | falsefalse
logImpl指定 MyBatis 所用日志的具体实现,未指定时将主动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING未设置


5. mappers(映射器)

 




6.别的 



  • typeHandlers(类型处理器)
  • objectFactory(对象工厂)
  • plugins(插件)

7.生命周期和作用域

明白我们现在已经讨论过的不同作用域和生命周期类是至关重要的,由于错误的利用会导致非常严重的并发问题 
  1. public class MybatisUtils {
  2.     private static SqlSessionFactory sqlSessionFactory;
  3.     static {
  4.         try {
  5.             // 从 XML 文件中构建 SqlSessionFactory 的实例
  6.             String resource = "mybatis-config.xml";
  7.             InputStream inputStream = Resources.getResourceAsStream(resource);
  8.             sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  9.         } catch (IOException e) {
  10.             e.printStackTrace();
  11.         }
  12.     }
  13.     //获取SqlSession连接
  14.     public static SqlSession getSession(){
  15.         return sqlSessionFactory.openSession();
  16.     }
  17. }
复制代码


 



   五.ResultMap要解决的问题:属性名和字段名不划一 

  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Alias("user")
  5. public class User {
  6.     private int id;  //id
  7.     private String name;   //姓名
  8.     // 密码 private String pwd;
  9.     // 字段不一致
  10.     private String passWord;
  11. }
复制代码
按刚才的步骤查询用户运行发现密码为null 
解决:
方式一:为列名指定别名 , 别名和java实体类的属性名划一
  1. <select id="selectUserById" resultType="User">
  2.     select id , name , pwd as password from user where id = #{id}
  3. </select>
复制代码
方式二:利用结果集映射->ResultMap 【推荐】
  1. <resultMap id="UserMap" type="User">
  2.     <!-- id为主键 -->
  3.     <id column="id" property="id"/>
  4.     <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
  5.     <result column="name" property="name"/>
  6.     <result column="pwd" property="password"/>
  7. </resultMap>
  8. <select id="selectUserById" resultMap="UserMap">
  9.     select id , name , pwd from user where id = #{id}
  10. </select>
复制代码

    六.MyBatis分页的实现

  1.日志工厂 

思索:我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率?
曾经:sout,debug
现在:日志工厂
logImpl指定 MyBatis 所用日志的具体实现,未指定时将主动查找。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING未设置

Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具 


  • SLF4J 
  • LOG4J 【需要把握】
  • LOG4J2
  • JDK_LOGGING 
  •  COMMONS_LOGGING
  •  STDOUT_LOGGING 【需要把握】
  • NO_LOGGING
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会利用最先找到的(按上文枚举的次序查找)。 假如一个都未找到,日志功能就会被禁用。 

尺度日志实现,在核心设置文件中设置
  1. <settings>
  2.         <setting name="logImpl" value="STDOUT_LOGGING"/>
  3. </settings>
复制代码


2.Log4j 

简介:


  • Log4j是Apache的一个开源项目
  • 通过利用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件….
  • 我们也可以控制每一条日志的输出格式;
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个设置文件来机动地举行设置,而不需要修改应用的代码。

利用步骤:


  • 导入log4j的包Maven Repository: log4j » log4j (mvnrepository.com)
  • 设置文件编写:在resources文件夹下创建log4j.properties设置文件
    1. #将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
    2. log4j.rootLogger=DEBUG,console,file
    3. #控制台输出的相关设置
    4. log4j.appender.console = org.apache.log4j.ConsoleAppender
    5. log4j.appender.console.Target = System.out
    6. log4j.appender.console.Threshold=DEBUG
    7. log4j.appender.console.layout = org.apache.log4j.PatternLayout
    8. log4j.appender.console.layout.ConversionPattern=[%c]-%m%n
    9. #文件输出的相关设置
    10. log4j.appender.file = org.apache.log4j.RollingFileAppender
    11. log4j.appender.file.File=./log/kuang.log
    12. log4j.appender.file.MaxFileSize=10mb
    13. log4j.appender.file.Threshold=DEBUG
    14. log4j.appender.file.layout=org.apache.log4j.PatternLayout
    15. log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
    16. #日志输出级别
    17. log4j.logger.org.mybatis=DEBUG
    18. log4j.logger.java.sql=DEBUG
    19. log4j.logger.java.sql.Statement=DEBUG
    20. log4j.logger.java.sql.ResultSet=DEBUG
    21. log4j.logger.java.sql.PreparedStatement=DEBUG
    复制代码

  • setting设置日志实现,在核心设置文件中设置
    1. <settings>
    2.     <setting name="logImpl" value="LOG4J"/>
    3. </settings>
    复制代码

  • 在程序中利用Log4j举行输出!
    1. public class UserMapperTest {
    2.     // 注意导包:org.apache.log4j.Logger
    3.     static Logger logger = Logger.getLogger(UserMapperTest.class);
    4.     @Test
    5.     public void selectUser(){
    6.         // 日志等级
    7.         logger.info("信息 info:进入selectUser方法");
    8.         logger.debug("调试 debug:进入selectUser方法");
    9.         logger.error("严重错误 error: 进入selectUser方法");
    10.         // 获取SqlSession
    11.         SqlSession session = MybatisUtils.getSession();
    12.         try {
    13.             // getMapper()
    14.             // List<User> users = session.selectList("com.dao.mapper.UserMapper.selectUser");老方式
    15.             UserMapper userMapper = session.getMapper(UserMapper.class);
    16.             List<User> users = userMapper.selectUser();
    17.             for (User user: users) {
    18.                 System.out.println(user);
    19.             }
    20.         } catch (Exception e) {
    21.             throw new RuntimeException(e);
    22.         } finally {
    23.             // 关闭SqlSession
    24.             session.close();
    25.         }
    26.     }
    27. }
    复制代码



 3.limit实现分页

思索:为什么需要分页?
在学习mybatis等持久层框架的时候,会常常对数据举行增删改查操纵,利用最多的是对数据库举行查询操纵,假如查询大量数据的时候,我们往往利用分页举行查询,也就是每次处理小部门数据,如许对数据库压力就在可控范围内。
利用Limit实现分页 
  1. public interface UserMapper {
  2.     // 选择全部用户实现分页
  3.     List<User> selectUser(Map<String,Object> map);
  4. }
复制代码
  1.     <!-- 注意Mapper.xml配置文件中一个id对应着一个方法,方法的重载会报错-->
  2.     <select id="selectUser" parameterType="map" resultType="user">
  3.         select * from user limit #{startIndex},#{pageSize}
  4.     </select>
复制代码
  1.     @Test
  2.     public void selectLimitUser() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         try {
  5.             UserMapper userMapper = session.getMapper(UserMapper.class);
  6.             Map<String,Object> map = new HashMap<String, Object>();
  7.             map.put("startIndex",0);
  8.             map.put("pageSize",2);
  9.             List<User> users = userMapper.selectUser(map);
  10.             for (User user: users) {
  11.                 System.out.println(user);
  12.             }
  13.         } catch (Exception e) {
  14.             throw new RuntimeException(e);
  15.         } finally {
  16.             session.close();
  17.         }
  18.     }
复制代码

4.RowBounds分页 

我们除了利用Limit在SQL层面实现分页,也可以利用RowBounds在Java代码层面实现分页,当然此种方式作为了解即可。我们来看下如何实现的!
  1. public interface UserMapper {
  2.     // 选择全部用户RowBounds实现分页
  3.     List<User> getUserByRowBounds();
  4. }
复制代码
  1.      <select id="getUserByRowBounds" resultType="user">
  2.         select * from user
  3.     </select>
复制代码
  1.     @Test
  2.     public void getUserByRowBounds() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         try {
  5.             int currentPage = 2;  //第几页
  6.             int pageSize = 2;  //每页显示几个
  7.             RowBounds rowBounds = new RowBounds((currentPage-1)*2,pageSize);
  8.             // 通过session.**方法进行传递rowBounds,[此种方式现在已经不推荐使用了]
  9.             List<User> users = session.selectList("com.dao.UserMapper.getUserByRowBounds",null,rowBounds);
  10.             for (User user: users) {
  11.                 System.out.println(user);
  12.             }
  13.         } catch (Exception e) {
  14.             throw new RuntimeException(e);
  15.         } finally {
  16.             session.close();
  17.         }
  18.     }
复制代码

 5.PageHelper分页

MyBatis 分页插件 PageHelper


    七.利用注解开辟

  1.增删改查 


  1. public interface UserMapper {
  2.     // 查询全部用户
  3.     @Select("select * from user")
  4.     List<User> selectUser();
  5.     //根据id查询用户
  6.     @Select("select * from user where id = #{id}")
  7.     // @Param注解用于给方法参数起一个名字。以下是总结的使用原则:
  8.     // 在方法只接受一个参数的情况下,可以不使用@Param。
  9.     // 在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名。
  10.     // 如果参数是 JavaBean , 则不能使用@Param。
  11.     // 不使用@Param注解时,参数只能有一个,并且是Javabean。
  12.     User selectUserById(@Param("id") int id);
  13.     // 添加用户
  14.     @Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
  15.     int addUser(User user);
  16.     // 删除用户
  17.     @Delete("delete from user where id = #{id}")
  18.     int deleteUser(@Param("id") int id);
  19.     // 更改用户
  20.     @Update("update user set name = #{name} where id = {id}")
  21.     int updateUser(User user);
  22. }
复制代码
在核心设置文件中注册
  1.     <mappers>
  2.         <mapper class="com.dao.UserMapper"/>
  3.     </mappers>
复制代码
 测试的代码是稳定的
  1.     // 注意导包:org.apache.log4j.Logger    static Logger logger = Logger.getLogger(UserMapperTest.class);        @Test    public void selectUser(){        // 日志等级        logger.info("信息 info:进入selectUser方法");        logger.debug("调试 debug:进入selectUser方法");        logger.error("严重错误 error: 进入selectUser方法");        // 获取SqlSession        SqlSession session = MybatisUtils.getSession();        try {            // getMapper()            // List<User> users = session.selectList("com.dao.mapper.UserMapper.selectUser");老方式            UserMapper userMapper = session.getMapper(UserMapper.class);            List<User> users = userMapper.selectUser();            for (User user: users) {                System.out.println(user);            }        } catch (Exception e) {            throw new RuntimeException(e);        } finally {            // 关闭SqlSession            session.close();        }    }    @Test
  2.     public void selectUserById() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         UserMapper userMapper = session.getMapper(UserMapper.class);
  5.         User user = userMapper.selectUserById(1);
  6.         try {
  7.             System.out.println(user);
  8.         } catch (Exception e) {
  9.             throw new RuntimeException(e);
  10.         } finally {
  11.             session.close();
  12.         }
  13.     }    @Test
  14.     public void addUser() {
  15.         SqlSession session = MybatisUtils.getSession();
  16.         UserMapper userMapper = session.getMapper(UserMapper.class);
  17.         int add = userMapper.addUser(new User(4,"lisa","452423423"));
  18.         if(add > 0) {
  19.             System.out.println("添加成功");
  20.         }
  21.         // 增删改需要提交事务
  22.         session.commit();
  23.         session.close();
  24.     }
  25.     @Test
  26.     public void deleteUser() {
  27.         SqlSession session = MybatisUtils.getSession();
  28.         UserMapper userMapper = session.getMapper(UserMapper.class);
  29.         int delete = userMapper.deleteUser(1);
  30.         if(delete > 0) {
  31.             System.out.println("删除成功");
  32.         }
  33.         session.commit();
  34.         session.close();
  35.     }
  36.     @Test
  37.     public void updateUser() {
  38.         SqlSession session = MybatisUtils.getSession();
  39.         UserMapper userMapper = session.getMapper(UserMapper.class);
  40.         int update = userMapper.updateUser(new User(2,"张三","111111"));
  41.         if(update > 0) {
  42.             System.out.println("修改成功");
  43.         }
  44.         session.commit();
  45.         session.close();
  46.     }
复制代码

2.本质 

利用Debug检察本质

本质上利用了jvm的动态代理机制


3.Mybatis具体的执行流程

 


4.#与$的区别 

{} 的作用重要是替换预编译语句(PrepareStatement)中的占位符? 【推荐利用】
  1. INSERT INTO user (name) VALUES (#{name});
  2. INSERT INTO user (name) VALUES (?);
复制代码
${} 的作用是直接举行字符串替换 
  1. INSERT INTO user (name) VALUES ('${name}');
  2. INSERT INTO user (name) VALUES ('kuangshen');
复制代码

   八.多对一的处理

   1.数据库设计与预备



  1. CREATE TABLE `teacher` (
  2.   `id` INT(10) NOT NULL,
  3.   `name` VARCHAR(30) DEFAULT NULL,
  4.   PRIMARY KEY (`id`)
  5. ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  6. INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
  7. CREATE TABLE `student` (
  8.   `id` INT(10) NOT NULL,
  9.   `name` VARCHAR(30) DEFAULT NULL,
  10.   `tid` INT(10) DEFAULT NULL,
  11.   PRIMARY KEY (`id`),
  12.   KEY `fktid` (`tid`),
  13.   CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
  14. ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  15. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
  16. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
  17. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
  18. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
  19. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
复制代码
实体类 
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class Teacher {
  5.     private int id;
  6.     private String name;
  7. }
复制代码
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Student {
  5.     private int id;
  6.     private String name;
  7.     private Teacher teacher;
  8. }
复制代码
编写实体类对应的Mapper接口 【两个】 
  1. public interface TeacherMapper {
  2. }
复制代码
  1. public interface StudentMapper {
  2. }
复制代码
编写Mapper接口对应的 mapper.xml设置文件 【两个】 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.StudentMapper">
  6. </mapper>
复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.TeacherMapper">
  6. </mapper>
复制代码


2.按查询嵌套处理(像子查询)

给StudentMapper接口增长方法 
  1. //获取所有学生及对应老师的信息
  2. public List<Student> getStudents();
复制代码
编写对应的Mapper文件
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.StudentMapper">
  6.     <select id="getStudents" resultMap="StudentTeacher">
  7.         select * from student
  8.     </select>
  9.     <resultMap id="StudentTeacher" type="Student">
  10.         <!--association – 一个复杂类型的关联;使用它来处理关联查询
  11.         association关联属性  property属性名 javaType属性类型 column在多的一方的表中的列名-->
  12.         <association property="teacher"  column="tid" javaType="Teacher" select="getTeacher"/>
  13.     </resultMap>
  14.     <!--
  15.     这里传递过来的id,只有一个属性的时候,下面可以写任何值
  16.     association中column多参数配置:
  17.         column="{key=value,key=value}"
  18.         其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。
  19.     -->
  20.     <select id="getTeacher" resultType="teacher">
  21.         select * from teacher where id = #{id}
  22.     </select>
  23. </mapper>
复制代码
 

编写完毕去Mybatis设置文件中,注册Mapper!
  1.     <mappers>
  2.         <mapper resource="com/dao/StudentMapper.xml"/>
  3.     </mappers>
复制代码
 测试
  1.     @Test
  2.     public void getStudents() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         StudentMapper mapper = session.getMapper(StudentMapper.class);
  5.         List<Student> students = mapper.getStudents();
  6.         for (Student student : students) {
  7.             System.out.println(student);
  8.         }
  9.          session.close();
  10.     }
复制代码

3.按结果嵌套处理(像联表查询)

接口方法编写
  1. public List<Student> getStudents2();
复制代码
编写对应的mapper文件
  1. <!--
  2. 按查询结果嵌套处理
  3. 思路:
  4.     1. 直接查询出结果,进行结果集的映射
  5. -->
  6. <select id="getStudents2" resultMap="StudentTeacher2" >
  7.     select s.id sid, s.name sname , t.name tname
  8.     from student s,teacher t
  9.     where s.tid = t.id
  10. </select>
  11. <resultMap id="StudentTeacher2" type="Student">
  12.     <id property="id" column="sid"/>
  13.     <result property="name" column="sname"/>
  14.     <!--关联对象property 关联对象在Student实体类中的属性-->
  15.     <association property="teacher" javaType="Teacher">
  16.         <result property="name" column="tname"/>
  17.     </association>
  18. </resultMap>
复制代码
去mybatis-config文件中注入【此处应该处理过了】
测试
  1.     @Test
  2.     public void getStudents2() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         StudentMapper mapper = session.getMapper(StudentMapper.class);
  5.         List<Student> students = mapper.getStudents();
  6.         for (Student student : students) {
  7.             System.out.println(student);
  8.         }
  9.          session.close();
  10.     }
复制代码

   九.一对多的处理

    1.数据库设计与预备



  1. CREATE TABLE `teacher` (
  2.   `id` INT(10) NOT NULL,
  3.   `name` VARCHAR(30) DEFAULT NULL,
  4.   PRIMARY KEY (`id`)
  5. ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  6. INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师');
  7. CREATE TABLE `student` (
  8.   `id` INT(10) NOT NULL,
  9.   `name` VARCHAR(30) DEFAULT NULL,
  10.   `tid` INT(10) DEFAULT NULL,
  11.   PRIMARY KEY (`id`),
  12.   KEY `fktid` (`tid`),
  13.   CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
  14. ) ENGINE=INNODB DEFAULT CHARSET=utf8;
  15. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1');
  16. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1');
  17. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1');
  18. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1');
  19. INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
复制代码
实体类 
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. public class Teacher {
  5.     private int id;
  6.     private String name;
  7.     // 老师有多个学生
  8.     private List<Student> students;
  9. }
复制代码
  1. @Data
  2. @AllArgsConstructor
  3. @NoArgsConstructor
  4. public class Student {
  5.     private int id;
  6.     private String name;
  7.     private int tid;
  8. }
复制代码
编写实体类对应的Mapper接口 【两个】 
  1. public interface TeacherMapper {
  2. }
复制代码
  1. public interface StudentMapper {
  2. }
复制代码
编写Mapper接口对应的 mapper.xml设置文件 【两个】 
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.StudentMapper">
  6. </mapper>
复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.TeacherMapper">
  6. </mapper>
复制代码

2.按查询嵌套处理(像子查询) 

TeacherMapper接口编写方法
  1. public Teacher getTeacher(int id);
复制代码
编写接口对应的Mapper设置文件
  1.    <select id="getTeacher" resultMap="TeacherStudent">
  2.         select * from teacher where id = #{id}
  3.     </select>
  4.     <resultMap id="TeacherStudent" type="Teacher">
  5.         <!--column是一对多的外键 , 写的是一的主键的列名 -->
  6.         <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
  7.     </resultMap>
  8.     <select id="getStudentByTeacherId" resultType="Student">
  9.         select * from student where tid = #{id}
  10.     </select>
复制代码

将Mapper文件注册到MyBatis-config文件中
  1.    <mappers>
  2.         <mapper resource="com/dao/TeacherMapper.xml"/>
  3.     </mappers>
复制代码
 测试
  1.     @Test
  2.     public void getTeacher() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         TeacherMapper mapper = session.getMapper(TeacherMapper.class);
  5.         Teacher teacher = mapper.getTeacher(1);
  6.         System.out.println(teacher);
  7. // 结果       Teacher(id=0, name=秦老师,
  8. //                students=[Student(id=1, name=小明, tid=1),
  9. //                Student(id=2, name=小红, tid=1),
  10. //                Student(id=3, name=小张, tid=1),
  11. //                Student(id=4, name=小李, tid=1),
  12. //                Student(id=5, name=小王, tid=1)])
  13.         
  14.         session.close();
  15. }
复制代码

3.按结果嵌套处理(像联表查询)

TeacherMapper接口编写方法
  1. //获取指定老师,及老师下的所有学生
  2. public Teacher getTeacher2(int id);
复制代码
 编写接口对应的Mapper设置文件
  1.         <select id="getTeacher2" resultMap="TeacherStudent2">
  2.             select s.id sid, s.name sname , t.name tname, t.id tid
  3.             from student s,teacher t
  4.             where s.tid = t.id and t.id=#{id}
  5.         </select>
  6.         <resultMap id="TeacherStudent2" type="Teacher">
  7.             <result  property="name" column="tname"/>
  8.             <collection property="students" ofType="Student">
  9.                 <result property="id" column="sid" />
  10.                 <result property="name" column="sname" />
  11.                 <result property="tid" column="tid" />
  12.             </collection>
  13.         </resultMap>
复制代码
将Mapper文件注册到MyBatis-config文件中
测试 
  1.     @Test
  2.     public void getTeacher2() {
  3.         SqlSession session = MybatisUtils.getSession();
  4.         TeacherMapper mapper = session.getMapper(TeacherMapper.class);
  5.         Teacher teacher = mapper.getTeacher(1);
  6.         System.out.println(teacher);
  7. // 结果       Teacher(id=0, name=秦老师,
  8. //                students=[Student(id=1, name=小明, tid=1),
  9. //                Student(id=2, name=小红, tid=1),
  10. //                Student(id=3, name=小张, tid=1),
  11. //                Student(id=4, name=小李, tid=1),
  12. //                Student(id=5, name=小王, tid=1)])
  13.         session.close();
  14.     }
复制代码

   十.动态SQL 

   1.简介

动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.
  1. [/code] [size=3]2.搭建环境 [/size]
  2.  [b]新建一个数据库表:blog[/b]
  3. [code]CREATE TABLE `blog` (
  4.   `id` varchar(50) NOT NULL COMMENT '博客id',
  5.   `title` varchar(100) NOT NULL COMMENT '博客标题',
  6.   `author` varchar(30) NOT NULL COMMENT '博客作者',
  7.   `create_time` datetime NOT NULL COMMENT '创建时间',
  8.   `views` int(30) NOT NULL COMMENT '浏览量'
  9. ) ENGINE=InnoDB DEFAULT CHARSET=utf8
复制代码
实体类编写 【注意set方法作用】 
  1. @Data
  2. public class Blog {
  3.     private String id;
  4.     private String title;
  5.     private String author;
  6.     private Date createTime; // 这里与数据库不对应,后面会在核心配置文件中配置
  7.     private int views;
  8. }
复制代码
IDutil工具类(随机数)
  1. package com.utils;
  2. import java.util.UUID;
  3. public class IDUtil {
  4.     public static String genId(){
  5.         return UUID.randomUUID().toString().replace("-","");
  6.     }
  7. }
复制代码
编写Mapper接口及xml文件 
  1. public interface BlogMapper {
  2. }
复制代码
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper
  3.         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4.         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="com.dao.BlogMapper">
  6. </mapper>
复制代码
 mybatis核心设置文件,下划线驼峰主动转换
mapUnderscoreToCamelCase是否开启驼峰定名主动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。true | falseFalse

  1.     <settings>
  2.         <setting name="mapUnderscoreToCamelCase" value="true"/>
  3.         <setting name="logImpl" value="STDOUT_LOGGING"/>
  4.     </settings>
  5.     <mappers>
  6.         <mapper resource="com/dao/BlogMapper.xml"/>
  7.     </mappers>
复制代码
插入初始数据 
编写接口
  1. //新增一个博客
  2. int addBlog(Blog blog);
复制代码
sql设置文件
  1. <insert id="addBlog" parameterType="blog">
  2.     insert into blog (id, title, author, create_time, views)
  3.     values (#{id},#{title},#{author},#{createTime},#{views});
  4. </insert>
复制代码
 初始化博客方法
  1. @Test
  2. public void addInitBlog(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     BlogMapper mapper = session.getMapper(BlogMapper.class);
  5.     Blog blog = new Blog();
  6.     blog.setId(IDUtil.genId());
  7.     blog.setTitle("Mybatis如此简单");
  8.     blog.setAuthor("狂神说");
  9.     blog.setCreateTime(new Date());
  10.     blog.setViews(9999);
  11.     mapper.addBlog(blog);
  12.     blog.setId(IDUtil.genId());
  13.     blog.setTitle("Java如此简单");
  14.     mapper.addBlog(blog);
  15.     blog.setId(IDUtil.genId());
  16.     blog.setTitle("Spring如此简单");
  17.     mapper.addBlog(blog);
  18.     blog.setId(IDUtil.genId());
  19.     blog.setTitle("微服务如此简单");
  20.     mapper.addBlog(blog);
  21.     session.close();
  22. }
复制代码
 初始化数据完毕!

3.if 语句

需求:根据作者名字和博客名字来查询博客!假如作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
编写接口类
  1. //需求1
  2. List<Blog> queryBlogIf(Map map);
复制代码
编写SQL语句
  1. <!--需求1:
  2. 根据作者名字和博客名字来查询博客!
  3. 如果作者名字为空,那么只根据博客名字查询,反之,则根据作者名来查询
  4. select * from blog where title = #{title} and author = #{author}
  5. -->
  6. <select id="queryBlogIf" parameterType="map" resultType="blog">
  7.     select * from blog where
  8.     <if test="title != null">
  9.         title = #{title}
  10.     </if>
  11.     <if test="author != null">
  12.         and author = #{author}
  13.     </if>
  14. </select>
复制代码
 测试
  1. @Test
  2. public void testQueryBlogIf(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     BlogMapper mapper = session.getMapper(BlogMapper.class);
  5.     HashMap<String, String> map = new HashMap<String, String>();
  6.     map.put("title","Mybatis如此简单");
  7.     map.put("author","狂神说");
  8.     List<Blog> blogs = mapper.queryBlogIf(map);
  9.     System.out.println(blogs);
  10.     session.close();
  11. }
复制代码
如许写我们可以看到,假如 author 等于 null,那么查询语句为 select from user where title=#{title},但是假如title为空呢?那么查询语句为 select from user where and author=#{author},这是错误的 SQL 语句,如何解决呢?请看下面的 where 语句!

4.Where 

修改上面的SQL语句;
  1. <select id="queryBlogIf" parameterType="map" resultType="blog">
  2.     select * from blog
  3.     <where>
  4.         <if test="title != null">
  5.             title = #{title}
  6.         </if>
  7.         <if test="author != null">
  8.             and author = #{author}
  9.         </if>
  10.     </where>
  11. </select>
复制代码
这个“where”标签会知道假如它包罗的标签中有返回值的话,它就插入一个‘where’。别的,假如标签返回的内容是以AND 或OR 开头的,则它会剔除掉。【这是我们利用的最多的案例】

5.choose、when、otherwise 

 修改上面的SQL语句;与Java中的switch相似
  1.    <select id="queryBlogIf" parameterType="map" resultType="blog">
  2.         select * from blog
  3.     <where>
  4.         <choose>
  5.             <when test="title != null">
  6.                 title = #{title}
  7.             </when>
  8.             <when test="author != null">
  9.                 and author = #{author}
  10.             </when>
  11.             <otherwise>
  12.                 and views = #{views}
  13.             </otherwise>
  14.         </choose>
  15.     </where>
  16.     </select>
复制代码

6.Set 

同理,上面的对于查询 SQL 语句包罗 where 关键字,假如在举行更新操纵的时候,含有 set 关键词,我们怎么处理呢?
编写接口方法
  1. int updateBlog(Map map);
复制代码
sql设置文件
  1. <!--注意set是用的逗号隔开-->
  2. <update id="updateBlog" parameterType="map">
  3.     update blog
  4.       <set>
  5.           <if test="title != null">
  6.               title = #{title},
  7.           </if>
  8.           <if test="author != null">
  9.               author = #{author}
  10.           </if>
  11.       </set>
  12.     where id = #{id};
  13. </update>
复制代码
测试
  1. @Test
  2. public void testUpdateBlog(){
  3. SqlSession session = MybatisUtils.getSession();
  4. BlogMapper mapper = session.getMapper(BlogMapper.class);
  5. HashMap<String, String> map = new HashMap<String, String>();
  6. map.put("title","动态SQL");
  7. map.put("author","秦疆");
  8. map.put("id","9d6a763f5e1347cebda43e2a32687a77");
  9. mapper.updateBlog(map);
  10.    session.close();
  11. }
复制代码

7.trim定制where、set



8.SQL片段 

 偶然候大概某个 sql 语句我们用的特别多,为了增长代码的重用性,简化代码,我们需要将这些代码抽取出来,然后利用时直接调用。
 提取SQL片段:
  1. <sql id="if-title-author">
  2.     <if test="title != null">
  3.         title = #{title}
  4.     </if>
  5.     <if test="author != null">
  6.         and author = #{author}
  7.     </if>
  8. </sql>
复制代码
引用SQL片段:
  1. <select id="queryBlogIf" parameterType="map" resultType="blog">
  2.     select * from blog
  3.     <where>
  4.         <!-- 引用 sql 片段,如果refid 指定的不在本文件中,那么需要在前面加上 namespace -->
  5.         <include refid="if-title-author"></include>
  6.         <!-- 在这里还可以引用其他的 sql 片段 -->
  7.     </where>
  8. </select>
复制代码
注意:①、最好基于 单表来定义 sql 片段,进步片段的可重用性
   ②、在 sql 片段中不要包罗 where

9.Foreach 

将数据库中前三个数据的id修改为1,2,3;
需求:我们需要查询 blog 表中 id 分别为1,2,3的博客信息
编写接口
  1. List<Blog> queryBlogForeach(Map map);
复制代码
编写SQL语句 

  1. <select id="queryBlogForeach" parameterType="map" resultType="blog">
  2.     select * from blog
  3.     <where>
  4.         <!--
  5.         collection:指定输入对象中的集合属性
  6.         item:每次遍历生成的对象
  7.         open:开始遍历时的拼接字符串
  8.         close:结束时拼接的字符串
  9.         separator:遍历对象之间需要拼接的字符串
  10.         select * from blog where 1=1 and (id=1 or id=2 or id=3)
  11.       -->
  12.         <foreach collection="ids"  item="id" open="and (" close=")" separator="or">
  13.             id=#{id}
  14.         </foreach>
  15.     </where>
  16. </select>
复制代码
测试
  1. @Test
  2. public void testQueryBlogForeach(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     BlogMapper mapper = session.getMapper(BlogMapper.class);
  5.     HashMap map = new HashMap();
  6.     List<Integer> ids = new ArrayList<Integer>();
  7.     ids.add(1);
  8.     ids.add(2);
  9.     ids.add(3);
  10.     map.put("ids",ids);
  11.     List<Blog> blogs = mapper.queryBlogForeach(map);
  12.     System.out.println(blogs);
  13.     session.close();
  14. }
复制代码
 小结:实在动态 sql 语句的编写往往就是一个拼接的问题,为了保证拼接正确,我们最好起首要写原生的 sql 语句出来,然后在通过 mybatis 动态sql 对照着改,防止堕落。多在实践中利用才是熟练把握它的本事

   十一.MyBatis缓存 

  1.简介 



  • 什么是缓存 [ Cache ]?

    • 存在内存中的暂时数据。
    • 将用户常常查询的数据放在缓存(内存)中,用户去查询数据就不消从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而进步查询效率,解决了高并发系统的性能问题。

  • 为什么利用缓存?

    • 淘汰和数据库的交互次数,淘汰系统开销,进步系统效率。

  • 什么样的数据能利用缓存?

    • 常常查询而且不常常改变的数据。


2.Mybatis缓存 



  • MyBatis包罗一个非常强盛的查询缓存特性,它可以非常方便地定制和设置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存

    • 默认环境下,只有一级缓存开启。(SqlSession级别的缓存,也称为当地缓存)
    • 二级缓存需要手动开启和设置,他是基于namespace级别的缓存。
    • 为了进步扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存



3.一级缓存 



  • 一级缓存也叫当地缓存:

    • 与数据库同一次会话期间查询到的数据会放在当地缓存中。
    • 以后假如需要获取雷同的数据,直接从缓存中拿,没必须再去查询数据库;

在mybatis中加入日志,方便测试结果
 编写接口方法
  1. //根据id查询用户
  2. User queryUserById(@Param("id") int id);
复制代码
 接口对应的Mapper文件
  1. <select id="queryUserById" resultType="user">
  2.     select * from user where id = #{id}
  3. </select>
复制代码
测试
  1. @Test
  2.     public void selectUserById() {
  3.         SqlSession session = MybatisUtils.getSession(); // 一级缓存开始
  4.         UserMapper userMapper = session.getMapper(UserMapper.class);
  5.         User user1 = userMapper.selectUserById(1);
  6.         System.out.println(user1);
  7.         System.out.println("-----------------------------");
  8.         User user2 = userMapper.selectUserById(1);
  9.         System.out.println(user2);
  10.         System.out.println("------------------------------");
  11.         System.out.println(user1 == user2);
  12.         session.close(); // 一级缓存结束
  13.         //一级缓存是SqlSession级别的缓存,是一直开启的,我们关闭不了它,这里指的是缓存范围
  14.         
  15. }
复制代码
结果分析

一级缓存失效的四种环境 
一级缓存失效环境:没有利用到当前的一级缓存,结果就是,还需要再向数据库中发起一次查询哀求!
1.sqlSession不同
  1. @Test
  2. public void testQueryUserById(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     SqlSession session2 = MybatisUtils.getSession();
  5.     UserMapper mapper = session.getMapper(UserMapper.class);
  6.     UserMapper mapper2 = session2.getMapper(UserMapper.class);
  7.     User user = mapper.queryUserById(1);
  8.     System.out.println(user);
  9.     User user2 = mapper2.queryUserById(1);
  10.     System.out.println(user2);
  11.     System.out.println(user==user2);
  12.     session.close();
  13.     session2.close();
  14. }
复制代码
观察结果:发现发送了两条SQL语句! 
结论:每个sqlSession中的缓存相互独立

 2.sqlSession雷同,查询条件不同
  1. @Test
  2. public void testQueryUserById(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     UserMapper mapper = session.getMapper(UserMapper.class);
  5.     UserMapper mapper2 = session.getMapper(UserMapper.class);
  6.     User user = mapper.queryUserById(1);
  7.     System.out.println(user);
  8.     User user2 = mapper2.queryUserById(2);
  9.     System.out.println(user2);
  10.     System.out.println(user==user2);
  11.     session.close();
  12. }
复制代码
观察结果:发现发送了两条SQL语句!很正常的明白 
结论:当前缓存中,不存在这个数据

3.sqlSession雷同,两次查询之间执行了增删改操纵!
  1. //修改用户
  2. int updateUser(Map map);
复制代码
  1. <update id="updateUser" parameterType="map">
  2.     update user set name = #{name} where id = #{id}
  3. </update>
复制代码
  1. @Test
  2. public void testQueryUserById(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     UserMapper mapper = session.getMapper(UserMapper.class);
  5.     User user = mapper.queryUserById(1);
  6.     System.out.println(user);
  7.     HashMap map = new HashMap();
  8.     map.put("name","kuangshen");
  9.     map.put("id",4);
  10.     mapper.updateUser(map);
  11.     User user2 = mapper.queryUserById(1);
  12.     System.out.println(user2);
  13.     System.out.println(user==user2);
  14.     session.close();
  15. }
复制代码
 观察结果:查询在中心执行了增删改操纵后,重新执行了
结论:由于增删改操纵大概会对当前数据产生影响

4.sqlSession雷同,手动打扫一级缓存 
  1. @Test
  2. public void testQueryUserById(){
  3.     SqlSession session = MybatisUtils.getSession();
  4.     UserMapper mapper = session.getMapper(UserMapper.class);
  5.     User user = mapper.queryUserById(1);
  6.     System.out.println(user);
  7.     session.clearCache();//手动清除缓存
  8.     User user2 = mapper.queryUserById(1);
  9.     System.out.println(user2);
  10.     System.out.println(user==user2);
  11.     session.close();
  12. }
复制代码
 一级缓存就是一个map

4.二级缓存 



  • 二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
  • 基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
  • 工作机制

    • 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    • 假如当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被生存到二级缓存中;
    • 新的会话查询信息,就可以从二级缓存中获取内容;
    • 不同的mapper查出的数据会放在自己对应的缓存(map)中;

 利用步骤
开启全局缓存 【mybatis-config.xml】
  1. <setting name="cacheEnabled" value="true"/>
复制代码
 去每个mapper.xml中设置利用二级缓存,这个设置非常简单;【xxxMapper.xml】
  1. <cache/>
  2. <!-- 可以带参数,也可以不带参数 -->
  3. <cache
  4.   eviction="FIFO"
  5.   flushInterval="60000"
  6.   size="512"
  7.   readOnly="true"/>
复制代码

所有的实体类先实现序列化接口
  1. @Data
  2. @NoArgsConstructor
  3. @AllArgsConstructor
  4. @Alias("user")
  5. public class User implements Serializable {
  6.     private int id;  //id
  7.     private String name;   //姓名
  8.     private String pwd;
  9. }
复制代码
 测试代码
  1.     @Test
  2.     public void selectUserById() {
  3.         SqlSession session1 = MybatisUtils.getSession(); // session1一级缓存开启
  4.         SqlSession session2 = MybatisUtils.getSession();//  session2一级缓存开启
  5.         UserMapper userMapper1 = session1.getMapper(UserMapper.class);
  6.         UserMapper userMapper2 = session2.getMapper(UserMapper.class);
  7.         User user1 = userMapper1.selectUserById(1);
  8.         System.out.println(user1);
  9.         session1.close(); // session1关闭一级缓存,将一级缓存的信息保存在二级缓存中
  10.         System.out.println("session1-----------------------------");
  11.         User user2 = userMapper2.selectUserById(1);
  12.         System.out.println(user2);
  13.         System.out.println("session2------------------------------");
  14.         System.out.println(user1 == user2);
  15.         session2.close();// session2关闭一级缓存,将一级缓存的信息保存在二级缓存中
  16.     }
复制代码
结论


  • 只要开启了二级缓存,我们在同一个Mapper中的查询,可以在二级缓存中拿到数据
  • 查出的数据都会被默认先放在一级缓存中
  • 只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中

5.缓存原理 



6.EhCache



  • Ehcache是一种广泛利用的java分布式缓存,用于通用缓存;
  • 要在应用程序中利用Ehcache,需要引入依赖的jar包
 https://mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache
编写ehcache.xml文件,假如在加载时未找到/ehcache.xml资源或出现问题,则将利用默认设置。
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
  4.          updateCheck="false">
  5.     <!--
  6.        diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
  7.        user.home – 用户主目录
  8.        user.dir  – 用户当前工作目录
  9.        java.io.tmpdir – 默认临时文件路径
  10.      -->
  11.     <diskStore path="./tmpdir/Tmp_EhCache"/>
  12.     <defaultCache
  13.             eternal="false"
  14.             maxElementsInMemory="10000"
  15.             overflowToDisk="false"
  16.             diskPersistent="false"
  17.             timeToIdleSeconds="1800"
  18.             timeToLiveSeconds="259200"
  19.             memoryStoreEvictionPolicy="LRU"/>
  20.     <cache
  21.             name="cloud_user"
  22.             eternal="false"
  23.             maxElementsInMemory="5000"
  24.             overflowToDisk="false"
  25.             diskPersistent="false"
  26.             timeToIdleSeconds="1800"
  27.             timeToLiveSeconds="1800"
  28.             memoryStoreEvictionPolicy="LRU"/>
  29.     <!--
  30.        defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
  31.      -->
  32.     <!--
  33.       name:缓存名称。
  34.       maxElementsInMemory:缓存最大数目
  35.       maxElementsOnDisk:硬盘最大缓存个数。
  36.       eternal:对象是否永久有效,一但设置了,timeout将不起作用。
  37.       overflowToDisk:是否保存到磁盘,当系统当机时
  38.       timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
  39.       timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
  40.       diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
  41.       diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
  42.       diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
  43.       memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
  44.       clearOnFlush:内存数量最大时是否清除。
  45.       memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
  46.       FIFO,first in first out,这个是大家最熟的,先进先出。
  47.       LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
  48.       LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
  49.    -->
  50. </ehcache>
复制代码
在mapper.xml中利用对应的缓存即可
  1. <cache type="org.mybatis.caches.ehcache.EhBlockingCache"/>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

西河刘卡车医

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表