ActiveRecord介绍
- 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录; 通常表的每个字段在类中都有相应的 Field;
- ActiveRecord 负责把自己持久化. 在 ActiveRecord 中封装了对数据库的访问,通过对象自己实现 CRUD,实现优雅的数据库操作。
- ActiveRecord 也封装了部分业务逻辑。可以作为业务对象使用。
AR 之 insert
dept 表设计:
create database dept;
use dept;
CREATE TABLE `dept` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(50) DEFAULT NULL,
`mobile` varchar(50) DEFAULT NULL,
`manager` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
更改springboot配置文件
代码模板:
将连接信息改为自己的
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/dept
username: root
password: root
#开启日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
实体类
必须继承 Model,Model 定义了表的 CRUD 方法,Dept 属性名和列名是一样的。
mapper
创建DeptMapper接口,继承BaseMapper
不使用 mapper,也需要定义这个类,Mybatis-Plus通过 mapper 获取到表的结构;
不定义时,Mybatis-Plus报错无法获取表的结构信息。
接下来测试AR的CRUD
AR 之 Insert
返回值是 boolean,true 添加成功。没有添加记录是 false。
日志:
数据库:
AR 之 update
创建实体对象,对要更新的属性赋值,null 的属性不更新,根据主键更新记录。
返回值是 boolean,true 更新成功。没有更新记录是 false。
日志:
数据库:
AR 之 delete
使用主键作为删除条件,deleteById()参数是主键值,sql 语句条件是 where id=1。
返回值始终是 true。通过源码查看:
可以看到deleteById内部调用了delBool
删除返回值判断条件是 result >=0 ,只有 sql 语法是正确的,返回就是 true。和删除记录的数量无关。
日志:
此时数据库已经为空!
为了方便演示后面的查询操作,将 AR 之 Insert的操作多运行几次,保证数据库有数据
这里我就运行3次
AR 之 select
对象调用 selectById()
对象提供主键值,调用 selectById()无参数,使用 id=2 作为查询条件,返回值是查询的结果对象:
没有查询到对象不会报错,返回是 null:
selectById(主键)
不需要依赖对象提供主键值,直接selectById(主键值)
创建对象,不设值 id 主键值, selectById 的参数是查询条件,和对象的属性值
无关。返回值是结果对象,id 不存在返回 null。
不提供主键 id 值会报错:
报错如下:
com.baomidou.mybatisplus.core.exceptions.MybatisPlusException: selectById primaryKey is null.
如图:
selectAll
查询所有数据,返回值是List集合
日志:
查询操作是最多的,其它方法的使用在介绍 Wrapper 对象后讲解
表和列
主键 ,TableName, TableId
主键类型
IdType 枚举类,主键定义如下:
- 0.none 没有主键
- 1.auto 自动增长(mysql, sql server)
- 2.input 手工输入
- 3.id_worker: 实体类用 Long id , 表的列用 bigint ,int 类型大小不够
- 4.id_worker_str 实体类使用 String id, 表的列使用 varchar 50
- 5.uuid 实体类使用 String id, 列使用 varchar 50
- id_worker: Twitter 雪花算法-分布式 ID
指定表名
定义实体类,默认的表名和实体类同名;如果不一致,在实体类定义上面使用@TableName 说明表名称。
例如:@TableName(value=”数据库表名”)
步骤:
表
CREATE TABLE `user_address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`city` varchar(50) DEFAULT NULL,
`street` varchar(255) DEFAULT NULL,
`zipcode` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
实体类
创建实体类UserAddress
mapper
创建UserAddressMapper接口
测试
注入mapper对象
insert 记录:
日志:
指定列名
表
CREATE TABLE `salary` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`empid` int(11) NOT NULL,
`empsal` float(10,2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
实体类
mapper
测试
注入mapper对象
添加
日志
驼峰命名
列名使用下划线,属性名是驼峰命名方式。MyBatis 默认支持这种规则。
表定义
CREATE TABLE `customer` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`cust_name` varchar(50) DEFAULT NULL,
`cust_age` int(11) DEFAULT NULL,
`cust_email` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
实体类
mapper
测试
注入mapper对象
添加
日志
数据库
自定义 sql
定义表
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(80) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`email` varchar(80) DEFAULT NULL,
`status` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
insert into student values(null,'张三',22,'zs@sina.com',1);
实体
创建 Mapper
新建 sql 映射 xml 文件
配置 xml 文件位置
application.yml
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
mapper-locations: classpath*:xml/*Mapper.xml
测试
日志:
查询和分页
查询构造器:Wrapper
QueryWrapper(LambdaQueryWrapper) 和UpdateWrapper(LambdaUpdateWrapper)的父类用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件. MP3.x开始支持lambda表达式,LambdaQueryWrapper,LambdaUpdateWrapper支持 lambda表达式的构造查询条件。
条件:
条件 | 说明 |
---|---|
allEq | 基于 map 的相等 |
eq | 等于 = |
ne | 不等于 <> |
gt | 大于 > |
ge | 大于等于 >= |
lt | 小于 < |
le | 小于等于 <= |
between | BETWEEN 值1 AND 值2 |
norBetween | NOT BETWEEN 值1 AND 值2 |
like | LIKE ‘%值%’ |
notLike | NOT LIKE ‘%值%’ |
likeLeft | LIKE ‘%值’ |
likeRight | LIKE ‘值%’ |
isNull | 字段 IS NULL |
isNotNull | 字段 IS NOT NULL |
in | 字段 IN (value1, value2, …) |
notIn | 字段 NOT IN (value1, value2, …) |
inSql | 字段 IN ( sql 语句 ) |
notInSql | 字段 NOT IN ( sql 语句 ) |
groupBy | GROUP BY 字段 |
orderByAsc | 升序 ORDER BY 字段, … ASC |
orderByDesc | 降序 ORDER BY 字段, … DESC |
orderBy | 自定义字段排序 |
having | 条件分组 |
or | OR 语句,拼接 + OR 字段=值 |
and | AND 语句,拼接 + AND 字段=值 |
apply | 拼接 sql |
last | 在 sql 语句后拼接自定义条件 |
exists | 拼接 EXISTS ( sql 语句 ) |
notExists | 拼接 NOT EXISTS ( sql 语句 ) |
nested | 正常嵌套 不带 AND 或者 OR |
QueryWrapper:查询条件封装类
方法 | 说明 |
---|---|
select | 设置查询字段 select 后面的内容 |
UpdateWrapper:更新条件封装类
方法 | 说明 |
---|---|
set | 设置要更新的字段,MP 拼接 sql 语句 |
setSql | 参数是 sql 语句,MP 不在处理语句 |
查询
Student 表:初始数据
allEq
以 Map 为参数条件
a) 条件:name 是张三,age 是 22
日志:where name=”张三” and age = 22
b) 查询条件有 null
true 日志:
false日志:
eq
name 等于李四
日志
ne
ne 不等于
日志
gt
gt 大于
日志
ge
ge 大于等于
日志
lt
lt 小于
日志
le
le 小于等于 <=
日志
between
between 在两个值范围之间
日志
notBetween
notBetween 不在两个值范围之间
日志
like , notLike
like 匹配值 “%值%”
notLike 不匹配 “%值%”
日志
likeLeft, likeRight
likeLeft 匹配 like “%值”
likeRight 匹配 like “值%”
日志
isNull , isNotNull
isNull 判断字段值为 null
isNotNull 字段值不为 null
日志
in , notIn
in 后面值列表, 在列表中都是符合条件的。
notIn 不在列表中的
将values存在list集合的方式
日志
inSql, notInSql
inSql 常用来做子查询 类似 in()
notInSql 类似 notIn()
日志
groupBy
groupBy 基于多个字段分组
日志
orderByAsc ,orderyByDesc , orderBy
orderByAsc 按字段升序
orderByDesc 按字段降序
orderBy 每个字段指定排序方向
日志
or , and
or 连接条件用 or,默认是 and
and 连接条件用 and
日志:
last
last 拼接 sql 语句
日志:
exists ,notExists
exists 拼接 EXISTS ( sql 语句 )
notExists 是 exists 的相反操作
日志:
分页
前提: 配置分页插件,实现物理分页。默认是内存分页
分页查询:
日志:
输出:
MP 生成器
准备条件:
<!-- 模板引擎 -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId>
<version>2.0</version>
</dependency>
创建生成类:
全局配置
数据源配置
其它配置