Mybatis-plus的使用和学习

Mybatis-plus的使用和学习

推荐官网学习https://baomidou.com/guide/

1、首先准备数据

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');

2、新建springboot项目,添加依赖

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.4.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.21</version>
    </dependency>
</dependencies>

3、添加配置

spring.datasource.url=jdbc:mysql://localhost:3306/mytest?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=MyNewPass4!
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

4、启动类添加扫描注解

@SpringBootApplication
@MapperScan("com.zhu.one.mapper")
public class OneApplication {
   public static void main(String[] args) {
      SpringApplication.run(OneApplication.class, args);
   }
}

5、添加实体类和mapper接口

@Data
public class User {
    private Long id;
    private String name;
    private Integer age;
    private String email;
}
public interface UserMapper extends BaseMapper<User> {
}

6、添加测试

@RunWith(SpringRunner.class)
@SpringBootTest
public class SampleTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        List<User> userList = userMapper.selectList(null);
        Assert.assertEquals(5, userList.size());
        userList.forEach(System.out::println);
    }

}

7、输出结果

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)

简单搭建成功

配置日志

开启sql日志打印

添加配置

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
JDBC Connection [HikariProxyConnection@1442768482 wrapping com.mysql.cj.jdbc.ConnectionImpl@54089484] 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@79e66b2f]
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)

测试插入

@Test
void test1() {
   System.out.println(("----- 测试插入 ------"));
   User user =new  User();
   user.setAge(22);
   user.setEmail("3526837@qq.com");
   user.setName("xiaozhu");
   userMapper.insert(user);
}
JDBC Connection [HikariProxyConnection@513241240 wrapping com.mysql.cj.jdbc.ConnectionImpl@630390b9] will not be managed by Spring
==>  Preparing: INSERT INTO user ( id, name, age, email ) VALUES ( ?, ?, ?, ? )
==> Parameters: 1324614255098048513(Long), xiaozhu(String), 22(Integer), 3526837@qq.com(String)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@79e66b2f]

id–雪花算法

雪花算法是Twitter开源的分布式id的生成算法,会返回一个long型

具体生成如下

0 - 0000000000 0000000000 0000000000 0000000000 0 - 00000 - 00000 - 000000000000

首位为无效位,不使用,接下来的41位为时间戳,在后5位是datacenterId,在后5位是workerId,最后12位是毫秒类的计数(差不多一毫秒可以生成4096个),加起来一共有64个,最后转化为长度为18的Long型

属性自动填充

以最常用的创建时间和更新时间为例,每次插入数据的时候,创建时间和更新时间字段会自动填充当前时间值,每次数据的时候,更新时间字段会自动更新为当前时间

只需要实现MetaObjectHandler 接口即可

@Slf4j
@Component
public class MyAutoFillFieldHandler implements MetaObjectHandler {

   @Override
   public void insertFill(MetaObject metaObject) {
      log.info("插入数据时自动填充创建时间和更新时间");
      this.strictInsertFill(metaObject,"createTime",Date.class,new Date());
      this.strictInsertFill(metaObject,"updateTime",Date.class,new Date());
   }

   @Override
   public void updateFill(MetaObject metaObject) {
      log.info("更新数据时自动填充创建时间和更新时间");
      this.strictInsertFill(metaObject,"updateTime",Date.class,new Date());
   }
}

然后在实体类上标记哈

@Data
public class User {
   @TableId(type = IdType.ASSIGN_ID)
   private Long id;

   private String name;
   private Integer age;
   private String email;
   @TableField(fill = FieldFill.INSERT)//插入时自动填充
   private Date createTime;
   @TableField(fill = FieldFill.INSERT_UPDATE)//插入和更新时自动填充
   private Date updateTime;
}

测试:插入

@Test
void test2() {
   System.out.println(("----- 测试自动填充 ------"));
   User user =new  User();
   user.setAge(22);
   user.setEmail("3526837@qq.com");
   user.setName("xiaozhu");
   userMapper.insert(user);
}
JDBC Connection [HikariProxyConnection@565627330 wrapping com.mysql.cj.jdbc.ConnectionImpl@309cedb6] will not be managed by Spring
==>  Preparing: INSERT INTO user ( id, name, age, email, create_time, update_time ) VALUES ( ?, ?, ?, ?, ?, ? ) ##在这里就已经把时间拿过来了,我们自己是没有设置值的
==> Parameters: 1324632793531674626(Long), xiaozhu(String), 22(Integer), 3526837@qq.com(String), 2020-11-06 16:40:43.125(Timestamp), 2020-11-06 16:40:43.127(Timestamp)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@489091bd]

在这里插入图片描述

最终数据自动填充上了

测试:更新

@Test
void test3() {
   System.out.println(("----- 测试自动填充 ------"));
   List<User> userList = userMapper.selectList(null);
   for (User user : userList) {
      userMapper.updateById(user);
   }
}

在这里插入图片描述

乐观锁

乐观锁:觉得什么都是好的,不会加锁,通过version判断

悲观锁:觉得什么都是不好的,干什么都会加锁

乐观锁:

  • 取出记录时,获取当前version
  • 更新时,带上这个version
  • 执行更新时, set version = newVersion where version = oldVersion(这一步必须为原子操作)
  • 如果version不对,就更新失败

数据库加上一个version字段
在这里插入图片描述

对应的实体类也加上version属性

@Data
public class User {
   @TableId(type = IdType.ASSIGN_ID)
   private Long id;

