-
定义
-
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
-
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
-
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)
-
-
特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足 *** 作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql。
-
补充
- 持久化:将程序数据在持久状态和瞬时状态间转换的机制
- 持久层:完成持久化工作的代码块
3.编写MyBatis核心配置文件org.mybatis mybatis3.5.2 mysql mysql-connector-java5.1.47
- mybatis-01srcmainresourcesmybatis-config.xml
4.编写mybatis工具类
- mybatis-01srcmainjavacomzcutilsMybatisUtils.java
public class MybatisUtils { private 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(); } } //获取SqlSession连接 public static SqlSession getSession(){ return sqlSessionFactory.openSession(); } }5.创建实体类
- mybatis-01srcmainjavacomzcpojoUser.java
public class User { private int id; private String name; private String pwd; }6.编写mapper接口
- mybatis-01srcmainjavacomzcmapperUserMapper.java
public interface UserMapper { List7.编写实现mapper接口的xml文件selectUsers(); }
- mybatis-01srcmainjavacomzcmapperUserMapper.xml
8.在mybatis的核心配置文件中,配置UserMapper.xml的路径
mybatis-01srcmainresourcesmybatis-config.xml
9.测试类
- mybatis-01srctestjavacomzcmapperUserMapperTest.java
@Test public void selectUsers(){ //获取SqlSession对象 SqlSession session = MybatisUtils.getSession(); //方式一: //List10.补充:users = session.selectList("com.zc.mapper.UserMapper.selectUsers"); //方式二: UserMapper mapper = session.getMapper(UserMapper.class); List users = mapper.selectUsers(); for (User user : users) { System.out.println(user); } session.close(); }
-
Maven静态资源过滤问题(maven会自动过滤一些路径下的资源文件)
-
在pom.xml中,加上如下配置,即可解决
3.增删改查实现 1.selectsrc/main/java ***.xml false src/main/resources ***.xml false
-
UserMapper.java
//根据id查询用户 User selectUserById(int id);
-
UserMapper.xml
-
test
@Test public void selectUserById(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(2); System.out.println(user); session.close(); }
-
UserMapper.java
//根据id删除用户 void delUserById(int id);
-
UserMapper.xml
DELETE FROM user WHERe id = #{id} -
test
@Test public void delUserById(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); mapper.delUserById(3); //提交事务 session.commit(); session.close(); }
-
UserMapper.java
//根据id修改用户信息 void updateUser(User user);
-
UserMapper.xml
UPDATE user set name=#{name},pwd=#{pwd} where id = #{id} -
test
@Test public void updateUser(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); mapper.updateUser(new User(4,"李白白白白","123456789")); session.commit(); session.close(); }
-
UserMapper.java
//添加用户 void addUser(User user);
-
UserMapper.xml
@Test public void addUser(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); mapper.addUser(new User(3,"张三三三三","123456")); mapper.addUser(new User(4,"李三三三三","123456")); session.commit(); session.close(); }
-
test
@Test public void addUser(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); mapper.addUser(new User(3,"张三三三三","123456")); mapper.addUser(new User(4,"李三三三三","123456")); session.commit(); session.close(); }
- 所有的增删改 *** 作都需要加事务
-
使用Map传递参数,可以很随意,不需要像传递对象那样,字段一一对应
-
UserMapper
//根据id修改用户指定信息 void updateUser2(Map map);
-
UserMapper.xml
update user set pwd = #{password} where id = #{UserId} -
Test
@Test public void updateUser2(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); Map
map = new HashMap (); map.put("UserId",3); map.put("password","111111111"); mapper.updateUser2(map); session.commit(); session.close(); }
-
UserMapper
//模糊查询 List
selectUserLike(String value); -
UserMapper.xml
-
Test
@Test public void selectUserLike(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); List
userList = mapper.selectUserLike("三%"); for (User user : userList) { System.out.println(user); } session.close(); }
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下:
1.环境配置(environments)-
MyBatis可以配置成适应多种环境,这种机制有助于将SQL映射应用于多种数据库中。
-
虽然可以配置多个环境,但每个SqlSessionFactory实例只能选择一种环境
-
实例:
-
有三种内嵌的数据源类型
type="[UNPOOLED|POOLED|JNDI]"
- unpooled:这个数据源的实现只是每次被请求时打开和关闭连接
- pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,这是一种使得并发Web应用快速响应请求的流行处理方式
- jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用
- 数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…
数据库这些属性是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
-
在Java属性文件中配置
-
mybatis-02srcmainresourcesdb.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis username=root password=ZC520
-
mybatis-02srcmainresourcesmybatis-config.xml
-
-
通过properties元素的子元素传递
-
mybatis-02srcmainresourcesdb.properties
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis
-
mybatis-02srcmainresourcesmybatis-config.xml
-
-
优先级:在Java属性文件中配置 > 通过properties元素的子元素传递
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
-
第一种:具体到某个类
当这样配置时,user可以使用在任意需要使用 com.zc.pojo.User 的地方
-
第二种:具体到包
-
当使用这种方式时,MyBatis会在包名下搜索需要的 Java Bean
-
每一个在包 com.zc.pojo 中的 Java Bean,
-
在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
-
例如:com.zc.pojo.User 的 别名为 user;
-
如果有注解,则别名为其注解值
@Alias("user") public class User { private int id; private String name; private String pwd; }
-
-
常用
-
懒加载
-
日志实现
-
缓存开启/关闭
-
-
一个配置完整的settings元素的示例如下
- 无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集取出一个值时,都会用类型处理器将获取的值以合适的方式转换成Java类型
- 可以重写类型处理器或者创建自己的类型处理器来处理不支持的或非标准的类型
- Mybatis每次创建结果对象的新实例时,都会使用对象工厂实例来完成
- 默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过有参构造方法来实例化
- 如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现
MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件
-
第一种方式:相对于类路径的资源引用
- 接口和实现接口的xml文件,名字可以不同
- 接口和实现接口的xml文件,可以不在同一个包
-
第二种方式:使用映射器接口实现类的完全限定类名
- 接口和实现接口的xml文件,名字必须相同
- 接口和实现接口的xml文件,必须在同一个包
-
第三种方式:将包内的映射器接口实现全部注册为映射器
- 接口和实现接口的xml文件,名字必须相同
- 接口和实现接口的xml文件,必须在同一个包
-
mybatis执行流程
-
作用域理解
-
SqlSessionFactoryBuilder的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder就失去了作用,所以它只能存在于创建SqlSessionFactory的方法中,而不要让它长期存在,因此,SqlSessionFactoryBuilder实例的最佳作用域是方法作用域(也就是局部方法变量)
-
SqlSessionFactory可以被认为是一个数据库连接池,它的作用是创建 SqlSession接口对象。因为MyBatis的本质就是Java对数据库的 *** 作,所以 SqlSessionFactory的生命周期存在于整个 Mybatis的应用之中,所以一旦创建了SqlSessionFactory,就要长期保存它,直至不再使用MyBatis应用 ,所以可以认为SqlSessionFactory的生命周期等同于MyBatis的应用周期
-
由于SqlSessionFactory是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况
-
因此在一般的应用中,我们往往希望SqlSessionFactory作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory的最佳作用域是应用作用域
-
如果说SqlSessionFactory相当于数据库连接池,那么 SqlSession就相当于一个数据库连接(Connection对象),你可以在一个事务里面执行多条SQL,然后通过它的commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费光,系统就会瘫痪,所以用 try…catch…finally…语句来保证其正确关闭。所以SqlSession的最佳作用域是请求或方法作用域
-
-
自动映射
-
resultMap元素是Mybatis中最重要最强大的元素。它可以让你从90%的JDBC ResultSets数据提取代码中解放出来
-
实际上,在为一些复杂语句编写映射代码时,一份resultMap能够代替实现同等功能的长达数千行的代码
-
ResultMap的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了
-
你已经见过简单映射的语句的示例了,但并没有显式指定resultMap。比如:
-
上述语句只是简单地将所有的列映射到HashMap的键上,这由resultType属性指定。虽然在大部分情况下都够用,但是HashMap不是一个很好的模型。你的程序更可能会使用JavaBean或POJO(Plain Old Java Objects,普通老式Java对象)作为模型
-
-
手动映射
-
返回值类型为:resultMap
-
编写resultMap,实现手动映射
-
思考:我们在测试SQL的时候,要是能够在控制台输出 SQL 的话,是不是就能够有更快的排错效率?
-
如果一个 数据库相关的 *** 作出现了问题,我们可以根据输出的SQL语句快速排查问题。
-
对于以往的开发过程,我们会经常使用到debug模式来调节,跟踪我们的代码执行过程。但是现在使用Mybatis是基于接口,配置文件的源代码执行过程。因此,我们必须选择日志工具来作为我们开发,调节程序的工具。
-
Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
- SLF4J
- Apache Commons Logging
- Log4j 2
- Log4j
- JDK logging
-
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。
-
标准日志实现
-
Log4j
-
简介:
- Log4j是Apache的一个开源项目
- 通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…
- 我们也可以控制每一条日志的输出格式
- 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
-
使用步骤
-
导入log4j的包
log4j log4j1.2.17 -
配置文件的编写
#将等级为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/zc.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=DEBUG
-
setting设置日志实现
-
在程序中使用Log4j进行输出
//注意导 apache 的包 import org.apache.log4j.Logger; public class UserMapperTest { static Logger logger = Logger.getLogger(UserMapperTest.class); @Test public void selectUsers(){ logger.info("info:进入selectUsers方法"); logger.debug("debug:进入selectUsers方法"); logger.error("error:进入selectUsers方法"); SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); List
users = mapper.selectUsers(); for (User user : users) { System.out.println(user); } session.close(); } }
-
-
-
-
mybatis-03srcmainjavacomzcmapperUserMapper.java
//分页查询 List
selectUsersByLimit(Map map); -
mybatis-03srcmainjavacomzcmapperUserMapper.xml
-
测试
@Test public void selectUsersByLimit(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); Map
map = new HashMap (); map.put("startIndex",2); map.put("pageSize",3); List userList = mapper.selectUsersByLimit(map); for (User user : userList) { System.out.println(user); } session.close(); }
-
mybatis-04srcmainresourcesmybatis-config.xml
-
mybatis-04srcmainjavacomzcpojoUser.java
@Alias("user") public class User { private int id; private String name; private String pwd; }
-
mybatis-04srcmainjavacomzcmapperUserMapper.java
public interface UserMapper { //查询所有用户 @Select("select * from user") List
selectUsers(); } -
mybatis-04srcmainjavacomzcutilsMybatisUtils.java
public class MybatisUtils { private 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(); } } //获取SqlSession连接 public static SqlSession getSession(){ return sqlSessionFactory.openSession(true); } }
-
测试
public class UserMapperTest { @Test public void test(){ SqlSession session = MybatisUtils.getSession(); UserMapper mapper = session.getMapper(UserMapper.class); List
users = mapper.selectUsers(); for (User user : users) { System.out.println(user); } session.close(); } }
-
通过id查询用户
-
UserMapper
//通过id查询用户 @Select("select * from user where id = #{uid}") User selectUserById(@Param("uid") int id);
-
-
增加一个用户
-
UserMapper
//增加一个用户 @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})") int addUser(User user);
-
-
删除一个用户
-
UserMapper
//删除一个用户 @Delete("delete from user where id = #{id}") int delUserById(@Param("id") int id);
-
-
修改用户信息
-
UserMapper
//修改用户信息 @Update("update user set name = #{name},pwd=#{pwd} where id = #{id}") int updateUser(User user);
-
- 基本类型的参数或者String类型,建议加上
- 引用类型不需要加
- 如果只有一个基本类型的话,可以忽略
- 在SQL中引用的是@Param()中设定的属性名
-
数据库
CREATE TABLE `teacher` ( `id` INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO teacher(`id`, `name`) VALUES (1, '秦老师'); CREATE TABLE `student` ( `id` INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, `tid` INT(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fktid` (`tid`), CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
-
mybatis-05srcmainresourcesmybatis-config.xml
-
mybatis-05srcmainjavacomzcutilsMyBatisUtils.java
-
mybatis-05srcmainjavacomzcpojoTeacher.java
@Data public class Teacher { private int id; private String name; }
-
mybatis-05srcmainjavacomzcpojoStudent.java
@Data public class Student { private int id; private String name; //多个学生可以是一个老师,即多对一 private Teacher teacher; }
-
mybatis-05srcmainjavacomzcmapperTeacherMapper.java
public interface TeacherMapper { }
-
mybatis-05srcmainjavacomzcmapperStudentMapper.java
public interface StudentMapper { }
-
mybatis-05srcmainresourcesmapperStudentMapper.xml
-
mybatis-05srcmainresourcesmapperTeacherMapper.xml
-
mybatis-05srcmainjavacomzcmapperStudentMapper.java
public interface StudentMapper { //获取所有学生 public List
getStudents(); //获取所有学生2 public List getStudents2(); }
-
第一种:按查询嵌套
mybatis-05srcmainresourcesmapperStudentMapper.xml
-
第二种:按结果嵌套
mybatis-05srcmainresourcesmapperStudentMapper.xml
select s.id sid,s.name sname , t.name tname,t.id tid from student s, teacher t WHERe s.tid = t.id
-
mybatis-06srcmainjavacomzcpojoTeacher.java
@Data public class Teacher { private int id; private String name; private List
students; } -
mybatis-06srcmainjavacomzcpojoStudent.java
@Data public class Student { private int id; private String name; //多个学生可以是一个老师,即多对一 private int tid; }
-
mybatis-06srcmainjavacomzcmapperTeacherMapper.java
public interface TeacherMapper { List
getTeachers(); List getTeachers2(); }
-
按结果嵌套处理
mybatis-06srcmainresourcesmapperTeacherMapper.xml
SELECT t.id tid, t.name tname, s.id sid, s.name sname FROM teacher t, student s WHERe t.id = s.tid -
按查询嵌套处理
mybatis-06srcmainresourcesmapperTeacherMapper.xml
SELECT * from teacher SELECT * from student WHERe tid = #{tid} -
小结
- 关联-association:用于一对一和多对一
- 集合-collection:用于一对多
- JavaType和ofType用来指定对象类型
- JavaType用来指定pojo中属性的类型
- ofType指定的是映射到list集合属性中pojo类型
- 我们之前写的 SQL 语句都比较简单,如果有比较复杂的业务,我们需要写复杂的 SQL 语句,往往需要拼接,而拼接 SQL ,稍微不注意,由于引号,空格等缺失可能都会导致错误。
- 那么怎么去解决这个问题呢?这就要使用 mybatis 动态SQL,通过 if, choose, when, otherwise, trim, where, set, foreach等标签,可组合成非常灵活的SQL语句,从而在提高 SQL 语句的准确性的同时,也大大提高了开发人员的效率。
-
mybatis-07srcmainresourcesmybatis-config.xml
-
mybatis-07srcmainjavacomzcpojoBlog.java
@Data public class Blog { private String id; private String title; private String author; private Date createTime; private int views; }
-
mybatis-07srcmainjavacomzcutilsIDUtil.java
public class IDUtil { //获取随机id public static String getId(){ return UUID.randomUUID().toString().replaceAll("-",""); } }
-
mybatis-07srcmainjavacomzcutilsMyBatisUtils.java
-
mybatis-07srcmainjavacomzcmapperBlogMapper.java
public interface BlogMapper { }
-
mybatis-07srcmainresourcesmapperBlogMapper.xml
-
mybatis-07srcmainjavacomzcmapperBlogMapper.java
public interface BlogMapper { //查询博客信息 List
queryBlogIF(Map map); } -
mybatis-07srcmainresourcesmapperBlogMapper.xml
select * from mybatis.blog WHERe 1=1 AND title = #{title} AND author = #{author}
-
where 元素只会在子元素返回任何内容的情况下才插入 “WHERe” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
-
mybatis-07srcmainresourcesmapperBlogMapper.xml
select * from mybatis.blog title = #{title} AND author = #{author}
5.set
-
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
-
mybatis-07srcmainresourcesmapperBlogMapper.xml
update blog title = #{title}, author = #{author}
6.Choose
-
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
-
mybatis-07srcmainresourcesmapperBlogMapper.xm
SELECT * FROM mybatis.blog title = #{title} and author = #{author} and views = #{views}
-
有时候可能某个 sql 语句我们用的特别多,为了增加代码的重用性,简化代码,我们可以将这些代码抽取出来,然后使用时直接调用。
-
提取SQL片段
title = #{title} AND author = #{author} -
引用SQL片段
select * from mybatis.blog
-
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符,看它多智能!
-
提示: 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
-
mybatis-07srcmainresourcesmapperBlogMapper.xm
SELECT * FROM blog id=#{id}
- 存在内存中的临时数据。
- 将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询。从缓存中查询,可以提高查询效率,解决了高并发系统的性能问题。
- 减少和数据库的交互次数,减少系统开销,提高系统效率。
- 经常查询并且不经常改变的数据
-
MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
-
MyBatis系统中默认定义了两级缓存:一级缓存和二级缓存
- 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
- 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
- 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存
一级缓存也叫本地缓存:
- 与数据库同一次会话期间查询到的数据会放在本地缓存中。
- 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;
-
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
-
基于namespace级别的缓存,一个名称空间,对应一个二级缓存;
-
工作机制
-
一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存中;
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中;
- 新的会话查询信息,就可以从二级缓存中获取内容;
- 不同的mapper查出的数据会放在自己对应的缓存(map)中;
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)