CRUD

官方文档:https://baomidou.com/

(建议多看看官方文档,每种功能里面都有讲解)【本文章使用的mybatisplus版本为3.5.2】

条件构造器

一般都是用service层的方法,因为比mapper层的全。十分重要:Wrapper 记住查看输出的SQL进行分析

相当于创建一个构造器对象,然后讲需要查询or更新的条件写在里面,最后打包给mapper or service层的插入、更新方法

下图是Wapper的子类,QueryWrapperUpdateWrapper是一般的Wrapper,AbstractLambdaWrapper 是lambda语法糖的链式操作(两者选择一种使用即可)

下图是wrapper的条件方法,就不一一介绍了,下面举了六个就基本例子

1、测试一

@Test
public void testWrapper1() {
//参数是一个wrapper ,条件构造器,和刚才的map对比学习!
//查询name不为空,email不为空,age大于18的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("name")
.isNotNull("email")
.ge("age",18);
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}

测试二

@Test
public void testWrapper2() {
//查询name=wsk的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","wsk");
//查询一个数据selectOne,若查询出多个会报错
//Expected one result (or null) to be returned by selectOne(), but found: *
//若出现多个结果使用list或map
User user = userMapper.selectOne(wrapper);//查询一个数据,若出现多个结果使用list或map
System.out.println(user);
}

测试三

@Test
public void testWrapper3() {
//查询age在10-20之间的用户
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age", 10, 20);//区间
Integer count = userMapper.selectCount(wrapper);//输出查询的数量selectCount
System.out.println(count);
}

测试四

@Test
public void testWrapper4() {
//模糊查询
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.notLike("name","s")
.likeRight("email","qq");//qq% 左和右?
List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
maps.forEach(System.out::println);
}

测试五

@Test
public void testWrapper5() {
//模糊查询
// SELECT id,name,age,email,version,deleted,create_time,update_time
//FROM user
//WHERE deleted=0 AND id IN
//(select id from user where id<5)
QueryWrapper<User> wrapper = new QueryWrapper<>();
//id 在子查询中查出来
wrapper.inSql("id","select id from user where id<5");
List<Object> objects = userMapper.selectObjs(wrapper);
objects.forEach(System.out::println);
}

测试六

@Test
public void testWrapper6() {
QueryWrapper<User> wrapper = new QueryWrapper<>();
//通过id进行降序排序
wrapper.orderByDesc("id");
List<User> userList = userMapper.selectList(wrapper);
userList.forEach(System.out::println);
}

CRUD接口

基本配置:

0、创建数据库

DROP TABLE IF EXISTS user;

CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
version INT(10) NOT NULL DEFAULT 1 COMMIT '乐观锁版本号',
DELETED INT(10) NOT NULL DEFAULT 0 COMMIT '逻辑删除',
CREATE_TIME DATE COMMIT '创建时间',
modify_time DATE COMMIT '更新时间',
PRIMARY KEY (id)
); DELETE FROM user; INSERT INTO user (id, name, age, email) VALUES
(1, '工藤新一','test1@baomidou.com'),
(2, '毛利兰','est2@baomidou.com'),
(3, '柯南', 28, 'test3@baomidou.com'),
(4, '灰原哀', 21, 'test4@baomidou.com'),
(5, '工藤有希子', 24, 'test5@baomidou.com');

1、创建项目,导入依赖

		<!--spring-boot-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--SpringBootTest-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mysql 驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>

2、yaml

#设置开发环境
spring:
datasource:
username: root
password: 123456
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
url: jdbc:p6spy:mysql://localhost:3306/mybatis_plus?serverTimezone=UTC&useUnicode=true&characterEncoding=utf #配置日志 log-impl:日志实现
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3、创建实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")
public class User {
@TableId(type = IdType.AUTO)
Long id;
String name;
int age;
String email;
@Version//乐观锁version注解
private Integer version;
private Integer isDelete; @TableField(fill = FieldFill.INSERT)
private Date cTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date upTime;
}

4、写Mapper

@Repository
public interface UserMapper extends BaseMapper<User> { }

5、写Service接口和实现类

