0 前置数据
首先创建这样一张数据表
CREATE TABLE
user
(id
INT(11) NOT NULL,username
VARCHAR(50),gendar
CHAR(2) ,remark
VARCHAR(50));
并向表中插入多条数据
1 简单查询
对于简单的查询,例如根据某一个字段或ID进行查询,使用 MyBatisPlus 可以直接进行。
1.1 根据ID查询
代码语言:txt
**复制
@Test
public void getUser(){
User user = userMapper.selectById(1);
System.out.println(user);
}
效果等同于如下SQL语句
1.2 根据某一个字段进行查询
代码语言:txt
**复制
@Test
public void getUserByField(){
Map<String, Object> map = new HashMap<>();
map.put("id", "1");
List<User> user = userMapper.selectByMap(map);
user.forEach(System.out::println);
}
因为只使用了一个属性进行查询,效果也和 1.1 中相同。
1.3 根据多个字段进行联合查询
代码语言:txt
@Test
public void getUserByFields(){
Map<String, Object> map = new HashMap<>();
map.put("id", "1");
map.put("username", "admin");
List<User> user = userMapper.selectByMap(map);
user.forEach(System.out::println);
}
多个字段的查询,等同于如下效果
2 条件查询
2.1 条件构造器 QueryWrapper 对象
那么如果想要实现复杂一些的查询呢,应该怎么做?
MyBatisPlus 中的 QueryWrapper 对象,可以让用户自由构造SQL查询条件,可以快速上手并且有效提高开发效率。
表达式 | 含义 |
---|---|
or | 条件或 |
and | 条件且 |
in | 在...中 |
notin | 不在...中 |
eq | 等于 |
ne | 不等于 |
gt | 大于 |
ge | 大于等于 |
lt | 小于 |
le | 小于等于 |
between | 在...范围 |
like | 模糊查询,含有 |
notlike | 模糊查询,不含有 |
groupBy | 分组 |
having | 分组后筛选 |
orderBy | 数据排序 |
isNull | 空值判断 |
isNotNull | 非空判断 |
exists | 存在 |
notExists | 不存在 |
需要注意的是:
条件查询中的列名,必须是数据库中的列名,而不是我们所创建实体类中的属性名。
2.2 查询举例
查询 username 中包含“zhang”并且性别为女的记录
代码语言:
@Test
public void getUserUseAnd(){
QueryWrapper<User> wrapper = new QueryWrapper<User>();
QueryWrapper<User> select = wrapper.like("username", "zhang").eq("gendar", "女");
List<User> users = userMapper.selectList(select);
users.forEach(System.out::println);
}
输出结果:
User{id=2, username='zhangsan', gendar='女', remark='销售人员'}
这里的 like() 方法相当于 SQL 语句中的 %zhang%;如果我们只想对某一个方向的查询进行模糊,如果左侧模糊或右侧模糊,可以使用 likeLeft()
或是 likeRight()
即可实现 %zhang 或 zhang% 的效果。
2.3 聚合查询-mybatisplus实现group by
有时需要对查询的结果使用聚合函数进行计算。
如:查询不同性别的用户数量,当数量等于0时不统计
首先需要按性别对用户表进行分组;然后计算各分组的数量;按数量对结果进行筛选,要求大于0
此文以 count() 函数举例,其它函数的使用方法可以进行参考。
代码语言:java
@Test
public void getUserUseGroup() {
QueryWrapper<User> wrapper = new QueryWrapper<User>();
wrapper.select("gendar", "COUNT(gendar) as count").groupBy("gendar").having("count > 0");
List<Map<String, Object>> objects = userMapper.selectMaps(wrapper);
objects.forEach(System.out::println);
}
在控制台可以看到生成的SQL语句及执行过程:
==> Preparing: SELECT gendar,COUNT(gendar) as count FROM user GROUP BY gendar HAVING count > 0
==> Parameters:
<== Columns: gendar, count
<== Row: 女, 2
<== Row: 男, 3
<== Total: 2
执行结果如下:
{gendar=女, count=2}
{gendar=男, count=3}
类似地,如果想要使用其他聚合函数,可以在 select()
方法中直接使用 SQL 语句实现。
1 插入记录
1.1 以普通方式插入记录
向 User 表中插入一条记录。
创建一个 User 对象,调用 insert() 方法,即可实现向数据表中插入数据
代码语言:java
**复制
@Test
public void addUserTest(){
User user = new User();
user.setUsername("韩梅梅");
user.setGendar("女");
user.setRemark("大堂经理");
int insert = userMapper.insert(user);
System.out.println(insert);
}
执行后,可以在控制台中看到 MybatisPlus 向数据库发送的 SQL 语句如下:
==> Preparing: INSERT INTO user ( id, username, gendar, remark ) VALUES ( ?, ?, ?, ? )
==> Parameters: -154062847(Integer), 韩梅梅(String), 女(String), 大堂经理(String)
<== Updates: 1
因为没有对 ID 属性进行指定,程序随机生成了一条内容,这显然不是我们所期望的,可以在执行程序时设置该字段内容。
代码语言:java
**复制
@Test
public void addUserTest(){
User user = new User();
user.setId(7);
user.setUsername("韩梅梅");
user.setGendar("女");
user.setRemark("大堂经理");
int insert = userMapper.insert(user);
System.out.println(insert);
}
数据入库后效果如下:
那么,如果id为主键,一般为自增序列,要如何插入呢?
1.2 以字段自增方式插入记录
1.2.1 修改数据表
原数据表创建语句为:
CREATE TABLE
User
(
id
INT NOT NULL,
username
VARCHAR(50) NULL DEFAULT NULL,
gendar
CHAR(2) NULL DEFAULT NULL,
remark
VARCHAR(50) NULL DEFAULT NULL);
在数据表中添加 ID 字段为主键,并且将该字段设置为自动增长:
ALTER TABLE user ADD PRIMARY KEY(id);
ALTER TABLE user modify id INT(11) AUTO_INCREMENT;
1.2.2 修改实体类
修改实体类属性 id 的注解,使用 @TableId
标识出id字段为主键,并且将该字段设置为自动增长 IdType.AUTO
。
修改后的 User 类如下:
代码语言:java
**复制
package com.test.pojo;
import com.baomidou.mybatisplus.annotation.*;
@TableName(value = "user")
public class User {
@TableId(value = "id", type = IdType.AUTO)
Integer id;
String username;
String gendar;
String remark;
@TableField(value = "COUNT(*)", insertStrategy = FieldStrategy.NEVER, updateStrategy = FieldStrategy.NEVER)
Integer count;
public Integer getGen() {
return count;
}
public void setGen(Integer gen) {
this.count = gen;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getGendar() {
return gendar;
}
public void setGendar(String gendar) {
this.gendar = gendar;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", gendar='" + gendar + ''' +
", remark='" + remark + ''' +
", count=" + count +
'}';
}
}
1.2.3 插入数据
代码语言:java
**复制
@Test
public void addUserTest(){
User user = new User();
user.setUsername("李磊");
user.setGendar("男");
user.setRemark("英语老师");
int insert = userMapper.insert(user);
System.out.println(insert);
}
在控制台中看到 MybatisPlus 向数据库发送的 SQL 语句中,不再有ID字段了:
==> Preparing: INSERT INTO user ( username, gendar, remark ) VALUES ( ?, ?, ? )
==> Parameters: 李磊(String), 男(String), 英语老师(String)
<== Updates: 1
插入后数据表中,新记录的ID自动设置为8:
2 修改记录
2.1 根据ID修改
调用 updateById()
方法修改记录,方法中必须传入带有ID属性的对象。
代码语言:java
**复制
@Test
public void updateUserById(){
User user = new User();
user.setId(8);
user.setRemark("美术老师");
int insert = userMapper.updateById(user);
System.out.println(insert);
}
这种方式可对指定id的记录进行修改,因此,只能修改一条记录。
2.2 根据筛选条件修改
当需要按照指定条件筛选,并对筛选后的记录进行批量修改时,就要考虑这种使用方式。
需要先创建一个 UpdateWrapper
对象,需要修改的内容可以使用 set()
方法进行设置,筛选条件和查询时类似。
注意: 在 set() 方法及 UpdateWrapper 中引用的字符串,都是数据表中的列名,而不是实体类的属性名。
比如:对 remark 字段中包含“人员”信息的,将其 remark 修改为 “职能部门人员”:
代码语言:java
**复制
@Test
public void updateUserTest(){
User user = new User();
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("remark", "职能部门人员");
wrapper.like("remark", "人员");
int insert = userMapper.update(new User(), wrapper);
System.out.println(insert);
}
在控制台可以看到执行的SQL语句如下:
==> Preparing: UPDATE user SET remark=? WHERE (remark LIKE ?)
==> Parameters: 职能部门人员(String), %人员%(String)
<== Updates: 4
执行后数据内容变化如下:
3 删除记录
3.1 根据ID删除
调用 deleteById()
方法,传入仅设置了id属性的对象,此方法可删除一条记录。
删除 id 为 -154062847 的记录:
代码语言:java
**复制
@Test
public void deleteUserById(){
User user = new User();
user.setId(-154062847);
int res = userMapper.deleteById(user);
System.out.println(res);
}
==> Preparing: DELETE FROM user WHERE id=?
==> Parameters: -154062847(Integer)
<== Updates: 1
使用对象的方式来删除记录,需要创建对象,还是有些麻烦,也可以省去对象的创建,直接根据id来删除。
代码语言:java
**复制
@Test
public void deleteUserById(){
int res = userMapper.deleteById(1);
System.out.println(res);
}
3.2 根据ID列表删除
如果想要根据多个ID批量删除,可以调用 deleteBatchIds()
,传入集合类对象,在集合类中设置想要批量删除的id集合。
删除 id 分别为 1,2 的记录:
代码语言:java
**复制
@Test
public void deleteUserByIds(){
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(2);
int res = userMapper.deleteBatchIds(ids);
System.out.println(res);
}
==> Preparing: DELETE FROM user WHERE id IN ( ? , ? )
==> Parameters: 1(Integer), 2(Integer)
<== Updates: 2
3.3 根据指定字段内容删除
将指定字段及对应内容,放入到 Map 中,调用 deleteByMap()
方法,删除对应记录。
需要注意的是,Map 中所有字段都为“且”的关系。Map 对象中键,都是数据表中的列名,不是实体类的对象名。
删除 username 为 “lisi” 并且 remark 为 “大堂经理” 的记录:
代码语言:java
**复制
@Test
public void deleteUserByMap(){
Map<String, Object> map = new HashMap<>();
map.put("username", "lisi");
map.put("remark", "大堂经理");
int res = userMapper.deleteByMap(map);
System.out.println(res);
}
==> Preparing: DELETE FROM user WHERE remark = ? AND username = ?
==> Parameters: 大堂经理(String), lisi(String)
<== Updates: 0
通过这种方式可以删除满足条件的单条记录或批量记录。
3.4 根据查询结果删除
调用 delete()
方法,并传入 QueryWrapper
对象,在 QueryWrapper
对象中如同查询一样,将查询出的记录进行删除。
删除 remark 中包含了 “职能” 字符串的所有记录:
代码语言:java
**复制
@Test
public void deleteUserByWrapper(){
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("remark", "职能");
int res = userMapper.delete(wrapper);
System.out.println(res);
}
==> Preparing: DELETE FROM user WHERE (remark LIKE ?)
==> Parameters: %职能%(String)
<== Updates: 3