   private String name;
   private Integer age;
   private String email;
   @TableField(fill = FieldFill.INSERT)
   private Date createTime;
   @TableField(fill = FieldFill.INSERT_UPDATE)
   private Date updateTime;

   @Version  //加上version注解
   private Long version;
}

加上OptimisticLockerInnerInterceptor拦截器,并且添加开启事务的注解

@SpringBootApplication
@EnableTransactionManagement  //开启事务
@MapperScan("com.zhu.one.mapper")
public class OneApplication {

   public static void main(String[] args) {
      SpringApplication.run(OneApplication.class, args);
   }

   @Bean
   public MybatisPlusInterceptor getOptimisticLockerInnerInterceptor(){
      MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
       //将乐观锁的拦截器添加进去
      interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
      return interceptor;
   }
}

测试

@Test
void test3() {
   System.out.println(("----- 测试乐观锁 ------"));
    
    //按照程序的逻辑最好age应该被更改为122,但是如果乐观锁生效的话应该是22,最好一个update会更新不成功
    
   User user= userMapper.selectById(1L);
   user.setAge(122);

   User user1= userMapper.selectById(1L);
   user1.setAge(22);
   userMapper.updateById(user1);

   userMapper.updateById(user);
}

测试结果
在这里插入图片描述

在这里插入图片描述

最后age结果为22,说明乐观锁生效

分页测试

@Test
void test5() {
   System.out.println(("----- 测试分页查询 ------"));
   Page page = new Page(2,3);
   userMapper.selectPage(page, null);
   page.getRecords().forEach(System.out::println);
}
User(id=4, name=Sandy, age=21, email=test4@baomidou.com, createTime=null, updateTime=Fri Nov 06 16:44:45 CST 2020, version=1)
User(id=5, name=Billie, age=24, email=test5@baomidou.com, createTime=null, updateTime=Fri Nov 06 16:44:45 CST 2020, version=1)
User(id=1324614255098048513, name=xiaozhu, age=22, email=3526837@qq.com, createTime=null, updateTime=Fri Nov 06 16:44:45 CST 2020, version=1)

逻辑删除

数据库添加字段deleted,默认为0,表示未删除,1表示已删除

实体类添加对应字段并且添加注解

@Data
public class User {
   @TableId(type = IdType.ASSIGN_ID)
   private Long id;

   private String name;
   private Integer age;
   private String email;
   @TableField(fill = FieldFill.INSERT)
   private Date createTime;
   @TableField(fill = FieldFill.INSERT_UPDATE)
   private Date updateTime;

   @Version
   private Long version;

   @TableLogic
   private Integer deleted;
}
@Test
void test6() {
   System.out.println(("----- 测试逻辑删除 ------"));
   userMapper.deleteById(1324632793531674626L);
}
JDBC Connection [HikariProxyConnection@1729045606 wrapping com.mysql.cj.jdbc.ConnectionImpl@6e03db1f] will not be managed by Spring
==>  Preparing: UPDATE user SET deleted=1 WHERE id=? AND deleted=0
==> Parameters: 1324632793531674626(Long)
<==    Updates: 1
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@5f2bd6d9]

虽然是删除,却走的是更新操作,逻辑删除的好处就是数据其实没有被删除,后天数据库还是有的,只是前段通过字段控制显示了

代码生成器

导入依赖

<!--末班引擎-->
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.0</version>
</dependency>
<!--代码生成依赖-->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.0</version>
</dependency>
public class Code {
   public static void main(String[] args) {
      AutoGenerator autoGenerator = new AutoGenerator();

      //全局配置
      GlobalConfig globalConfig=new GlobalConfig();
      globalConfig.setOutputDir(System.getProperty("user.dir")+"/one/src/main/java");
      globalConfig.setAuthor("xiaozhu");
      globalConfig.setOpen(false);
      globalConfig.setFileOverride(false);
      globalConfig.setServiceName("%sService");
      autoGenerator.setGlobalConfig(globalConfig);

      // 数据源配置
      DataSourceConfig dsc = new DataSourceConfig();
      dsc.setUrl("jdbc:mysql://localhost:3306/nacos_config?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC");
      dsc.setDriverName("com.mysql.cj.jdbc.Driver");
      dsc.setUsername("root");
      dsc.setPassword("xxxxx");
      dsc.setDbType(DbType.MYSQL);
      autoGenerator.setDataSource(dsc);

      //包的配置
      PackageConfig packageConfig=new PackageConfig();
      packageConfig.setModuleName("one");
      packageConfig.setParent("com.zhu");
      packageConfig.setEntity("entity");
      packageConfig.setMapper("mapper");
      packageConfig.setService("serviec");
      packageConfig.setController("controller");
      autoGenerator.setPackageInfo(packageConfig);

      // 策略配置
      StrategyConfig strategy = new StrategyConfig();
      strategy.setNaming(NamingStrategy.underline_to_camel);
      strategy.setColumnNaming(NamingStrategy.underline_to_camel);
      strategy.setEntityLombokModel(true);
      strategy.setRestControllerStyle(true);
      strategy.setControllerMappingHyphenStyle(true);

      TableFill createTime=new TableFill("createTime",FieldFill.INSERT);
      TableFill updateTime=new TableFill("updateTime",FieldFill.INSERT);
      List list=new ArrayList();
      list.add(createTime);
      list.add(createTime);
      strategy.setTableFillList(list);
      autoGenerator.setStrategy(strategy);

      autoGenerator.execute();
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值