//Service接口
public interface UserService extends IService<User> { //别忘了继承这个父类 } //实现类
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService { //记得继承父类 }

6、之后就可以测试了

Mapper CRUD接口

顾名思义这个只有mapper层对象才有的方法

Insert

写数据库的时候id设置了主键自增的话,插入的时候不需要加入id,因为MP会自动添加并且自增的。

注:数据库写了id自增的话,在实体类设置主键生成策略是没用的,因为数据库设置了自增,数据库优先级高于代码

@Test//测试插入
public void insertTest(){
User user = new User();
user.setName("wsk");
user.setAge(18);
user.setEmail("2803708553@qq.com");
Integer result = userMapper.insert(user); //会帮我们自动生成id
System.out.println(result); //受影响的行数
System.out.println(user); //通过日志发现id会自动回填(id是由雪花算法生成的,在主键生成策略部分有讲到)
}

数据库插入的id的默认值为:全局的唯—id

Update

@Test//测试更新
public void updateTest(){
User user = new User();
user.setId(2L);//怎么改id??
//通过条件自动拼接动态Sql
user.setName("root");
user.setAge(12);
user.setEmail("root@qq.com");
int i = userMapper.updateById(user);//updateById,但是参数是个user
System.out.println(i);
}

Select

  • 通过id查询单个用户
@Test//通过id查询单个用户
public void testSelectById(){
User user = userMapper.selectById(1L);
System.out.println(user);
}

  • 通过id查询多个用户
@Test//通过id查询多个用户
public void testSelectBatchIds(){
List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
users.forEach(System.out::println);
//System.out.println(users);
}

  • 条件查询 通过map封装
@Test//通过条件查询之一  map(这里的map,相当于where后面的 name="conan"等条件)
public void testMap(){
HashMap<String, Object> map = new HashMap<>();
//自定义要查询的
map.put("name","www"); //查询名字是www的数据
map.put("name","111"); //查询名字是111的数据 最后的结果是取两者交集
map.put("age",18);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}

Delete

基本的删除任务:

@Test
public void testDeleteById(){
userMapper.deleteById(1359507762519068681L);
}
@Test
public void testDeleteBatchIds(){
userMapper.deleteBatchIds(Arrays.asList(1359507762519068675L,1359507762519068676L));
}
@Test
public void testD(){
HashMap<String, Object> map = new HashMap<>();
map.put("age","18");
map.put("name","lol");
userMapper.deleteByMap(map);
}

Service CRUD接口

顾名思义这是Service层才有的方法

Save

为了区分mapper层和service层的方法,所以service层的插入方法取名为save

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所");
//插入单条数据
userService.save(user);
// 插入(批量)
userService.saveBatch(Arrays.asList(user));
}

Remove

service层删除方法取名为remove

 @Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎"); userService.remove(wrapper); //根据条件构造器删除数据
userService.removeById(16L); //根据id删除数据,也可以根据实体类对象删除数据
userService.removeByMap(map); //根据map的条件删除记录
userService.removeBatchByIds(Arrays.asList(user)); //批量删除
}

Update

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.update(wrapper); //根据条件构造器更新
userService.updateById(user); //根据传入的实体类id确定需要更新的数据,更新为传入的实体类对象
userService.updateBatchById(Arrays.asList(user)); //批量更新
}

Get

该方法只能查询一条数据,所以不推荐。查询用list方法

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.getById(12L); //根据id查询一条数据
userService.getMap(wrapper); //根据构造器查询一条数据,返回Mapper集合
}

List

查询多条数据

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.list(); //查询全部数据
userService.listMaps(); //查询全部数据,以map形式返回
userService.listByMap(map); //根据map查询数据
userService.listByIds(Arrays.asList(10L,15L)); //根据id查询数据
}

SaveOrUpdate

运行逻辑:直接更新,更新0行的话;就select,查询出来是0行;则就插入

有传入id的情况会优先更新,如果更新不了,则会插入新的数据

记得在实体类写上@TableId!!!

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.saveOrUpdate(user); //传入的对象id存在则更新,否则插入新数据
userService.saveOrUpdate(user,wrapper); //根据更新条件构造器,更细数据
userService.saveOrUpdateBatch(Arrays.asList(user)); //批量修改插入
}

Count

统计符合条件的数据的数量

@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.count();
userService.count();
}

Chain

链式调用,可以不用条件构造器完成 条件设置和增删改查。推荐!因为优雅!

Query
@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); List<User> userList = userService.query()
.eq("name", "工藤新一")
.gt("age", 17)
.list();
for(User user01: userList) {
System.out.println(user);
}
}
Update
@Test
void test(){
User user = new User();
user.setName("Conan");
user.setAge(18);
user.setEmail("毛利侦探事务所"); HashMap<String,Object> map = new HashMap<>();
map.put("name","Conan"); QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("name","毛利小五郎")
.ge("age",18); userService.update()
.eq("name", "工藤新一")
.gt("age", 17)
.update();
}

