ssm框架逻辑删除mysql_MybatisPlus--CRUD接口及主键增长策略、自动填充、乐观锁更新数据...

目录

一、insert

1、插入操作

2、主键策略

二、update

1、根据Id更新操作

2、自动填充

3、乐观锁

三、select

1、根据id查询记录

2、通过多个id批量查询

3、简单的条件查询

4、分页

四、delete

1、根据id删除记录

2、批量删除

3、简单的条件查询删除

4、逻辑删除

一、insert

1、插入操作

@RunWith(SpringRunner.class)

@SpringBootTest

public class CRUDTests {

@Autowired

private UserMapper userMapper;

@Test

public void testInsert(){

User user = new User();

user.setName("Helen");

user.setAge(18);

user.setEmail("[email protected]");

int result = userMapper.insert(user);

System.out.println(result); //影响的行数

System.out.println(user); //id自动回填

}

}

注意:数据库插入id值默认为:全局唯一id

e487c894e60dc60f0561939a653b8253.png

2、主键策略

(1)ID_WORKER

MyBatis-Plus默认的主键策略是:ID_WORKER  全局唯一ID

参考资料:分布式系统唯一ID生成方案汇总:https://www.cnblogs.com/haoxinyue/p/5208136.html

(2)自增策略

要想主键自增需要配置如下主键策略

需要在创建数据表的时候设置主键自增

实体字段中配置 @TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)

private Long id;

要想影响所有实体的配置,可以设置全局主键配置

#全局设置主键生成策略

mybatis-plus.global-config.db-config.id-type=auto

其它主键策略:分析 IdType 源码可知

@Getter

public enum IdType {

/**

* 数据库ID自增

*/

AUTO(0),

/**

* 该类型为未设置主键类型

*/

NONE(1),

/**

* 用户输入ID

* 该类型可以通过自己注册自动填充插件进行填充

*/

INPUT(2),

/* 以下3种类型、只有当插入对象ID 为空,才自动填充。 */

/**

* 全局唯一ID (idWorker)

*/

ID_WORKER(3),

/**

* 全局唯一ID (UUID)

*/

UUID(4),

/**

* 字符串全局唯一ID (idWorker 的字符串表示)

*/

ID_WORKER_STR(5);

private int key;

IdType(int key) {

this.key = key;

}

}

二、update

1、根据Id更新操作

注意:update时生成的sql自动是动态sql:UPDATE user SET age=? WHERE id=?

@Test

public void testUpdateById(){

User user = new User();

user.setId(1L);

user.setAge(28);

int result = userMapper.updateById(user);

System.out.println(result);

}

2、自动填充

项目中经常会遇到一些数据,每次都使用相同的方式填充,例如记录的创建时间,更新时间等。

我们可以使用MyBatis Plus的自动填充功能,完成这些字段的赋值工作:

(1)数据库表中添加自动填充字段

在User表中添加datetime类型的新的字段 create_time、update_time

(2)实体上添加注解

@Data

public class User {

......

@TableField(fill = FieldFill.INSERT)

private Date createTime;

[email protected](fill = FieldFill.UPDATE)

@TableField(fill = FieldFill.INSERT_UPDATE)

private Date updateTime;

}

(3)实现元对象处理器接口

注意:不要忘记添加 @Component 注解

@Component

public class MyMetaObjectHandler implements MetaObjectHandler {

private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class);

@Override

public void insertFill(MetaObject metaObject) {

LOGGER.info("start insert fill ....");

this.setFieldValByName("createTime", new Date(), metaObject);

this.setFieldValByName("updateTime", new Date(), metaObject);

}

@Override

public void updateFill(MetaObject metaObject) {

LOGGER.info("start update fill ....");

this.setFieldValByName("updateTime", new Date(), metaObject);

}

}

3、乐观锁

主要适用场景:当要更新一条记录的时候,希望这条记录没有被别人更新,也就是说实现线程安全的数据更新

乐观锁实现方式:

取出记录时,获取当前version

更新时,带上这个version

执行更新时, set version = newVersion where version = oldVersion

如果version不对,就更新失败

c805b7a7515916e9a86d5be80f8daa6e.png

(1)数据库中添加version字段

ALTER TABLE `user` ADD COLUMN `version` INT

ff21c5d7f01fb477c8663016a83493d0.png

(2)实体类添加version字段

并添加 @Version 注解

@Version

@TableField(fill = FieldFill.INSERT)

private Integer version;

(3)元对象处理器接口添加version的insert默认值

@Override

public void insertFill(MetaObject metaObject) {

......

this.setFieldValByName("version", 1, metaObject);

}

特别说明:

支持的数据类型只有 int,Integer,long,Long,Date,Timestamp,LocalDateTime

