MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github,MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
内存断电后数据会丢失。
内存过于昂贵,需要持久化来缓存到外存。
==思路:==搭建环境–>导入MyBatis–>编写代码–>测试
3.1 搭建数据库
CREATE DATABASE `mybatis`;
USE `mybatis`;
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(20) NOT NULL,
`name` varchar(30) DEFAULT NULL,
`pwd` varchar(30) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user`(`id`,`name`,`pwd`) values (1,'sun','12345'),(2,'sunshile','12345'),(3,'shile','11231');
3.2 导入依赖包
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
注:Maven静态资源过滤问题 在pom.xml中配置
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties
**/ *.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties
**/ *.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
3.3 编写mybatis的核心配置文件(resources mybatis-config.xml)
<?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核心配置文件-->
<configuration>
<!--environments配置环境组-->
<!--default默认环境-->
<environments default="development">
<!--environment单个环境-->
<environment id="development">
<!--transactionManager配置事务管理器-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UFT-8"/>
<property name="username" value="root"/>
<property name="password" value="123123"/>
</dataSource>
</environment>
</environments>
<!--每一个Mapper.xml都需要在mybatis配置核心文件-->
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
</mappers>
</configuration>
3.4 编写mybatis工具类(utils)
package com.rui.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
//sqlSessionFactory—>SessionFactory
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try{
//获取sqlSessionFactory对象
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();
}
}
3.5 编写Mapper/DAO接口类
import com.kuang.pojo.User;
import java.util.List;
public interface UserMapper {
List<User> selectUser();
}
3.6 编写实体类pojo
package com.rui.pojo;
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;
}
3.7Dao/mapper接口
//Dao==mapper
public interface UserDao {
List<User> getuserList();
}
3.8 接口实现类
<?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">
<!--namespace绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.sun.dao.UserDao">
<!-- id对应方法名字 dao-->
<select id="getuserList" resultType="com.sun.pojo.User">
select * from mybatis.user;
</select>
</mapper>
3.9 测试
junit进行测试
public class UserDaoTest {
@Test
public void test(){
//获得sqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//执行sql
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.getuserList();
for (User user : userList) {
System.out.println(user);
}
}
}
注:增删改需要提交事务。
namespace中的包名要和Dao/mapper接口的包名一致!
id:对应namespace中的方法名
resultType: sql语句执行的返回值
编写接口addUser
// 增加一个用户
int addUser(User user);
编写对应的mapper中的sql语句
<insert id="addUser" parameterType="com.sun.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd});
</insert>
测试
@Test
public void addUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int ser = mapper.addUser(new User(6, "wangwu", "112321"));
if(ser>0){
System.out.println("插入成功!");
}
//提交事务
sqlSession.commit();
//关闭事务
sqlSession.close();;
}
思路:
1.编写接口
当表单的数据字段过多时,删除修改字段时,过程较麻烦,使用Map可以简化过程!
1.编写接口
//使用map
int addUser2(Map<String, Object> map);
编写对应的mapper中的sql语句
<insert id="addUser" parameterType="map">
insert into mybatis.user (id, name) values (#{id}, #{name});
</insert>
测试
@Test
public void addUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<String, Object>();
map.put("id",7);
map.put("name","hello");
mapper.addUser2(map);
sqlSession.commit();
sqlSession.close();
}
Map传递参数,直接在sql中取出key即可!【parameterType=“map”】
对象传递参数,直接在sql中取对象的属性即可!【parameterType=“Object”】
只有一个基本类型参数的情况下,可以直接在sql中取到!
configuration(配置文件)
properties(属性文件)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
编写一个配置文件
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username=root
password=942626
<configuration>
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
mappers>
configuration>
2.它仅用于 XML 配置,意在降低冗余的全限定类名书写.
<typeAliases>
<typeAlias type="com.sun.pojo.User" alias="User"/>
typeAliases>
3.可以指定一个包名,MyBatis 会在包名下面搜索需要的 JavaBean,比如:
<typeAliases>
<package name="com.sun.pojo"/>
typeAliases>
应用场景:
1.如果实体类多,第二种方法更合适
2.如果实体类少,可以用第一种,第二种则 不行, 如果非要改,需要在实体上增加注释
@Alias("user")
public class User {
MapperRegistry:注册绑定mapper文件
<mappers>
<mapper resource="com/sun/dao/UserMapper.xml"/>
mappers>
<mappers>
<mapper class="com.sun.dao.UserMapper.xml"/>
mappers>
使用class注意:
1.接口和它的Mapper配置文件必须同名
2.接口和它的Mapper配置文件必须在同一个包下
一般使用resource文件绑定注册更好
功能:
当数据中的字段和实体类中的字段不一致时,可以用ResultMap 解决
resultMap
元素是 MyBatis 中最重要最强大的元素。
ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
结果集映射
id name pwd
id name password
<resultMap id="userMap" type="user">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="=pwd" property="password"/>
resultMap>
<select id="getuserList" resultMap="userMap">
select * from user
select>
Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。
指定 MyBatis 应该使用哪个日志记录实现。如果此设置不存在,则会自动发现日志记录实现
测试,可以看到控制台有大量的输出!我们可以通过这些输出来判断程序到底哪里出了Bug
简介:
1.导入log4的包
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
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=DEBUG
3、设置setting日志实现
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
4、使用Log4j进行输出!
**注意导包:org.apache.log4j.Logger **
MyTest表示对该类的测试
static Logger logger = Logger.getLogger(UseMapperTest.class);
@Test
public void selectUser() {
logger.info("info:进入info方法");
logger.debug("debug:进入debug方法");
logger.error("error: 进入error方法");
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
使用Log4j 输出日志
在学习mybatis等持久层框架的时候,会经常对数据进行增删改查操作,使用最多的是对数据库进行查询操作,如果查询大量数据的时候,我们往往使用分页进行查询,也就是每次处理小部分数据,这样对数据库压力就在可控范围内。
1.1语法
SELECT * FROM table LIMIT stratIndex,pageSize
1.2接口(mapper)
List<User> selectUser(Map<String,Integer> map);
1.3 接口实现
<select id="getUserByLimit" parameterType="map" resultMap="userMap">
select * from user limit #{startIndex},#{pagesize}
</select>
1.4 测试
@Test
public void getUserByLimit(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",0);
map.put("pagesize",4);
List<User> userList = mapper.getUserByLimit(map);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
区别:不使用SQL实现分页
2.1 接口
List<User> getUserByRowBounds();
2.2 接口实现
<select id="getUserByRowBounds" resultMap="userMap">
select *from user
</select>
2.3 测试
@Test
public void getUserByRowBounds(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
//RowBound实现
RowBounds rowBounds = new owBounds(1,4);
List<User> userList = sqlSession.selectList("com.sun.dao.getUserByRowBounds",null,rowBounds);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
网址:https://pagehelper.github.io/
1.增删改查,关联映射,动态SQL语言等知识,其所有的配置是通过XML完成的,但是注释配置不需要xml配置。
2.mybatis提供了@Insert、 @Delete、@Update、@Select等常用注解。
**注意:**利用注解开发就不需要mapper.xml映射文件了
@Select("select * from user")
//查询全部用户
public List<User> getAllUser();
<mappers>
<mapper class="com.sun.dao.UserMapper"/>
mappers>
本质:反射机制
底层:动态代理
@Test
public void testGetAllUser() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.getAllUser();
for (User user : users){
System.out.println(user);
}
sqlSession.close();
}
Lombok项目是一个Java库,它提供了一组有用的注释,用来消除Java类中的大量代码。
使用步骤:
在IDEA中安装Lombok插件
在项目中导入lombok的jar包
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.10version>
<scope>providedscope>
dependency>
使用实现案例
一个老师对应多个学生
1.搭建环境,编写实体类
@Data
public class Student {
private int id;
private String name;
private int tid;
}
@Data
public class Teacher {
private int id;
private String name;
//老师对应学生
private List<Student> students;
}
处理数据库数据
1.TeacherMapper接口编写方法
public Teacher getTeacher(int id);//获取指定老师,及老师下的所有学生
2.编写对应mapper接口
<mapper namespace="com.sun.dao.TeacherMapper">
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname , t.name tname, t.id tid
from student s,teacher t
where s.tid = t.id and t.id=#{id}
select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid" />
<result property="name" column="sname" />
<result property="tid" column="tid" />
collection>
resultMap>
mapper>
3.绑定接口(mybatis-config.xml)
<mappers>
<mapper resource="com/sun/dao/TeacherMapper.xml"/>
<mapper class="com.sun.dao.StudentMapper"/>
mappers>
4.测试
@Test
public void testTeacher(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
}
1、TeacherMapper接口编写方法
//获取指定老师,及老师下的所有学生
public Teacher getTeacher1(int id);
2,编写mapper对应的配置文件
<select id="getTeacher1" resultMap="TeacherStudent1">
select * from teacher where id = #{id}
select>
<resultMap id="TeacherStudent1" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid = #{id}
select>
3.映射文件编写(MyBatis-config.xml)
4.测试
@Test
public void testGetTeacher2(){
SqlSession session = MybatisUtils.getSession();
TeacherMapper mapper = session.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher1(1);
System.out.println(teacher);
}
多个学生对应一个老师
1.数据库设计
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');
2.引入依赖(maven)
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.16.10version>
dependency>
3,编写实体类
@Data
public class Teacher {
private int id;
private String name;
}
@Data
public class Student {
private int id;
private String name;
//多个学生可以是同一个老师,即多对一
private Teacher teacher;
}
4.编写接口
public interface StudentMapper {
}
public interface TeacherMapper {
}
5.接口映射
<mapper namespace="com.sun.dao.StudentMapper">
mapper>
<mapper namespace="com.sun.dao.TeacherMapper">
mapper>
处理数据库数据
1.添加接口方法(给StudentMapper接口增加方法)
public List<Student> getStudents();//学生对老师 多对一
2.编写对应的mapper.xml文件
<mapper namespace="com.sun.dao.StudentMapper">
<select id="getStudents" resultMap="StudentTeacher">
select * from student
select>
<resultMap id="StudentTeacher" type="Student">
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
resultMap>
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id}
select>
mapper>
3.绑定接口(mybatis-config.xml)
<mappers>
<mapper resource="com/sun/dao/TeacherMapper.xml"/>
<mapper class="com.sun.dao.StudentMapper"/>
mappers>
4.测试
@Test
public void testGetStudents(){
SqlSession session = MybatisUtils.getSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudents();
for (Student student : studentList){
System.out.println(
"学生名:"+ student.getName()
+"\t老师:"+student.getTeacher().getName());
}
}
1.添加接口方法(给StudentMapper接口增加方法)
2.编写对应的mapper文件(与方法一的mapper不同,其他相同)
<select id="getStudents" resultMap="StudentTeacher" >
select s.id sid, s.name sname , t.name tname
from student s,teacher t
where s.tid = t.id
select>
<resultMap id="StudentTeacher" type="Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
association>
resultMap>
3.绑定接口(mybatis-config.xml)
4.测试
==什么是动态SQL:==动态 SQL 是 MyBatis 的强大特性之一,可以根据不同的条件生成不同的SQL语句
新建一个数据库
数据库字段:
CREATE TABLE `blog` (
`id` varchar(50) NOT NULL COMMENT '博客id',
`title` varchar(100) NOT NULL COMMENT '博客标题',
`author` varchar(30) NOT NULL COMMENT '博客作者',
`create_time` datetime NOT NULL COMMENT '创建时间',
`views` int(30) NOT NULL COMMENT '浏览量'
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1.创建一个Mybatis工程
2.创建一个工具类(使用UUID自动生成随机数)
public class IDUtil {
public static String genId(){
return UUID.randomUUID().toString().replaceAll("-","");
}
}
3.编写实体类
@Data
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private int views;
}
4.编写一个实体类接口(Mapper接口及xml文件)
public interface BlogMapper {
}
<mapper namespace="com.sun.dao.BlogMapper">
mapper>
5.编写mybatis核心配置文件
<mapper resource="com/sun/dao/BlogMapper.xml"/>
</mappers>
6.插入初始化数据
6.1 编写接口
int addBlog(Blog blog);
6.2 sql配置文件
insert into blog (id, title, author, create_time, views)
values (#{id},#{title},#{author},#{createTime},#{views});
6.3 初始化接口配置
@Test
public void addInitBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = new Blog();
blog.setId(IDUtil.genId());
blog.setTitle("Mybatis如此简单");
blog.setAuthor("狂神说");
blog.setCreateTime(new Date());
blog.setViews(9999);
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("Java如此简单");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("Spring如此简单");
mapper.addBlog(blog);
blog.setId(IDUtil.genId());
blog.setTitle("微服务如此简单");
mapper.addBlog(blog);
session.close();
}
元素是简单的条件判断,可以用来实现某些简单的条件选择。
1.1 编写接口类
List<Blog> queryBlogIf(Map map);
1.2编写SQL语句
1.3 测试
@Test
public void testQueryBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap map = new HashMap();
map.put("title","Mybatis如此简单");
map.put("author","狂神说");
List blogs = mapper.queryBlogIf(map);
System.out.println(blogs);
session.close();
}
当if元素较多时,可能会拼接成where and或者 where or之类的关键字多余的错误SQL语句,使用元素可以解决这类问题,只有元素的条件成立时,才会拼接SQL语句时加上where关键字。如果出现where and或者where or时, 元素会自动剔除where关键字后面多余的and或or.
where语句使用
和元素可以组装update语句,只有当《set》元素的条件都成立的时候,才会组装SQL语句时加上set关键字,元素包含子元素,每个元素包含SQL语句后面会有一个逗号,拼接好的SQL语句中会包含多余的逗号,从而造成SQL语法错误,但是元素能将SQL语句中多余的逗号剔除。
1.1 编写接口类
int updateBlog(Map map);
1.2编写SQL语句
<update id="updateBlog" parameterType="map">
update blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="author != null">
author = #{author}
</if>
</set>
where id = #{id};
</update>
1.3 测试
@Test
public void testUpdateBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap<String, String> map = new HashMap<String, String>();
map.put("title","hello");
map.put("author","hi");
map.put("id","110");
mapper.updateBlog(map);
session.close();
}
choose元素的用法和case元素用法类似,可以从多个选项中选择一个,可以使用mybatis提供的、和元素来实现,元素可以判断元素的条件是否成立,如果有一个成立,则不在判断后面的元素的条件是否成立,元素执行结束,如果条件都不满足,则执行元素中的SQL语句。
sql文件的编写
元素主要是迭代一个集合,在SQL语句中通常在in这个关键字的后面。
提示: 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
字段属性解析:
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
index:指定一个变量名称,表示每次迭代到的位置
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
collection属性需要根据具体情况进行设定,通常分为两种情况:
1.如果向SQL语句传递的是单参数且参数类型为List< E >,collection属性值为list
2.如果向SQL语句传递的是单参数且参数类型为array数组,collection属性值为array.
操作数据
1.编写接口
List<Blog> queryBlog(Map map);
2.编写sql
3.测试
@Test
public void testQueryBlog(){
SqlSession session = MybatisUtils.getSession();
BlogMapper mapper = session.getMapper(BlogMapper.class);
HashMap map = new HashMap();
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(2);
ids.add(3);
map.put("ids",ids);
List<Blog> blogs = mapper.queryBlogForeach(map);
System.out.println(blogs);
session.close();
缓存定义:存在内存中的临时数据
将用户经常查询的数据放在缓存(内存)中,用户去查询数据就从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题.
Mybatis缓存分为一级缓存和二级缓存。
一级缓存是SQLsession级别的缓存,当同一个SQLsession中执行两次相同的SQL语句时,会将第一次的数据存入到一级缓存中,第二次查询时就会从缓存中读取数据,从而提高查询性能。 但是当SQLSesseion执行insert,delete、和update操作,并提交到数据库中,或者SQLsession结束后,这个SQLSession中的一级缓存就不存在了。
测试实现:
1.加载日志
2.编写接口
User queryUserById(@Param("id") int id);
3.编写对应的xml文件
4.测试
@Test
public void testQueryUserById(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
User user2 = mapper.queryUserById(1);
System.out.println(user2);
session.close();
}
结果分析:
当执行第二次相同查询时,由于第一次进行数据库访问,第二次访问时,直接从缓存中读取数据,从而提高查询性能。
1.SqlSesssion不同
2.sqlSession相同,查询条件不同
3.增删改改变了原来的数据
4.缓存的清理(手动清理)
@Test
public void testUser(){
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
session.clearCache();//手动清除缓存
User user2 = mapper.queryUserById(1);
System.out.println(user2);
System.out.println(user==user2);
session.close();
}
mybatis的二级缓存是namespace级别的缓存,多个SQLsession公用二级缓存,他们使用同一个Mapper语句操作数据库获得的数据就会存在二级缓存中。
测试数据
1.开启全局缓存(mybatis-config.xml)
<setting name="cacheEnabled" value="true"/>
2.在Mapper.xml中使用缓存
//可以存储结果对象或列表的 512 个引用
3.测试
4.结论
5.缓存原理
总结:
视频来自:狂神说 mybatis https://www.bilibili.com/read/cv5702420
资料参考:https://www.cnblogs.com/renxuw/p/13047424.html