MyBatis
第一章 框架的概述
1.1 三层架构
- mvc:web开发中,使用mvc架构模式。m:数据,v:视图,c:控制器
- c控制器:接收数据,调用service对象,显示请求的处理结果。当前使用servlet作为控制器
- v视图:现在使用jsp、html、css、js。显示请求的处理结果,把m中的数据显示出来
- m数据:来自数据库mysql,来自文件,来自网络
- mvc的作用:
- 实现解耦合
- 让mvc各负其责
- 使得系统扩展更好,更容易维护
- 三层架构:
- 界面层(视图层):接收用户的请求,调用service,显示请求的处理结果。包含了jsp、html、servlet等对象。对应的包controller。
- 业务逻辑层:处理业务逻辑,使用算法处理数据的。把数据返回给界面层。对应的是service包,和包中的很多的XXXService类。例如:StudentService、OrderService、ShopService等等。
- 持久层(数据访问层):访问数据库,或者读取文件,访问网络,获取数据。对应的包是dao。和包中很多的XXXDao类。例如:StudentDao、OrderDao、ShopDao等等。
1.2 三层架构请求的处理流程
- 用户发起请求----->界面层----->业务逻辑层----->持久层----->数据库(mysql)
1.3 为什么要使用三层架构?
- 结构清晰、耦合度低、各层分工明确
- 可维护性高,可扩展性高
- 有利于标准化
- 开发人员可以只关注整个结构中的其中某一层功能实现
- 有利于各层逻辑的复用
1.4 三层架构模式和框架
- 每一层对应着一个框架
- 界面层—SpringMVC框架
- 业务逻辑层—Spring框架
- 持久层—MyBatis框架
1.5 框架
- 什么是框架(framework)
- 框架:就是一个软件,完成了部分的功能。软件中的类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架看做是模板
- 框架是可以升级的、改造的。框架是安全的
- 框架是对某一个方面有用的,不是全能的
1.6 框架解决的问题
- 框架能实现技术的整合
- 提供开发的效率,降低难度
1.7 JDBC访问数据库的优缺点
- 优点:
- 直观,好理解
- 缺点:
- 创建很多对象Connection、Statement、ResultSet
- 注册驱动
- 执行sql语句
- 把ResultSet转为Student,List集合
- 关闭资源
- sql语句和业务逻辑层代码混在一起
1.8 MyBatis框架
-
MyBatis:是一个持久层框架,原名是ibatis,2010年改名为MyBatis,MyBatis可以操作数据库,对数据执行增删改查。看做是高级的jdbc,用来解决jdbc的缺点。 -
MyBatis能做什么?
- 注册驱动
- 创建jdbc中使用的Connection、Statement、ResultSet
- 执行sql语句,得到ResultSet
- 处理ResultSet,把记录集中的数据转为java对象,同时还能把java对象放入到List集合
- 关闭资源
- 实现sql语句和java代码的解耦合
-
MyBatis官网:https://mybatis.org/mybatis-3/zh/index.html -
MyBatis下载jar包或在Maven设置依赖:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qjn9yqyF-1627139123993)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210712200509562.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wfsDj6ws-1627139124001)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210712200741130.png)]
第二章 MyBatis入门
2.1 第一个例子
-
实现步骤:
- 创建student表(id,name,email,age)
DROP DATABASE IF EXISTS springdb;
CREATE DATABASE IF NOT EXISTS springdb;
USE springdb;
CREATE TABLE student(
id INT PRIMARY KEY AUTO_INCREMENT,#编号
`name` VARCHAR(80) NOT NULL,#姓名
email VARCHAR(80) NOT NULL,#电子邮件
age INT NOT NULL#年龄
);#学生表
- 新建maven项目
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CbYOU0I9-1627139124005)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210717151846175.png)]
- 修改pom.xml
- 加入依赖mybatis依赖、mysql驱动、junit
- 在加入资源插件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kgc</groupId>
<artifactId>ch01-first</artifactId>
<version>1.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.7</maven.compiler.source>
<maven.compiler.target>1.7</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
</project>
- 创建实体类Student。定义属性,属性名和列名保持一致
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "学生实体的信息{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
- 创建Dao接口,定义操作数据库的方法
public interface StudentDao {
Student getStudentById(Integer id);
}
- 创建xml文件(mapper文件),写sql语句
- mybatis框架推荐是把sql语句和java代码分开
- mapper文件:定义和Dao接口在同一目录,一个表一个mapper文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kgc.dao.StudentDao">
<select id="getStudentById" resultType="com.kgc.pojo.Student">
select * from student where id = #{id}
</select>
</mapper>
- 创建mybatis的主配置文件(xml文件):有一个,放在recources目录下
- 定义创建连接实例的数据源(DateSource)对象
- 指定其他mapper文件的位置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springdb?useUnicode=true&
characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="ok"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/kgc/dao/StudentDao.xml"/>
</mappers>
</configuration>
- 创建测试的内容
- 使用main方法,测试mybatis访问数据库
- 也可以使用junit访问数据库
public class MyTest {
@Test
public void testSelectStudentById() throws IOException {
String config = "config.xml";
InputStream is = Resources.getResourceAsStream(config);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession session = factory.openSession();
String sqlId = "com.kgc.dao.StudentDao"+"."+"getStudentById";
Student student = session.selectOne(sqlId,1002);
System.out.println("使用mybatis查询一个学生="+student);
session.close();
}
}
2.2 概念
- 自动提交:当你的sql语句执行完毕后,提交事务。数据库更新操作之间保存到数据
- 手动(手工)提交事务:在你需要提交事务的位置,执行方法,提交事务或者回顾事务
2.3 MyBatis的一些重要对象
- Resources:mybatis框架中的对象,一个作用读取主配置文件
InputStream is = Resources.getResourceAsStream("config.xml");
- SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
- SqlSessionFactory(重要对象)
- SqlSessionFactory是重量级的对象,创建此对象需要使用更多的资源和时间。在项目中有一个就可以了
- SqlSessionFactory接口:作用是SqlSession的工厂,就是创建SqlSession对象
- DefaultSqlSessionFactory是实现类
public class DefaultSqlSessionFactory implements SqlSessionFactory{ }
- SqlSessionFactory接口中的方法
- openSession():获取一个默认的SqlSession对象,默认是需要手工提交事务的
- openSession(boolean):boolean参数表示是否自动提交事务
- true:创建一个自动提交事务的SqlSession对象
- false:等同于没有参数的openSession
- SqlSession对象
- SqlSession对象是通过SqlSessionFactory获取的。SqlSession本身是接口
- DefaultSqlSession实现类
public class DefaultSqlSession implements SqlSession{ }
- SqlSession作用是提供了大量的执行sql语句的方法:
selectOne:执行sql语句,最多得到一行记录,超过一行会报错
selectList:执行sql语句,返回多行数据
selectMap:执行sql语句,得到一个Map结果
insert:执行insert语句
update:执行update语句
delete:执行delete语句
commit:提交事务
rollback:回顾事务
- 注意:SqlSession对象不是线程安全的,使用的步骤:
- 在方法的内部,执行sql语句之前,先获取SqlSession对象
- 调用SqlSession的方法,执行sql语句
- 关闭SqlSession对象,执行SqlSession.close()
2.4 使用工具类和模板
- 创建模板,mapper文件模板和mybatis主配置文件模板
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PCxev2qp-1627139124013)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210718223251800.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bquRSHKT-1627139124016)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210718223600007.png)]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3ksoyIpX-1627139124021)(C:\Users\naizhi\AppData\Roaming\Typora\typora-user-images\image-20210718224320149.png)]
public class MyBatisUtil {
private static SqlSessionFactory factory = null;
static {
String config = "mybatis.xml";
try {
InputStream is = Resources.getResourceAsStream(config);
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
SqlSession session = null;
if (factory!=null){
session = factory.openSession();
}
return session;
}
public static void close(SqlSession session) {
if (null != session) {
session.close();
}
}
}
@Test
public void testInsertById() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
String sqlId = "com.kgc.dao.StudentDao.getStudentById";
Student student = session.selectOne(sqlId, 1001);
System.out.println(student);
MyBatisUtil.close(session);
}
第三章 MyBatis的dao代理
3.1 dao代理
- mybatis提供代理:mybatis创建Dao接口的实现类对象,完成对sql语句的执行。mybatis创建一个对象代替你的dao实现类功能
- 使用mybatis代理的要求
- mapper文件中的namespace一定是dao接口的全限定名称
- mapper文件中标签的id是dao接口方法名称
- mybatis代理实现方式:
- 使用SqlSession对象的方法getMapper(dao.class)
- 例如:现在的StudentDao接口
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);
@Test
public void testInsertById() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);
System.out.println(student);
MyBatisUtil.close(session);
}
3.2 理解参数
- 理解参数:通过Java程序把数据传入到mapper文件中的sql语句。参数主要是指dao接口方法的形参
3.2.1 parameterType
<select id="getStudentById" parameterType="int"
resultType="com.kgc.pojo.Student">
select * from student where id = #{id}
</select>
3.2.2 dao接口方法有一个简单类型的参数
Student selectByEmail(String email);
<select id="getStudentById" resultType="com.kgc.pojo.Student">
select * from student where email=#{e}
</select>
3.2.3 dao接口方法有多个简单类型的参数
List<Student> selectByNameOrAge(@Param(value="name") String name,
@Param("age") Integer age);
<select id="selectByNameOrAge" resultType="com.kgc.pojo.Student">
select * from student where name =#{name} or age = #{age}
</select>
3.2.4 dao接口方法使用一个对象作为参数
- 方法的形参是一个java对象,这个java对象表示多个参数。使用对象的属性值作为参数使用
- java对象:
public class Student {
private Integer id;
private String name;
private String email;
private Integer age;
}
public class QueryParam {
private Object p1;
private Object p2;
}
List<Student> selectByObject(Student student);
List<Student> selectByQueryParam(QueryParam param);
<select id="selectByObject" resultType="com.kgc.pojo.Student">
select * from student where name=#{name} or age=#{age}
</select>
<select id="selectByQueryParam" resultType="com.kgc.pojo.Student">
select * from student where name=#{p1} or age=#{p2}
</select>
<select id="selectByObject" resultType="com.kgc.pojo.Student">
select * from student where
name=#{name,javaType=java.lang.String,jdbcType=varchar}
or
age=#{age,javaType=java.lang.Integer,jdbcType=integer}
</select>
3.2.5 dao接口中多个简单类型的参数,使用位置
List<Student> selectByNameOrAge( String name,Integer age);
<select id="selectByNameOrAge" resultType="com.kgc.pojo.Student">
select * from student where name =#{arg0} or age = #{arg1}
</select>
3.2.6 dao接口参数是一个Map
- map作为dao接口的参数,使用key获取参数值,在mapper文件中,语法格式#{key}
- dao接口中的方法定义:
List<Student> selectStudentByMap(Map<String,Object> map);
<select id="selectStudentByMap" resultType="com.kgc.pojo.Student">
select * from student where name=#{name} or age=#{age}
</select>
@Testpublic void testInsertByMap() throws IOException { SqlSession session = MyBatisUtil.getSqlSession(); StudentDao dao = session.getMapper(StudentDao.class); HashMap<String, Object> data = new HashMap<>(); data.put("name","李四"); data.put("age",14); List<Student> students = dao.selectStudentByMap(data); System.out.println(students); MyBatisUtil.close(session);}
3.3 #和$的区别
3.3.1 #占位符
- 语法:#{字符}
- mybatis处理#{} 使用jdbc对象是PreparedStatement对象
<select id="getStudentById" parameterType="int"
resultType="com.kgc.pojo.Student">
select * from student where id = #{id}
</select>
mybatis创建出PreparedStatement对象,执行sql语句
String sql = "select * from student where id = ?"
PreparedStatement pst = com.PreparedStatement(sql);
pst.setInt(1,1001);//传递参数
ResultSet rs = pst.executeQuery();//执行sql语句
- #{}特点:
- 使用的PreparedStatement对象,执行sql语句,效率高。
- 使用的PreparedStatement对象,能避免sql注入,sql语句执行更安全
- #{}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型有关的
3.3.2 $占位符
-
语法:${字符} -
mybatis执行${}占位符的sql语句
<select id="getStudentById" parameterType="int"
resultType="com.kgc.pojo.Student">
select * from student where id = ${id}
</select>
${}表示字符串的连接,把sql语句的其他内容和${}内容使用字符串(+)连接的方式连在一起
String sql = "select * from student where id = "+"1001";
mybatis创建Statement对象,执行sql语句
Statement stmt = com.createStatement(sql);
ResultSet rs = stmt.executeQuery();
-
${}的特点:
- 使用Statement对象,执行sql语句,效率低
- ${}占位符的值,使用的字符串连接的方式,有sql注入的风险。有代码安全的问题
- ${}数据是原样使用的,不会区分数据类型
-
常
用
作
为
表
名
或
者
列
名
,
在
能
保
证
数
据
安
全
的
情
况
下
使
用
{}常用作为表名或者列名,在能保证数据安全的情况下使用
常用作为表名或者列名,在能保证数据安全的情况下使用{}
-
dao接口中的方法定义:
List<Student> selectStudentOrderByName(@Param("colName")String name);
<select id="selectStudentOrderByName" resultType="com.kgc.pojo.Student">
select * from student order by #{colName} desc
</select>
@Test
public void testInsertByMap() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> students = dao.selectStudentOrderByName("id");
System.out.println(students);
MyBatisUtil.close(session);
}
3.4 封装Mybatis输出结果
- 封装输出结果:MyBatis执行sql语句,得到ResultSet,转为java对象
- 主要使用:resultType和resultMap
3.4.1 resultType
- resultType属性:在执行select时使用,作为标签的属性出现的
- reslutType表示结果类型,mybatis执行sql语句,得到java对象的类型,它的值有两种
- java类型的全限定名称
- 使用别名
- resultType表示java自定义对象
Student getStudentById(Integer id);
<select id="getStudentById" parameterType="int"
resultType="com.kgc.pojo.Student">
select * from student where id = ${id}
</select>
resultType:现在使用java类型的全限定名称,表示的意思是mybatis执行sql语句,把ResultSet中的数据转为Student类型的对象。mybatis会做以下操作:
1.调用com.kgc.pojo.Student的无参构造方法,创建对象
Student student = new Student();//使用反射创建对象
2.同名的列赋值给同名的属性
student.setId(rs.getInt("id"));
studnet.setName(rs.getString("name"));
3.得到java对象,如果dao接口返回值是List类型,mybatis把student对象放入到List集合
所以执行Student student = dao.getStudentById(1001);得到数据库中id=1001这行数据
这行数据的列值,赋给了student对象的属性,你能得到student对象。就相当于id=1001这行数据
- resultType表示简单类型
long countStudent();
<select id="countStudent" resultType="java.lang.Long">
select count(*) from student
</select>
- resultType表示一个Map结构
Map<Object,Object> selectMap(@Param("id") Integer id);
<select id="selectMap" resultType="map">
select * from student where id = #{id}
</select>
3.4.2 resultMap
- resultMap:结果映射。自定义列名和java对象属性的对应关系,常用在列名和属性名不同的情况
- 用法:
- 先定义resultMap标签,指定列名和属性名称对应关系
- 在select标签使用resultMap属性,指定上面定义的resultMap的id值
<resultMap id="StudentMap" type="com.kgc.pojo.Student">
<id column="id" property="cid"/>
<result column="name" property="cname"/>
<result column="email" property="email"/>
<result column="age" property="age"/>
</resultMap>
<select id="getStudentById" resultMap="StudentMap">
select * from student where id = #{id}
</select>
- 复杂的属性:我们需要单独处理的对象或者集合
- association:是resultMap的子元素,用于处理对象
- collection:是resultMap的子元素,用于处理集合
3.5 自定义别名
- mybatis提供的对java类型定义简短、好记的名称
- 自定义别名的步骤:
- 在mybatis主配置文件,使用typeAliase标签声明别名
- 在mapper文件中,resultType=“别名”
- 第一种方式:
- 声明别名(mybatis主配置文件):
<typeAliases>
<typeAlias type="com.kgc.pojo.Student" alias="stu"/>
</typeAliases>
<select id="getStudentById" parameterType="int"resultType="stu"> select * from student where id = ${id}</select>
- 第二种方式:
- 声明别名(mybatis主配置文件):
<typeAliases>
<package name="com.kgc.pojo"/>
</typeAliases>
<select id="getStudentById" parameterType="int"resultType="student">
select * from student where id = ${id}
</select>
3.6 列名和java对象属性名称不一样解决方式
- 使用resultMap:自定义列名和属性名称对应关系
- 使用resultType:使用列的别名,让别名和java属性名称一样
<select id="getStudentById" resultType="com.kgc.pojo.Student">
select id as cid,name cname,email,age from student where id = #{id}
</select>
3.7 like
List<Student> selectLikeOne(@Param("name") String name);
<select id="selectLikeOne" resultType="com.kgc.pojo.Student"> select * from student where name like #{name}</select>
@Testpublic void testInsertById() throws IOException { SqlSession session = MyBatisUtil.getSqlSession(); StudentDao dao = session.getMapper(StudentDao.class); String name = "%李%"; List<Student> students = dao.selectLikeOne(name); MyBatisUtil.close(session);}
<select id="selectLikeOne" resultType="com.kgc.pojo.Student"> select * from student where name like concat('%',#{name},'%')</select>
@Test
public void testInsertById() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
String name = "李";
List<Student> students = dao.selectLikeOne(name);
MyBatisUtil.close(session);
}
第四章 动态sql
- 说明是动态sql:同一个dao方法,根据不同的条件可以表示不同的sql语句,主要是where、set部分有变化
- 使用mybatis提供的标签,实现动态sql的能力,主要是if、where、set、foreach,sql。
- 使用动态sql的时候,dao方法的形参使用java对象
- 一般在多条件查询时使用动态sql
4.1 if标签
<if test="boolean判断结果">
sql代码
</if>
List<Student> selectIf(Student student);
<select id="selectIf" resultType="com.kgc.pojo.Student">
select * from student
where id =-1
<if test="name!=null and name!=''">
or name = #{name}
</if>
<if test="age>0">
or age = #{age}
</if>
</select>
4.2 where标签
-
使用if标签时,容易引起sql语句语法错误,使用where标签解决if产生的语法问题 -
使用时where里面是一个或多个if标签,当有一个if标签判断条件为true,where标签会转为WHERE关键字附加到sql语句的后面,如果if没有一个条件为true,就会忽略where和里面的if -
if条件满足的话where标签会自动删除和最近的or或者and -
语法:
<where>
<if test="条件1">sql语句1</if>
<if test="条件2">sql语句2</if>
</where>
List<Student> selectWhere(Student student);
<select id="selectWhere" resultType="com.kgc.pojo.Student">
select * from student
<where>
<if test="name!=null and name!=''">
or name = #{name}
</if>
<if test="age>0">
or age = #{age}
</if>
</where>
</select>
4.3 set标签
-
用于在update语句,一般配合if标签使用 -
使用时set里面是一个或多个if标签,当有一个if标签判断条件为true,set标签会转为SET关键字附加到sql语句的后面,如果if没有一个条件为true,就会忽略set和里面的if -
if条件满足的话where标签会自动删除和最近的 ‘,’ -
语法:
<set>
<if test="条件1">sql语句1</if>
<if test="条件2">sql语句2</if>
where sql语句
</set>
int updateSet(Student student);
<select id="updateSet" >
select * from student
<set>
<if test="name!=null and name!=''">
name = #{name},
</if>
<if test="age>0">
or age = #{age},
</if>
where id =#{id}
</set>
</select>
4.4 foreach标签
- 使用foreach可以循环数组,list集合,一般使用在in语句中
- 语法:
<foreach collection= "集合类型" open="开始的字符" close="结束的字符"
item="集合中的成员" separator="集合成员之间的分隔符">
#{item的值}
</foreach>
标签属性:
collection:表示,循环的对象是数组,还是list集合。如果dao接口方法的形参是数组, collection="array",如果dao接口的形参是List,collection="list"
open:循环开始时的字符。 sql.append("(");
close:循环结束时字符。 sql.append(")");
item:集合成员,自定义的变量。Integer item = idList.get(i);//item是集合成员
separator:集合成员之间的分隔符。 sql.append(",");//集合成员之间的分隔符
#{item的值}:获取集合成员的值。
List<Student> selectForeach(List<Integer> id);
<select id="selectForeach" resultType="com.kgc.pojo.Student">
select * from student
<if test="id!=null and id.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</if>
</select>
List<Student> selectForeach(List<Student> students);
<select id="selectForeach" resultType="com.kgc.pojo.Student">
select * from student
<if test="id!=null and id.size>0">
where id in
<foreach collection="list" open="(" close=")" separator="," item="stu">
#{stu.id}
</foreach>
</if>
</select>
4.5 choose标签
<choose>
<when test="条件1">
sql语句
</when>
<when test="条件2">
sql语句
</when>
<otherwise>
sql语句
</otherwise>
</choose>
List<Student> getStudentChoose(Map<String,String> map);
<select id="getStudentChoose" resultType="com.kgc.pojo.Student">
select * from Student
<where>
<choose>
<when test="name!=null and name!=''">
name like concat('%',#{name},'%')
</when>
<when test="email!=null and email!=''">
email like concat('%',#{email},'%')
</when>
<otherwise>
age like concat('%',#{age},'%')
</otherwise>
</choose>
</where>
</select>
4.6 trim标签
- trim标签可以替代我们的set或者where标签,也是配合if标签使用
- 属性:
- prefix:给sql语句拼接的前缀
- suffix:给sql语句拼接的后缀
- prefixOverrides:前缀拼接字符或者关键字
- suffixOverrides:后缀拼接字符或者关键字
- where语法:
<select id="getUserList" resultType="User">
SELECT * FROM smbms_user
<trim prefix="where" prefixOverrides="and|or">
<if test="name != null and name != ''">
AND userName LIKE CONCAT('%',#{name},'%')
</if>
<if test="rid != null">
AND userRole = #{rid}
</if>
</trim>
</select>
<update id="updatePerson" parameterType="com.kgc.pojo.Person">
update person
<trim prefix="set" prefixOverrides="," suffix="where id=#{id}" >
<if test="name!=null and name!=''">,name=#{name}</if>
<if test="age!=null and age!=''">,age=#{age}</if>
<if test="address!=null and address!=''">,address=#{address}</if>
<if test="dept_id!=null and dept_id!=''">,dept_id=#{dept_id}</if>
</trim>
</update>
4.7 sql标签
- sql标签表示一段sql代码,可以是表名,几个字段,where条件都可以,可以在其他地方复用sql标签的内容
- 使用方式:
1. 在mapper文件中定义,sql代码片段,<sql id="唯一字符串">部分sql语句</sql>
2. 在其他的位置,使用include标签引用某个代码片段
<sql id="student">
select * from student
</sql>
<select id="getStudentById" resultMap="StudentMap">
<include refid="student"/>
where id = #{id}
</select>
第五章 MyBatis配置文件
- mybatis配置文件两大类:1.mybatis主配置文件;2.mybatis的mapper文件
- mybatis主配置文件,提供mybatis全局配置的。包括的内容有日志、数据源、mapper文件位置
- mapper文件:写sql语句的。一个表一个mapper文件
5.1 settings部分
- settings是mybatis的全局设置,影响整个mybatis的运行。这个设置一般使用默认值就可以了。
<settings>
<setting name="cacheEnabled" value="true"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="multipleResultSetsEnabled" value="true"/>
<setting name="useColumnLabel" value="true"/>
<setting name="useGeneratedKeys" value="false"/>
<setting name="autoMappingBehavior" value="PARTIAL"/>
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="defaultFetchSize" value="100"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
5.2 typeAliase 别名
<typeAliases>
<typeAlias type="com.kgc.pojo.Student" alias="stu"/>
<package name="com.kgc.pojo"/>
</typeAliases>
5.3 配置环境
- environments:环境标签,在它里面可以设置多个environment
- 属性:default:必须是某个environment的id属性值,表示mybatis默认连接的数据库
- environment:表示一个数据库的连接信息
- transactionManager:事务管理器
- 属性:type表示事务管理器的类型
- JDBC:使用Connection对象,由mybatis自己完成事务的处理
- MANAGED:管理,表示把事务的处理交给容器实现(由其他软件完成事务的提交,回滚)
- dataSource:数据源,创建的Connection对象,连接数据库
- 属性:type表示数据源的类型
- POOLED:mybatis会在内存中创建PooledDataSource类,管理多个Connection连接对象,使用的连接池
- UNPOOLED:不使用连接池,mybatis创建一个UnPooledDataSource这个类,每次执行sql语句先创建Connection对象,再执行sql语句,最后关闭Connection
- JHDI:java的命名和目录服务
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/springdb"/>
<property name="username" value="root"/>
<property name="password" value="ok"/>
</dataSource>
</environment>
</environments>
5.4 使用数据库属性配置文件(*)
- 需要把数据库的配置信息放到一个单独文件中,独立管理。这个文件扩展名是properties,在这个文件中,使用自定义的key=value的格式表示数据
- 使用步骤:
- 在resources目录中,创建XXX.properties
- 在文件中,使用key=value的格式定义数据
- 例如:jdbc.url=jdbc:mysql://localhost:3306/springdb
- 在mybatis主配置文件,使用properties标签引用外部的属性配置文件
- 在使用值的位置,使用${key}获取key对应的value(等号右侧的值)
- 例子:
- db.properties:
driver=com.mysql.jdbc.Driverurl=jdbc:mysql://localhost:3306/dbuseUnicode=true&characterEncoding=utf-8username=rootpassword=ok
<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>
5.5 mapper 标签(*)
- 使用mapper指定其他mapper文件的位置
- mapper标签使用的格式有两个常用的方式:
<mappers> <mapper resource="com/kgc/dao/StudentDao.xml"/> <package name="com.kgc.dao"/></mappers>
第六章 pageHelper(分页)
-
pageHelper做数据分页的,在你的select语句后面加入分页的sql内容,如果你使用的mysql数据库,他就会在select * from student后面加入 limit 语句。 -
使用步骤:
- 加入依赖pageHelper依赖
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version></dependency>
- 在mapper主配置文件,加入plugin声明
在<environments>之前加入<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"/></plugins>
- 在select语句之前,调用PageHelper.startPage(页码,每页条数)
-
对比:
- 没有使用PageHelper输出:select * from student order by id
- 使用PageHelper输出:select * from student order by id limit ?
-
例子: -
dao接口:
<select id="getStudent" resultType="com.kgc.pojo.Student"> select * from student order by id</select>
@Testpublic void textPageHelper() throws IOException { SqlSession session = MyBatisUtil.getSqlSession(); StudentDao dao = session.getMapper(StudentDao.class);
|