整数类型下 newVersion = oldVersion + 1

newVersion 会回写到 entity 中

仅支持 updateById(id) 与 update(entity, wrapper) 方法

在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

(4)在 MybatisPlusConfig 中注册 Bean

创建配置类

@EnableTransactionManagement

@Configuration

@MapperScan("com.atguigu.mybatis_plus.mapper")

public class MybatisPlusConfig {

/**

* 乐观锁插件

*/

@Bean

public OptimisticLockerInterceptor optimisticLockerInterceptor() {

return new OptimisticLockerInterceptor();

}

}

(5)测试乐观锁可以修改成功

测试后分析打印的sql语句,将version的数值进行了加1操作

/**

* 测试 乐观锁插件

*/

@Test

public void testOptimisticLocker() {

//查询

User user = userMapper.selectById(1L);

//修改数据

user.setName("Helen Yao");

user.setEmail("[email protected]");

//执行更新

userMapper.updateById(user);

}

此时数据库中的version版本也变为了2

三、select

1、根据id查询记录

@Test

public void testSelectById(){

User user = userMapper.selectById(1L);

System.out.println(user);

}

2、通过多个id批量查询

完成了动态sql的foreach的功能

@Test

public void testSelectBatchIds(){

Listusers = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));

users.forEach(System.out::println);

}

3、简单的条件查询

通过map封装查询条件

@Test

public void testSelectByMap(){

HashMapmap = new HashMap<>();

map.put("name", "Helen");

map.put("age", 18);

Listusers = userMapper.selectByMap(map);

users.forEach(System.out::println);

}

注意:map中的key对应的是数据库中的列名。例如数据库user_id,实体类是userId,这时map的key需要填写user_id

4、分页

MyBatis Plus自带分页插件,只要简单的配置即可实现分页功能

(1)在配置类中添加插件

/**

* 分页插件

*/

@Bean

public PaginationInterceptor paginationInterceptor() {

return new PaginationInterceptor();

}

(2)测试selectPage分页

测试:最终通过page对象获取相关数据

@Test

public void testSelectPage() {

Pagepage = new Page<>(1,5);

userMapper.selectPage(page, null);

page.getRecords().forEach(System.out::println);

System.out.println(page.getCurrent());

System.out.println(page.getPages());

System.out.println(page.getSize());

System.out.println(page.getTotal());

System.out.println(page.hasNext());

System.out.println(page.hasPrevious());

}

控制台sql语句打印:SELECT id,name,age,email,create_time,update_time FROM user LIMIT 0,5

(3)测试selectMapsPage分页:结果集是Map

@Test

public void testSelectMapsPage() {

Pagepage = new Page<>(1, 5);

IPage> mapIPage = userMapper.selectMapsPage(page, null);

//注意:此行必须使用 mapIPage 获取记录列表,否则会有数据类型转换错误

mapIPage.getRecords().forEach(System.out::println);

System.out.println(page.getCurrent());

System.out.println(page.getPages());

System.out.println(page.getSize());

System.out.println(page.getTotal());

System.out.println(page.hasNext());

System.out.println(page.hasPrevious());

}

四、delete

1、根据id删除记录

Test

public void testDeleteById(){

int result = userMapper.deleteById(8L);

System.out.println(result);

}

2、批量删除

@Test

public void testDeleteBatchIds() {

int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));

System.out.println(result);

}

3、简单的条件查询删除

@Test

public void testDeleteByMap() {

HashMapmap = new HashMap<>();

map.put("name", "Helen");

map.put("age", 18);

int result = userMapper.deleteByMap(map);

System.out.println(result);

}

4、逻辑删除

物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除数据

逻辑删除:假删除,将对应数据中代表是否被删除字段状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录

(1)数据库中添加 deleted字段

ALTER TABLE `user` ADD COLUMN `deleted` boolean

4b2b0873fe97fd7ba0f26ba5fbd1ba84.png

(2)实体类添加deleted 字段

并加上 @TableLogic 注解 和 @TableField(fill = FieldFill.INSERT) 注解

@TableLogic

@TableField(fill = FieldFill.INSERT)

private Integer deleted;

(3)元对象处理器接口添加deleted的insert默认值

@Override

public void insertFill(MetaObject metaObject) {

......

this.setFieldValByName("deleted", 0, metaObject);

}

(4)application.properties 加入配置

此为默认值,如果你的默认值和mp默认的一样,该配置可无

mybatis-plus.global-config.db-config.logic-delete-value=1

mybatis-plus.global-config.db-config.logic-not-delete-value=0

(5)在 MybatisPlusConfig 中注册 Bean

@Bean

