目录
一、搭建环境
二、核心配置文件
三、核心类 (测试类)
四、缓存机制
一级缓存
二级缓存
清理缓存
五、sqlMapper文件
六、单参数和多参数的传递
6.1取别名
6.2 测试新增返回自增主键
七、mybatis中Statement和PreparedStatement
作业
1、掌握环境搭建
2、掌握单个参数、多个参数的增删改查
3、缓存机制 (一级、二级缓存特点)
4、mybatis核心配置文件 常见的配置项
5、#和$的区别?(重点)
6、sqlMapper文件新增返回自增主键
7、预习 动态sql和多表关联映射
动态sql
高级结果映射
1、引入jar包
mysql.jar
mybatis.jar
2、补全结构
com.hl.pojo
com.hl.mapper
mybatis-config.xml
sqlMapper.xml
3、测试类
加载myabtis核心配置文件,得到IO流 Resources
创建sqlSessionFactory SqlsessionFactoryBuilder
SqlSession session = sqlSessionFactory.openSession()
//获取mapper接口
调用mapper方法
//关闭流
mybatis-config.xml
//1、
//2、
username
password
driver
//3、
补充完整代码
package com.hl.mybatis02;
import com.hl.mybatis02.mapper.StudentMapper;
import com.hl.mybatis02.pojo.Student;
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 org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
class Mybatis02ApplicationTests {
@Test
void contextLoads() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
Student student = new Student(0,"admin",
"男","2020-1-5",1001,
null,null,null);
int num = studentMapper.insertStudent(student);
System.out.println("受影响的数据行数:"+num);
System.out.println("自增主键值为:"+student.getStudentId());
session.commit();
session.close();
}
@Test
void query() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List list = studentMapper.listAll();
System.out.println(list);
session.commit();
session.close();
}
}
缓存:多次执行相同dql,第一次走数据库表查询,第二次不再执行sql语句,直接从缓存区中获取数据。
默认已开启,可以直接使用,属于sqlSession级别的缓存。
默认没有开启,需要手动在mybatis配置文件中开启,属于sqlSessionFactory级别的缓存。
java代码清理缓存
session.clearCache();
sqlMapper文件清理缓存
useCache="false" 禁用当前sql语句的二级缓存
flushCache="true" 清空缓存区数据 导致一级缓存和二级缓存失效
示例:
@Test
void firstCache() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List list = studentMapper.listAll();
System.out.println(list);
//清理缓存
// session.clearCache();
List list2 = studentMapper.listAll();
System.out.println(list2);
session.commit();
session.close();
}
@Test
void secondCache() throws IOException {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
SqlSession session = factory.openSession();
StudentMapper studentMapper = session.getMapper(StudentMapper.class);
List list = studentMapper.listAll();
System.out.println(list);
session.close();
SqlSession session2 = factory.openSession();
StudentMapper studentMapper2 = session2.getMapper(StudentMapper.class);
List list2 = studentMapper2.listAll();
System.out.println(list2);
session2.close();
SqlSession session3 = factory.openSession();
StudentMapper studentMapper3 = session3.getMapper(StudentMapper.class);
List list3 = studentMapper3.listAll();
System.out.println(list3);
session3.close();
}
insert into student(name,gender,birth_date,class_id,enrollment_date)
values (#{name},#{gender},#{birthDate},#{classId},now())
Mapper接口
测试新增主键的生成,对象也可以取别名
多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等
单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}
//测试新增主键的生成,对象也可以取别名
public int insertStudent(@Param("stu")Student student);
// 查询 下划线到驼峰式命名法的映射
public List listAll();
// 多个参数,给参数起别名,将不再使用系统默认的arg0、arg1等
public List findStudent(@Param("name")String name, @Param("phone")String phone);
// 单个参数,也可以取别名,之后#{里面不能随便写了只能写别名}
public Student findStudentById(int id);
Mapper映射文件里面
测试新增主键的生成:
useGeneratedKeys="true" 获取自动生成的主键
keyProperty="studentId" 主键对应的属性名
对象在接口中取别名之后,调用对象的属性名,应该写成:别名.属性名
insert into student(name,gender,birth_date,class_id,enrollment_date)
values (#{stu.name},#{stu.gender},#{stu.birthDate},#{stu.classId},now())
statementType="PREPARED" 默认 使用预编译(防止sql注入)
statementType="STATEMENT" sql 字符串拼接
statementType="CALLABLE" 调用存储过程
预处理方式不同
#{}
:使用预编译(PreparedStatement)方式,参数会被替换为 ?
,能有效防止 SQL 注入
${}
:使用字符串拼接方式,直接将参数值替换到 SQL 语句中
安全性
#{}
:安全,能防止 SQL 注入
${}
:不安全,存在 SQL 注入风险
参数处理
#{}
:会对传入的参数自动添加引号(字符串类型)
${}
:原样替换,不会添加引号
见6.2
if
choose (when, otherwise)
trim (where, set)
foreach
MyBatis 创建时的一个思想是:数据库不可能永远是你所想或所需的那个样子。 我们希望每个数据库都具备良好的第三范式或 BCNF 范式,可惜它们并不都是那样。 如果能有一种数据库映射模式,完美适配所有的应用程序,那就太好了,但可惜也没有。 而 ResultMap 就是 MyBatis 对这个问题的答案。
比如,我们如何映射下面这个语句?
你可能想把它映射到一个智能的对象模型,这个对象表示了一篇博客,它由某位作者所写,有很多的博文,每篇博文有零或多条的评论和标签。 我们先来看看下面这个完整的例子,它是一个非常复杂的结果映射(假设作者,博客,博文,评论和标签都是类型别名)。 不用紧张,我们会一步一步地来说明。虽然它看起来令人望而生畏,但其实非常简单。