MybatisPlus核心功能——实现CRUD增删改查操作 (包含条件构造器)的更多相关文章

  1. 创建支持CRUD(增删改查)操作的Web API(二)

    一:准备工作 你可以直接下载源码查看 Download the completed project.     下载完整的项目 CRUD是指“创建(C).读取(R).更新(U)和删除(D)”,它们是四个 ...

  2. yii2-basic后台管理功能开发之二:创建CRUD增删改查

    昨天实现了后台模板的嵌套,今天我们可以试着创建CRUD模型啦 刚开始的应该都是“套用”,不再打算细说,只把关键的地方指出来. CRUD即数据库增删改查操作.可以理解为yii2为我们做了一个组件,来实现 ...

  3. 使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序

    使用ASP.NET Core MVC 和 Entity Framework Core 开发一个CRUD(增删改查)的应用程序 不定时更新翻译系列,此系列更新毫无时间规律,文笔菜翻译菜求各位看官老爷们轻 ...

  4. 前端的CRUD增删改查的小例子

    前端的CRUD增删改查的小例子 1.效果演示 2.相关代码: <!DOCTYPE html> <html lang="en"> <head> & ...

  5. JavaWeb系统(增删改查、多条件查询功能)

    该系统是一个简单的青年服务管理系统,主要包括了较完整的常用的增删改查以及多条件查询功能,对于初学者有很大帮助. 下面是相关的Java代码.jsp页面.以及数据库的创建和相关表的设计 java代码 首先 ...

  6. 如何搭建一个WEB服务器项目(二)—— 对数据库表进行基本的增删改查操作

    使用HibernateTemplate进行增删改查操作 观前提示:本系列文章有关服务器以及后端程序这些概念,我写的全是自己的理解,并不一定正确,希望不要误人子弟.欢迎各位大佬来评论区提出问题或者是指出 ...

  7. (转)SQLite数据库增删改查操作

    原文:http://www.cnblogs.com/linjiqin/archive/2011/05/26/2059182.html SQLite数据库增删改查操作 一.使用嵌入式关系型SQLite数 ...

  8. 浅谈dataGridView使用,以及画面布局使用属性,对datagridview进行增删改查操作,以及委托使用技巧

        通过几天的努力后,对datagridview使用作一些简要的介绍,该实例主要运用与通过对datagridview操作.对数据进行增删改查操作时,进行逻辑判断执行相关操作.简单的使用委托功能,实 ...

  9. Android SQLite 数据库 增删改查操作

    Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...

随机推荐

  1. SQL中把汉字转换拼音码

    思路:在SQL中创建一个函数fn_GetPy(),函数的输入参数是一个汉字字符串,返回值是拼音码字符串. 创建函数语句: CREATE function fn_GetPy(@str nvarchar( ...

  2. 快速 IO

    IO 的进化史 cin和cout 刚开始学的时候,老师叫我们用 cin 和 cout 大概是因为这最简单吧 cin>>x; cout<<x scanf和printf 学到函数了 ...

  3. 想知道Vue3与Vue2的区别?五千字教程助你快速上手Vue3!

    从Vue3发布以来,我就一直对其非常感兴趣,就一直想着将其投入公司的生产中,但是开始考虑到很多不确定性就暂时对一些很小的功能进行一些尝试:慢慢的发现组合式Api的形式非常适合开发(个人感觉),尤其是V ...

  4. Node.js精进(4)——事件触发器

    Events 是 Node.js 中最重要的核心模块之一,很多模块都是依赖其创建的,例如上一节分析的流,文件.网络等模块. 比较知名的 Express.KOA 等框架在其内部也使用了 Events 模 ...

  5. Metasploit msfvenom

    一. msfvenom简介 msfvenom是msf payload和msf encode的结合体,于2015年6月8日取代了msf payload和msf encode.在此之后,metasploi ...

  6. 解决nginx反向代理Mixed Content和Blockable问题

    nginx配置https反向代理,按F12发现js等文件出现Mixed Content,Optionally-blockable 和 Blockable HTTPS 网页中加载的 HTTP 资源被称之 ...

  7. python简单处理验证码,三分钟,不能再多了

    序言 大家好鸭, 又是我小熊猫啦 我们在做采集数据的时候,过快或者访问频繁,或者一访问就给弹出验证码,然后就蚌珠了~今天就给大家来一个简单处理验证码的方法 环境模块 Python和pycharm如果还 ...

  8. 用python制作文件搜索工具,深挖电脑里的【学习大全】

    咳咳~懂得都懂啊 点击此处找管理员小姐姐领取正经资料~ 开发环境 解释器: Python 3.8.8 | Anaconda, Inc. 编辑器: pycharm 专业版 先演示效果 开始代码,先导入模 ...

  9. NC15052 求最值

    NC15052 求最值 题目 题目描述 给你一个长为 \(n\) 的序列 \(a\) 定义 \(f(i,j)=(i-j)^2+g(i,j)^2\) \(g\) 是这样的一个函数 求最小的 \(f(i, ...

  10. Codeforces Round #780 (Div. 3)

    A. Vasya and Coins 题目链接 题目大意 Vasya 有 a 个 1-burle coin,有 b 个 2-burle coin,问他不能通过不找钱支付的价格的最小值. 思路 如果 a ...