public ISqlInjector sqlInjector() {

return new LogicSqlInjector();

}

(6)测试逻辑删除

测试后发现,数据并没有被删除,deleted字段的值由0变成了1

测试后分析打印的sql语句,是一条update

注意:被删除数据的deleted 字段的值必须是 0,才能被选取出来执行逻辑删除的操作

/**

* 测试 逻辑删除

*/

@Test

public void testLogicDelete() {

int result = userMapper.deleteById(1L);

System.out.println(result);

}

(7)测试逻辑删除后的查询

MyBatis Plus中查询操作也会自动添加逻辑删除字段的判断

/**

* 测试 逻辑删除后的查询:

* 不包括被逻辑删除的记录

*/

@Test

public void testLogicDeleteSelect() {

User user = new User();

Listusers = userMapper.selectList(null);

users.forEach(System.out::println);

}

测试后分析打印的sql语句,包含 WHERE deleted=0

SELECT id,name,age,email,create_time,update_time,deleted FROM user WHERE deleted=0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/355696.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python对英语的要求_学python需要英语基础吗

在很多人的眼里&#xff0c;学习编程需要英语基础&#xff0c;因为程序代码全是英文字母&#xff0c;如果没有英语基础可能很难学懂编程。程序代码是英文确实没有错&#xff0c;但是也不是必须得懂英语&#xff0c;因为计算机程序有自己语言&#xff0c;并不是我们生活中的英语…

mysql5.6 优点_MySQL5.6复制:GTID的优点和限制(第一部分)_MySQL

bitsCN.com全局事务标示符(Global Transactions Identifier)是MySQL 5.6复制的一个新特性。它为维护特定的复制拓扑结构下服务器的DBA们大幅度改善他们的工作状况提供了多种可能性。然而&#xff0c;你还应该明白当前实现的一些局限。本博文是专门对在生产环境中启用GTID到底意…

python找不到csv文件_Python如何读取csv文件

逗号分隔值&#xff08;Comma-Separated Values&#xff0c;CSV&#xff0c;有时也称为字符分隔值&#xff0c;因为分隔字符也可以不是逗号&#xff09;&#xff0c;其文件以纯文本形式存储表格数据&#xff08;数字和文本&#xff09;。纯文本意味着该文件是一个字符序列&…

jsf 自定义属性_必填字段的自定义JSF验证器

jsf 自定义属性实现EditableValueHolder接口的JSF组件具有两个属性“ required”和“ requiredMessage” –一个标志&#xff0c;指示用户需要输入/选择非空值&#xff0c;以及一个用于验证消息的文本。 我们可以使用它&#xff0c;但是它不够灵活&#xff0c;我们不能直接在视…

Python那些事

Python这几年很火&#xff0c;在这里我用问答的方式来总结一下使用python的一些常见问题&#xff0c;对自己是个总结&#xff0c;也希望对有同样问题的朋友有帮助。Q&#xff1a;Python为什么流行&#xff1f;A&#xff1a;Python是一个比较方便的跨平台脚本语言。对于像我这种…

python cv2模块imshow_Python-OpenCV:cv2.imread(),cv2.imshow(),cv2.imwrite()

一、需要工具本机使用python 2.7.10下调试代码均通过&#xff0c;一下学习需要有一定的代码阅读能力&#xff0c;一下学习只介绍函数方法&#xff1a;Python 作为一种高效简洁的直译式语言非常适合我们用来解决日常工作的问题。而且它简单易学&#xff0c;初学者几个小时就可以…

python程序设计课程设计_《Python程序设计》教学大纲.doc

PAGE 理论课程教学大纲 《Python程序设计》教学大纲 课程编号&#xff1a; 总 学 时&#xff1a;64&#xff08;其中&#xff0c;讲课&#xff1a;32&#xff1b;实验&#xff1a;32&#xff09; 学 分&#xff1a;3 实践教学&#xff1a;0周 修读专业&#xff1a;地理信息系统…

2016年将是Java终于拥有窗口函数的那一年!

你没听错。 到目前为止&#xff0c;出色的窗口功能是SQL独有的功能。 即使是复杂的函数式编程语言似乎也缺少这种漂亮的功能&#xff08;如果我记错了&#xff0c;请纠正我&#xff0c;Haskell伙计们&#xff09;。 我们撰写了许多有关窗口函数的博客文章&#xff0c;并在诸如…

LINQ to Entities 不识别方法“System.String ToString() 的解决方法

今天在做一个页面的时候出现了LINQ to Entities 不识别方法“System.String ToString()”的错误&#xff0c;对于源码IQueryable<SelectListItem> items roleInfoServer.Get(r > true).Select(r > new SelectListItem() { Value r.Id.ToString(), Text r.RoleNa…

