MyBatis
Mybatis是基于JDBC操作数据库的半ORM持久层框架,是apache的开源项目。主要提供了简便的在程序中操作数据库的功能。
ORM(Object Relational Mapping):对象关系映射,数据库表对象和Java对象之间的映射关系,将数据库的操作转化为对Java对象操作。
半ORM:操作数据库时,需要手动编写SQL来完成,无法像全ORM框架(如Hibernate)那样直接根据对象关系模型获取。因此,MyBatis被称为半自动ORM映射工具。
1.回顾JDBC操作数据库的过程
- 创建数据库的连接池DataSource(建立和管理数据库连接)
- 通过DataSource获取数据库连接对象Connection
- 编写SQL语句(包含占位符)。
- 通过Connection和SQL语句创建操作命令对象Statement
- 对占位符内容进行替换和填充。
- 使用Statement对象执行SQL语句。
- 接收数据库返回结果。
- 对数据进行业务处理
- 释放资源。
以上操作流程繁琐,每操作一次都需要获取数据库连接对象、释放资源等操作,因此为了简便流程,就有大佬开发了MyBaits框架。
2.MyBatis的组成部分
Data Access Objects(DAO):提供了一种使用接口操作数据的方式。
SQL Maps:使用XML文件配置(和Data Access Objects对应 )来实现Java对象和SQL语句的映射,将代码和SQL语句分离,使得代码更加清晰简洁,力与维护。
底层原理: MyBatis 会为接口创建一个代理对象,当调用接口中的方法时,MyBatis 就会根据方法名找到对应的 SQL 语句并执行。最后将结果映射到Java对象上。(底层原理还须深究)
3.如何使用MyBatis操作数据库
1.创建SpringBoot项目并引入依赖
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>2.3.1</version>
<scope>test</scope>
</dependency>
2.配置数据库连接
#配置数据库连接信息
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/blog_system?characterEncoding=utf8&useSSL=false
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
#配置加载的映射文件路径
mybatis:
mapper-locations: classpath:mapper/**Mapper.xml
#配置打印SQL语句日志
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
3.定义数据库表映射Java对象的类
@Data
public class User {
private Integer id;
private String username;
private String nickname;
private String password;
private Date createtime;
private Date updatetime;
private Integer state;
}
4.定义操作数据库的接口
@Mapper
public interface UserMapper {
User getUserById(@Param("id") Integer uid);
}
@Mapper:指示MyBatis框架为该接口创建代理对象,从而将该接口的方法映射到数据库操作。
@Param:表示将传入的参数uid,插入到查询语句中#{id}占位符中。
5.编写xml接口映射文件
<?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:表示该映射文件所对应的接口 -->
<mapper namespace="com.example.demo.mapper.UserMapper">
<!-- id:表示和接口对应的方法 resultType:返回数据对象映射,根据字段名填充User对象 -->
<select id="getUserById" resultType="com.example.demo.model.User">
select * from user where id = #{id}
</select>
</mapper>
6.调用接口实现对数据库的操作
void getUserById() {
User user = userMapper.getUserById(1);
System.out.println(user);
}
4.xml中不同操作语句的属性介绍
4.1select
<select>元素用于定义查询操作,它支持以下属性:
id:必选属性,用于唯一标识该元素。
parameterType:可选属性,指定传入参数的类型。这是在MyBatis 3.4.0版本之后被弃用的,推荐在接口方法上使用@Param注解。
resultType:可选属性,指定查询结果的类型。
resultMap:可选属性,指定结果映射的ID,用于将查询结果映射到Java对象。
flushCache:可选属性,用于指定是否刷新缓存。如果设置为true,则在查询操作后刷新缓存。
useCache:可选属性,用于指定是否使用缓存。如果设置为false,则不使用缓存。
timeout:可选属性,用于指定查询操作的超时时间(以秒为单位)。
fetchSize:可选属性,用于指定每次从数据库获取的行数。
statement:可选属性,用于指定要执行的SQL语句。
4.2insert
<insert>元素用于定义插入操作。它支持以下属性:
id:必选属性,用于唯一标识该元素。
parameterType:可选属性,指定传入参数的类型。这是在MyBatis 3.4.0版本之后被弃用的,推荐在接口方法上使用@Param注解。
keyProperty:可选属性,用于指定将插入的记录的某个属性值设置到传入的参数对象的哪个属性中。
keyColumn:可选属性,用于指定数据库表中的哪个字段的值会被设置到传入的参数对象的keyProperty属性中。
useGeneratedKeys:可选属性,用于指定是否使用数据库生成的键。如果设置为true,则MyBatis会获取数据库生成的主键,并将其设置到传入的参数对象的keyProperty属性中。
timestamp:可选属性,用于指定插入操作的时间戳。可以设置为当前时间戳或指定一个特定的时间戳。
flushCache:可选属性,用于指定是否刷新缓存。如果设置为true,则在插入操作后刷新缓存。
statement:可选属性,用于指定要执行的SQL语句。
keyGenerator:可选属性,用于指定主键生成器。
4.3update、delete
1. id:必选属性,用于唯一标识该元素。
2. parameterType:可选属性,指定传入参数的类型。这是在MyBatis 3.4.0版本之后被弃用的,推荐在接口方法上使用`@Param`注解。
3. flushCache:可选属性,用于指定是否刷新缓存。如果设置为`true`,则在更新操作后刷新缓存。
4. statement:可选属性,用于指定要执行的SQL语句。
5.关于resultMap
表字段和Java类的字段不相同,可使用resultMap来解决。
<resultMap id="user" type="com.example.demo.model.User">
<id property="id" column="id" />
<result property="userName" column="username" />
<result property="password" column="password"/>
<result property="nickname" column="nickname"/>
<result property="createTime" column="createtime"/>
<result property="updateTime" column="updatetime"/>
<result property="state" column="state"></result>
</resultMap>
<select id="getUserById" resultMap="user">
select * from user where id = ${id}
</select>
5.参数占位符
- #{}:预编译处理,Mybatis处理#{}时,会将#{}替换为?号,使用PreparedStatement的set方法来赋值。
- ${}:将参数直接插入到sql语句中。如下图
需要注意的是,#{}和${}在一条sql语句中不能同时使用,否则会导致出错。
5.1关于模糊查询
<select id="selectArticleByName" resultType="com.example.demo.model.Article">
SELECT * FROM article
WHERE article_name LIKE '%#{articleName}%'
</select>
使用该种方式会报错。
<select id="selectArticleByName" resultType="com.example.demo.model.Article">
SELECT * FROM article
WHERE article_name LIKE CONCAT('%', #{articleName}, '%')
</select>
6.动态SQL
动态 SQL 是 MyBatis 的强大特性之一。
建立一张表:
create table if not exists user(
id int primary key auto_increment,
username varchar(32) not null,
password varchar(32) not null,
avatar varchar(32),
state int default 1
)
6.1if和trim标签
if:用于是否需要插入语句
trim:用于添加前缀或后缀,删除前缀或后缀
<insert id="addUser">
insert into user
<trim prefix="(" suffix=")" suffixOverrides=",">
username,
password,
<if test="avatar != null">
avatar,
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
#{username},
#{password},
<if test="avatar != null">
#{avatar}
</if>
</trim>
</insert>
prefix:添加前缀
suffix:添加后缀
suffixOverrides:删除某个后缀
prefixOverrides:删除某个前缀
6.2where标签
用于是否需要添加where语句,当where语句中存在内容则添加where否则不添加where
<select id="queryUserByUsername" resultType="com.example.demo.model.User">
select * from user
<where>
<if test="username != null">
and username = #{username}
</if>
</where>
</select>
- where标签可以删除最前面的条件关键字
- 根据where标签的内容决定是否要添加where语句
6.3set标签
用于生成set关键字,并去除最后一个,
<update id="updateUserById">
update user
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="avatar != null">
avatar = #{avatar},
</if>
</set>
where id = #{id}
</update>
6.4 foreach标签
循环的拼接字符串。
可用于批量删除(根据id列表批量删除用户…)。
<delete id="deleteUserByListId">
delete from user
where
id
in
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
collection:循环的集合
item:当前循环的元素
open:生成的字符串的开始部分。
close:生成的字符串的结尾部分。
批量删除(根据id列表批量删除用户…)。
<delete id="deleteUserByListId">
delete from user
where
id
in
<foreach collection="ids" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
collection:循环的集合
item:当前循环的元素
open:生成的字符串的开始部分。
close:生成的字符串的结尾部分。
separator:循环元素之间的分隔符。