MybatisPlus的使用
- 后端
- 鹏重名了
- 0
MyBatisPlius
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 '邮箱',
PRIMARY KEY (id)
);
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
1、导入依赖
<!--数据库驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version> <!-- 使用适当的版本号 -->
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
- 我们使用
mybaits-plus
可以节省我们大量的代码,尽量不要同时导入mybatis
和mybaits-plus
2、连接数据库
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=PRC&characterEncoding=UTF8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
3、做一个小测试
pojo
:com.yap.mybatis_plus.mapper
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private String age;
private String email;
}
mapper
:com.yap.mybatis_plus.mapper
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.yap.mybatis_plus.pojo.User;
import org.springframework.stereotype.Repository;
/**
* @author yap
* @version 1.0
*/
//在对应的mapper 上面继承基本的类 BaseMapper
@Repository//代表持久层
public interface UserMapper extends BaseMapper<User> {
}
启动类
:
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//扫描mapper 文件夹
@MapperScan("com.yap.mybatis_plus.mapper")
@SpringBootApplication
public class MybatisPlusApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisPlusApplication.class, args);
}
}
4、测试类中
- 引入
//继承了BaseMapper,所以的方法都来自父类
//我们也可以编写自己的扩展方法
@Autowired
private UserMapper userMapper;
@Test
void selectList() {
//参数是一个Wrapper,条件构造器,
//查询全部用户
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
- 输出结果
User(id=1, name=Jone, age=18, email=<test1@baomidou.com>)
User(id=2, name=Jack, age=20, email=<test2@baomidou.com>)
User(id=3, name=Tom, age=28, email=<test3@baomidou.com>)
User(id=4, name=Sandy, age=21, email=<test4@baomidou.com>)
User(id=5, name=Billie, age=24, email=<test5@baomidou.com>)
5、配置日志
- 现在是看不到sql的,配置控制台输出日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
- 输出结果
Creating a new SqlSession
SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3289079a] was not registered for synchronization because synchronization is not active
JDBC Connection [HikariProxyConnection@324701295 wrapping com.mysql.cj.jdbc.ConnectionImpl@6419a0e1] will not be managed by Spring
==> Preparing: SELECT id,name,age,email FROM user
==> Parameters:
<== Columns: id, name, age, email
<== Row: 1, Jone, 18, test1@baomidou.com
<== Row: 2, Jack, 20, test2@baomidou.com
<== Row: 3, Tom, 28, test3@baomidou.com
<== Row: 4, Sandy, 21, test4@baomidou.com
<== Row: 5, Billie, 24, test5@baomidou.com
<== Total: 5
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3289079a]
6、CRUD拓展
6.1 测试插入(insert)
- insert:使用的是雪花算法生成唯一Id
- 雪花算法:snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是: 使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID ),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个ID),最后还有一个符号位,永远是0。可以保证全球唯一!
- 主键自增:
- 1、 :实体类字段上
@TableId(type = IdType.ID_WORKER)
//唯一- AUTO:数据库id自增
- NONE:未设置主键
- INPUT:手动输入
- ID_WORKER:默认的全局唯一ID
- UUID:全局唯一id uuid
- ID_WORKER_STR:ID_WORKER的字符串表示法
- 2、 :数据库字段一定要是自增否则会报错!
- 1、 :实体类字段上
@Test
void insert() {
User user = new User();
user.setName("abc");
user.setAge(3);
user.setEmail("456");
int result = userMapper.insert(user);//自动生成id
System.out.println(result);
System.out.println(user);
}
6.2 测试更新(update)
- updateById:参数是一个对象
@Test
void updateById() {
User user = new User();
//通过条件自动拼接sql
user.setId(1667764916303597570L);
user.setName("123");
user.setAge(1);
user.setEmail("456");
//注意updateById的参数是个对象
int result = userMapper.updateById(user);
System.out.println(result);
System.out.println(user);
}
6.3 自动填充
- 创建时间、修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新!
- 阿里巴巴开发手册:所有数据库表:创建时间(
gmt_create
)、修改时间:(gmt_modified
)几乎所有表都要配置上!而且需要自动化!
方式:代码级别
- 1:在表中新建字段 create_time,update_time
- 2:同步实体类User
//字段添加填充内容
@TableField(fill = FieldFill.INSERT)//代表添加的时候执行
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)//代表添加修改的时候执行
private Date updateTime;
- 3:创建com.yap.mybatis_plus.handler.MyMetaObjectHandler
- 自定义实现类
package com.yap.mybatis_plus.handler;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import java.util.Date;
@Slf4j
@Component//不要忘记把处理器加到ioc容器中
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
//插入的时候添加和修改都会存入时间
this.strictInsertFill(metaObject, "createTime", Date.class, new Date());
this.strictInsertFill(metaObject, "updateTime", Date.class, new Date());
}
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
//更新的时候会修改时间
this.strictUpdateFill(metaObject, "updateTime", Date.class, new Date());
}
}
6.4 乐观锁
乐观锁:顾名思义十分乐观,它总会认为不会出现问题,无论干什么都不上锁!如果出现问题,再次更新值测试
悲观锁:顾名思义十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!
- 乐观锁实现方式:
- 取出记录时,获取当前 version
- 更新时,带上这个 version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果 version 不对,就更新失败
乐观锁:1、先查询 获得版本号 version = 1
-- A
update user set name = "abc",version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候version = 2,会导致A修改失败!
update user set name = "abc",version = version + 1
where id = 2 and version = 1
测试一下MP乐观锁插件
- 1、:给数据库增加
version
字段,默认值为1
,int
类型,长度10
- 2、:实体类增加字段
@Version//乐观锁version注解
private Integer version;
- 说明:
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下
newVersion = oldVersion + 1
newVersion
会回写到entity
中- 仅支持
updateById(id)
与update(entity, wrapper)
方法 - 在
update(entity, wrapper)
方法下,wrapper
不能复用!!!
- 3、:测试一下!
//测试乐观锁成功
@Test
public void testVersion() {
//1、查询用户信息
User user = userMapper.selectById(1L);
//2、修改用户信息
user.setName("abc");
user.setEmail("2314526");
//3、执行更新操作
int i = userMapper.updateById(user);
System.out.println(i);
}
//测试乐观锁失败
//开启version最后数据库显示的结果是abc222
//未开启version最后数据库显示的结果是abc111
@Test
public void testVersion2() {
//线程1
User user = userMapper.selectById(1L);
user.setName("abc111");
user.setEmail("2314526");
//模拟另外一个线程执行了插队操作
User user2 = userMapper.selectById(1L);
user2.setName("abc222");
user2.setEmail("2314526");
userMapper.updateById(user2);
//自旋锁来多次尝试提交
userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值
}
免责申明:本站发布的内容(图片、视频和文字)以转载和分享为主,文章观点不代表本站立场,如涉及侵权请联系站长邮箱:xbc-online@qq.com进行反馈,一经查实,将立刻删除涉嫌侵权内容。