android 仿京东地址选择_Android 开发:仿美团地址选择

最近做了这个功能&#xff0c;分享一下&#xff0c;用的是百度地图api&#xff0c;和美团外卖的地址选择界面差不多&#xff0c;也就是可以搜索或者滑动地图展示地址列表给用户选择&#xff0c;看下效果图先。文章重点展示地图并定位到“我”的位置 滑动地图获取周边poi(逆地理…

简单回顾在杭州7年

回顾2010年回到浙江杭州&#xff0c;从一开始做.net到后来转到As3网页游戏开发&#xff0c;后又搞起android&#xff0c;那时候就立志想做一款有关于bible的游戏&#xff0c;2010年进入一家创业公司&#xff0c;叫追梦&#xff0c;是追求梦想的开始&#xff0c;在那接触火山和A…

ps还原上一步快捷键_ps还原上一步快捷键_photoshop恢复上一步操作的快捷键是什么...

满意答案simonsinxer推荐于 2017.09.01采纳率&#xff1a;53% 等级&#xff1a;11已帮助&#xff1a;63469人还原/重做前一步操作 【Ctrl】【Z】其他一些快捷键&#xff1a;还原两步以上操作 【Ctrl】【Alt】【Z】重做两步以上操作 【Ctrl】【Shift】【Z】剪切选取的图像或路…

python中排序从小到大_从Python看排序:冒泡排序

冒泡排序在排序算法中是最简单的一种&#xff0c;它通过多次遍历列表&#xff0c;将最大的元素冒泡到列表的头部或尾部。我们通过对四张扑克牌&#xff08;花色相同&#xff09;以从小到大的方式进行排序来演示该算法的工作原理。首先将扑克牌面朝上放在桌上&#xff0c;如下图…

Shell else if mysql_Shell if else语句(详解版)

和其它编程语言类似&#xff0c;Shell 也支持选择结构&#xff0c;并且有两种形式&#xff0c;分别是 if else 语句和 case in 语句。本节我们先介绍 if else 语句&#xff0c;case in 语句将会在《Shell case in》中介绍。如果你已经熟悉了C语言、Java、JavaScript 等其它编程…

【Java并发编程】:使用synchronized获取互斥锁

在并发编程中&#xff0c;多线程同时并发访问的资源叫做临界资源&#xff0c;当多个线程同时访问对象并要求操作相同资源时&#xff0c;分割了原子操作就有可能出现数据的不一致或数据不完整的情况&#xff0c;为避免这种情况的发生&#xff0c;我们会采取同步机制&#xff0c;…

WildFly Swarm –将Java EE应用程序部署为独立的Jar

WildFly Swarm为将Java EE应用程序部署为独立的Jar文件提供了一种简单的解决方案。 这使得部署应用程序特别是REST或Web服务非常容易。 Swarm在这方面与Spring Boot非常相似&#xff0c;因为它可以快速开发Web&#xff08;.War&#xff09;应用程序&#xff0c;然后将其部署为独…

c语言三个数从小到大排序/输出_我的c语言笔记(三)

int表达式这个表达式存在的目的在于将表达式转为整数。比如&#xff1a;float a9999.9999&#xff1b;int b;b(int)(a/1000);就可以得到9啦&#xff0c;别忘了套上固定格式哦&#xff5e;然后我们接下来一起来做一道很重要的题哦&#xff0c;反复练习&#xff0c;可以顺利拿下同…

java虚拟_Java虚拟机(JVM)工作原理

虽然本教程的内容为 x86 处理器的原生汇编语言&#xff0c;但是了解其他机器架构如何工作也是有益的。JVM 是基于堆栈机器的首选示例。JVM 用堆栈实现数据传送、算术运算、比较和分支操作&#xff0c;而不是用寄存器来保存操作数(如同 x86 一样)。数据结构&#xff0c;让它们协…

MVC5 + EF6 + Bootstrap3

MVC5 EF6 Bootstrap3 (16) 客户端验证摘要: 本节介绍MVC客户端验证。阅读全文posted 2015-05-26 07:15 Slark.NET 阅读(6333) | 评论 (21) 编辑MVC5 EF6 Bootstrap3 (15) 应用ModelState和Data Annotation做服务器端数据验证摘要: 本节我们用两种不同的方法ModelState和Da…

java for循环break_Java中break、continue、return在for循环中的使用

这篇文章主要介绍了break、continue、return在for循环中的使用&#xff0c;本文是小编收藏整理的&#xff0c;非常具有参考借鉴价值,需要的朋友可以参考下引言&#xff1a;在使用循环的时候&#xff0c;循环里面带有break、continue、return的时候经常弄混&#xff0c;今天特意…