0 简介
MyBatis官网介绍
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
1 准备
1.1 创建一个空的SpringBoot项目
创建一个SpringBoot的项目,配置好相关依赖。
1.2 配置SpringBoot项目相关信息
空项目床架完成后,配置properties配置文件,连接mysql数据库。
创建pojo,mapper包,在两个包下分别创建Emp.java,EmpMapper.java接口。
Emp.java
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
private Integer id;//ID
private String username;//用户名
private String password;//密码
private String name;//姓名
private Short gender;//性别,1:男,2:女
private String image;//图像
private Short job;//职位,说明,1:班主任,2:讲师,3:学工主管4 教研主管, 5 咨询师
private LocalDate entryDate;//入职时间
private Integer deptId;//部门ID
private LocalDateTime createTime;//创建时间
private LocalDateTime updateTime;//修改时间
}
EmpMapper.java
@Mapper
public interface EmpMapper {
}
SpringBoot项目结构
1.3 创建数据库
-- 部门管理
create table dept(
id int unsigned primary key auto_increment comment '主键ID',
name varchar(10) not null unique comment '部门名称',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间'
) comment '部门表';
insert into dept (id, name, create_time, update_time) values(1,'学工部',now(),now()),(2,'教研部',now(),now()),(3,'咨询部',now(),now()), (4,'就业部',now(),now()),(5,'人事部',now(),now());
-- 员工管理
create table emp (
id int unsigned primary key auto_increment comment 'ID',
username varchar(20) not null unique comment '用户名',
password varchar(32) default '123456' comment '密码',
name varchar(10) not null comment '姓名',
gender tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
image varchar(300) comment '图像',
job tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
entrydate date comment '入职时间',
dept_id int unsigned comment '部门ID',
create_time datetime not null comment '创建时间',
update_time datetime not null comment '修改时间'
) comment '员工表';
INSERT INTO emp
(id, username, password, name, gender, image, job, entrydate,dept_id, create_time, update_time) VALUES
(1,'jinyong','123456','金庸',1,'1.jpg',4,'2000-01-01',2,now(),now()),
(2,'zhangwuji','123456','张无忌',1,'2.jpg',2,'2015-01-01',2,now(),now()),
(3,'yangxiao','123456','杨逍',1,'3.jpg',2,'2008-05-01',2,now(),now()),
(4,'weiyixiao','123456','韦一笑',1,'4.jpg',2,'2007-01-01',2,now(),now()),
(5,'changyuchun','123456','常遇春',1,'5.jpg',2,'2012-12-05',2,now(),now()),
(6,'xiaozhao','123456','小昭',2,'6.jpg',3,'2013-09-05',1,now(),now()),
(7,'jixiaofu','123456','纪晓芙',2,'7.jpg',1,'2005-08-01',1,now(),now()),
(8,'zhouzhiruo','123456','周芷若',2,'8.jpg',1,'2014-11-09',1,now(),now()),
(9,'dingminjun','123456','丁敏君',2,'9.jpg',1,'2011-03-11',1,now(),now()),
(10,'zhaomin','123456','赵敏',2,'10.jpg',1,'2013-09-05',1,now(),now()),
(11,'luzhangke','123456','鹿杖客',1,'11.jpg',5,'2007-02-01',3,now(),now()),
(12,'hebiweng','123456','鹤笔翁',1,'12.jpg',5,'2008-08-18',3,now(),now()),
(13,'fangdongbai','123456','方东白',1,'13.jpg',5,'2012-11-01',3,now(),now()),
(14,'zhangsanfeng','123456','张三丰',1,'14.jpg',2,'2002-08-01',2,now(),now()),
(15,'yulianzhou','123456','俞莲舟',1,'15.jpg',2,'2011-05-01',2,now(),now()),
(16,'songyuanqiao','123456','宋远桥',1,'16.jpg',2,'2010-01-01',2,now(),now()),
(17,'chenyouliang','123456','陈友谅',1,'17.jpg',NULL,'2015-03-21',NULL,now(),now());
idea连接mysql数据库
2 MyBatis基于注解开发
2.1 select语句
在EmpMapper.java接口中写入:
@Mapper
public interface EmpMapper {
@Select("select `id`, `username`, `password`, `name`, `gender`, `image`, `job`, `entrydate` as `entryDate`, `dept_id` as `deptId`, `create_time` as `createTime`, `update_time` as `updateTime` from emp")
public List<Emp> list();
}
直接在方法上添加@Select()注解即可,括号内填写查询语句,由于数据库中的字段名与我们的Emp.java类中的属性名不一致,所以,我们需要设置别名,以便MyBatis能顺利将查询出的数据封装到Emp.对象中。
测试:
@SpringBootTest
class SprintbootMybatis02ApplicationTests {
//Spring的依赖注入机制
//过去我们创建对象为 private EmpMapper empMapper = new EmpMapperImpl();
//需要有个实现EmpMapper接口的实现类,而引入Spring后,则不需要自己手动创建对象,直接添加
//@Autowired注解,Spring会将实现EmpMapper接口的类的对象直接创建好,然后赋值给empMapper成员。
//当然要实现此功能,需要在EmpMapper.java接口上添加@Mapper注解,Spring才会控制反转,将该类的对象创建过程由Spring来控制
@Autowired
private EmpMapper empMapper;
@Test
public void testListEmp(){
for (Emp emp : empMapper.list()) {
System.out.println(emp);
}
}
}
结果:
2.2 delete语句
@Mapper
public interface EmpMapper {
@Select("select `id`, `username`, `password`, `name`, `gender`, `image`, `job`, `entrydate` as `entryDate`, `dept_id` as `deptId`, `create_time` as `createTime`, `update_time` as `updateTime` from emp")
public List<Emp> list();
//由于删除的记录不是固定的,我们不能给写死,需要传递一个参数,来实现删除指定id记录。
//这里有两种方式:
//方式一:@Delete("delete from emp where id = ${id}")
//这种是拼接字符串,会有sql注入风险,一般不用
//方式二:@Delete("delete from emp where id = #{id}")
//预编译sql,推荐使用
//#{...}中的变量一般与对应方法中参数变量名字相一致
@Delete("delete from emp where id = #{id}")
public int delete(Integer id);
}
2.3 insert语句和update语句
@Mapper
public interface EmpMapper {
@Select("select `id`, `username`, `password`, `name`, `gender`, `image`, `job`, `entrydate` as `entryDate`, `dept_id` as `deptId`, `create_time` as `createTime`, `update_time` as `updateTime` from emp")
public List<Emp> list();
@Delete("delete from emp where id = #{id}")
public int delete(Integer id);
// @Results({
// @Result(column = "dept_id",property = "deptId"),
// @Result(column = "create_time",property = "createTime"),
// @Result(column = "update_time",property = "updateTime"),
// @Result(column = "entrydate",property = "entryDate")
// })//数据库中表的字段与类中的属性名不一致,可以采用映射的方式
@Select("select * from emp where id = #{id}")
public Emp queryEmpById(Integer id);
@Options(keyProperty = "id",useGeneratedKeys = true)//返回自动生成的主键,并放入emp对象中
@Insert("insert into emp(id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time)\n" +
"values (#{id},#{username},#{password},#{name},#{gender},#{image},#{job},#{entryDate},#{deptId},#{createTime},#{updateTime})")
public int insertEmp(Emp emp);
//当参数变量过多时,我们可以采用封装的思想,将参数封装到类中
@Update("update emp set username = #{username},password=#{password},name = #{name},gender=#{gender},image=#{image}, job=#{job},entrydate=#{entryDate},dept_id=#{deptId},create_time=#{createTime},update_time=#{updateTime} where id=#{id}")
public int update(Emp emp);
}
3 MyBatis基于XML开发
3.1 配置
在resources下创建com/xiaoyan/mapper结构的文件,这里要与src下的EmpMapper所在的包结构对应命名。
然后在目录下床架一个EmpMapper.xml映射文件。
3.2 properties配置文件
添加最后两行,可以在控制台输出执行的sql语句
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.username=root
spring.datasource.password=123456
# 在application.properties中添加:开启mybatis驼峰命名方式映射
#该方式有个严格的前提,数据库中的命名方式为x_yz,java类中的属性命名xYzmn
mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
3.3 mybaitsx插件
可以使用该插件实现mapper中方法的快速定位。在file->setting->plugins中直接搜索即可。
3.3 编写EmpMapper.xml映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace命名空间需要与对应方法所在包结构一致-->
<mapper namespace="com.xiaoyan.mapper.EmpMapper">
</mapper>
3.4 编写动态SQL
原有的select条件查询语句
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp
where name like concat('%',#{name},'%')
and gender = #{gender}
and entrydate between #{begin} and #{end}
order by update_time desc
</select>
动态sql语句
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp
where
<if test="name != null">
name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
order by update_time desc
</select>
优化:
<where>
只会在子元素有内容的情况下才插入where子句,而且会自动去除子句的开头的AND或OR
<select id="list" resultType="com.itheima.pojo.Emp">
select * from emp
<where>
<!-- if做为where标签的子元素 -->
<if test="name != null">
and name like concat('%',#{name},'%')
</if>
<if test="gender != null">
and gender = #{gender}
</if>
<if test="begin != null and end != null">
and entrydate between #{begin} and #{end}
</if>
</where>
order by update_time desc
</select>