• 欢迎光临~

mybatisplus

开发技术 开发技术 2022-07-31 次浏览

mybatis plus

特点:所有的crud代码都可以自动化完成!

 

特征:1.无侵入

2.损耗小

3.强大的crud操作

4.支持主键生成

5.内置代码生成器

6.内置分页插件

.........

 

 

使用第三方组件一般步骤:

1.导入对应的依赖

2.研究依赖如何配置

3.代码如何编写

4.提高扩展技术能力

 

配置:

 <!--1.数据库驱动-->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <scope>runtime</scope>
       </dependency>
       <!--2.lombok-->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>
       <!--3.mybatis-plus  版本很重要3.0.5-->
       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-boot-starter</artifactId>
           <version>3.0.5</version>
       </dependency>
       <!--4.h2-->
       <dependency>
           <groupId>com.h2database</groupId>
           <artifactId>h2</artifactId>
           <scope>runtime</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
spring:
datasource:
  driver-class-name: com.mysql.cj.jdbc.Driver
   #url: jdbc:mysql://127.0.0.1:3306/test001?ullNamePatternMatchesAll=true&amp;serverTimezone=GMT%2b8?useUnicode=true&characterEncoding=utf8
  url: jdbc:mysql://127.0.0.1:3306/test001?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
  username: root
  password: 123456


注意:#号后面是平常的,这里如果是这个就会报错,用下面那个。

 

 

这个就写实体类,和mapper接口就可以了

例子:

package com.kuang.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
//get set toString 方法不用写了
//所有的有参构造方法不用写了
//所有的无参构造方法也不用写了
public class User {
   private Long id;
   private String name;
   private Integer age;
   private String email;
}

 

package com.kuang.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kuang.demo.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
//在对应的mapper上面继承基本的接口 BaseMapper
public interface UserMapper extends BaseMapper<User> {
   List<User> selectList();
   //到这里所有的crud已经完成,不需要配置了
}

 

测试
   package com.kuang.demo;

import com.kuang.demo.mapper.UserMapper;
import com.kuang.demo.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class DemoApplicationTests {
   //继承了BaseMapper,所有的方法来自自己的父类,我们也可以编写自己的方法
   @Autowired
   private UserMapper userMapper;


   @Test
   void contextLoads() {
       //参数是一个wrapper,条件构造器,这里先不用写成null
       //查询全部用户
       List<User> users = userMapper.selectList(null);
       users.forEach(System.out::println);
  }

}

因为plus里面的SQL是不可见的,所以要加日志

在配置文件里面加

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

这是默认日志,不需要导入依赖。

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

 

主键生成策略

分布式系统唯一id生成(默认的id生成)

1.雪花算法(snowflake)

是推特开源的分布式id生成算法,结果是一个long型的id,可以保证全球唯一。

 

我们需要配置主键自增:

1.实体类字段上 @TableId(type=Idtype.AUTO)

2.数据库字段一定要是自增!

3.再次测试即可

 

解释:

public enum IdType {
   AUTO(0),  //数据库id自增
   NONE(1),//为设置主键
   INPUT(2),//手动输入
   ID_WORKER(3),//默认的全局id
   UUID(4), //全局唯一id,UUID
   ID_WORKER_STR(5);//字符串表示法

 

更新操作

 @Test
   public void testUpdate(){
       User user = new User();
      //通过条件自动拼接动态SQL
       user.setName("卡面打");
     // user.setEmail("648532946@qq.com");
       user.setAge(7);
       user.setId(1478543865383448578L);
       int i = userMapper.updateById(user);
       System.out.println(i);
  }

//丢入的是一个对象,而不是某个字段
//setId,是数据库里面有才行

 

自动填充

创建时间 ,修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新。

阿里巴巴开发手册:所有的数据库:gmt_create,gmt_modified几乎所有的表都要配置上!而且需要自动化!

方法一:数据库级别(不建议使用)

1.在表中新增字段create_time,update_time

数据库类型:datetime

默认:CREATE_TIMESTAMP

更新打钩

2.再次测试插入方法,我们需要先把实体类同步!

 

方式二:代码级别(推荐使用)

1.删除数据库的默认值,更新操作!

2.实体类字段属性上需要增加注解

 //字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

3.编写处理器来处理这个注解即可!

package com.kuang.demo.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.util.Date;

//要被识别,必须要丢到springboot里面,也就是@Component
@Component //处理器加到IOC容器中
@Slf4j
//加一些日志
public class MyHandler implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill............");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill............");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}

基本上这个处理器就不变了,就字段跟在来

 

 

乐观锁

.........................

 

查询操作

@Test
//批量查询(删除同理)
   public void testSelectByBatchId(){
       List<User> users = userMapper.selectBatchIds(Arrays.asList(1L, 2L, 3L));
       users.forEach(System.out::println);
  }
 //根据条件查询
//按条件查询,一般都使用map
   @Test
   public void testSelectBytchs(){
       HashMap<String, Object> hashMap = new HashMap<>();
       hashMap.put("name","卡面来打");
       List<User> users = userMapper.selectByMap(hashMap);
       users.forEach(System.out::println);
  }

 

分页查询(mp里面配置了分页)

1.配置拦截器组件即可(自己建一个config)
@Configuration
@MapperScan("com.kuang.demo.mapper")
@EnableTransactionManagement
public class MyConfig {
   @Bean
   public PaginationInterceptor paginationInterceptor(){
       return new PaginationInterceptor();
  }
}

 

2.直接使用page对象即可
    @Test
   public void testPage(){
       //参数一:当前页
       //参数二:页面多少个
       Page<User> page = new Page<>(2, 5);
       userMapper.selectPage(page,null);
       page.getRecords().forEach(System.out::println); //总条数
       System.out.println("总共有:"+page.getTotal()+"条数据!");
  }

//page点后面的东西特别多
 

条件构造器

点出来的方法,里面的参数都可以填一个wrapper。

十分重要:wrapper

参数是一个wrapper,条件构造器

例子:

 @Test
    void contextLoads(){
       //查询name不为空,邮箱不为空,年龄大于等于12
       QueryWrapper<User> wrapper = new QueryWrapper<>();
       wrapper
              .isNotNull("name")
              .isNotNull("email")
              .ge("age","12");
       userMapper.selectList(wrapper).forEach(System.out::println);
  }

wrapper是链式编程,也就是点出来。

 

 @Test
    //衣裤
   //查询名字为卡面来打的数据
   void selectByName(){
       QueryWrapper<User> wrapper = new QueryWrapper<>();
       wrapper.eq("name" , "卡面来打");
       System.out.println(userMapper.selectList(wrapper));
  }

selectOne 这个是查询只有一个数据用的。有多个就报错

 

   @Test
   //查询年龄在5和14之间的个数
   void betweenByAge(){
       QueryWrapper<User> wrapper = new QueryWrapper<>();
       wrapper.between("age",5,14);
       Integer count = userMapper.selectCount(wrapper);
       //这里返回的是,Integer类型,别想着去遍历
       System.out.println(count);
  }

between,查询之间的数据

selectCount,查询数据的个数

 

  //模糊查询
   @Test
   void like(){
       QueryWrapper<User> wrapper = new QueryWrapper<>();

       wrapper.notLike("name","l")
              .likeRight("age","6")  //右,指的是%在右边
              .likeLeft("name","i");  //左,指的是%在左边
       userMapper.selectMaps(wrapper).forEach(System.out::println);
  }

notlike:字段中不包含

likeright:字段右模糊查询

likeleft:字段左模糊查询

 

@Test
   void join(){
       QueryWrapper<User> wrapper = new QueryWrapper<>();
       wrapper.inSql("id","select id from user where id<7");
       //这是id在子查询中,查询出来   拼接SQL
      //in查询
       userMapper.selectObjs(wrapper).forEach(System.out::println);
  }

 

 

@Test
   void order(){
       QueryWrapper<User> wrapper = new QueryWrapper<>();
  //     wrapper.orderByDesc("id"); //降序排列
       wrapper.orderByAsc("id");  //升序排列
       userMapper.selectList(wrapper).forEach(System.out::println);
  }
 

保存的时间少了8个小时的问题

问题出在驱动配置的时区上

datasource:
   username: root
   password: 111111
   url: jdbc:mysql://11.12.2.55:3306/sevenstarts?serverTimezone=Asia/Shanghai&allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8
   driver-class-name: com.mysql.cj.jdbc.Driver
   type: com.alibaba.druid.pool.DruidDataSource

时区配置改成Asia/Shanghai就好了

 

代码生成器

1.先建一个包,建一个类

package com.kuang.demo.wsk;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import java.util.ArrayList;
//代码自动生成器
public class WskCode {
   public static void main(String[] args) {
       //我们需要构建一个代码生成器对象
       AutoGenerator mpg = new AutoGenerator();
       //怎么样去执行,配置策略
       //1、全局配置
       GlobalConfig gc = new GlobalConfig();
       String projectPath = System.getProperty("user.dir");//获取当前目录
       gc.setOutputDir(projectPath+"/src/main/java");//输出到哪个目录
       gc.setAuthor("shiyi");
       gc.setOpen(false);
       gc.setFileOverride(false);//是否覆盖
       gc.setServiceName("%sService");//去Service的I前缀
       gc.setIdType(IdType.ID_WORKER);
       gc.setDateType(DateType.ONLY_DATE);
       gc.setSwagger2(true);
       mpg.setGlobalConfig(gc);
       //2、设置数据源
       DataSourceConfig dsc = new DataSourceConfig();
       dsc.setUsername("root");
       dsc.setPassword("123456");
       dsc.setUrl("jdbc:mysql://127.0.0.1:3306/test001?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8");
       dsc.setDriverName("com.mysql.cj.jdbc.Driver");
       dsc.setDbType(DbType.MYSQL);
       mpg.setDataSource(dsc);
       //3、包的配置
       PackageConfig pc = new PackageConfig();
       pc.setModuleName("study");
       pc.setParent("com.wsk");
       pc.setEntity("pojo");
       pc.setMapper("mapper");
       pc.setService("service");
       pc.setController("controller");
       mpg.setPackageInfo(pc);
       //4、策略配置
       StrategyConfig strategy = new StrategyConfig();//需要生成那个表,就把那个表写在下面
       strategy.setInclude("demo1");//设置要映射的表名,只需改这里即可
       strategy.setNaming(NamingStrategy.underline_to_camel);
       strategy.setColumnNaming(NamingStrategy.underline_to_camel);
       strategy.setEntityLombokModel(true);//是否使用lombok开启注解
       strategy.setLogicDeleteFieldName("deleted");
       //自动填充配置
       TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
       TableFill gmtUpdate = new TableFill("gmt_update", FieldFill.INSERT_UPDATE);
       ArrayList<TableFill> tableFills = new ArrayList<>();
       tableFills.add(gmtCreate);
       tableFills.add(gmtUpdate);
       strategy.setTableFillList(tableFills);
       //乐观锁配置
       strategy.setVersionFieldName("version");
       strategy.setRestControllerStyle(true);//开启驼峰命名
       strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
       mpg.setStrategy(strategy);
       mpg.execute();//执行
  }
}

需要创建那个表,就在4.策略配置那个该相应表名即可。

  <!--3.mybatis-plus  版本很重要3.0.5-->
      <dependency>
          <groupId>com.baomidou</groupId>
          <artifactId>mybatis-plus-boot-starter</artifactId>
          <version>3.0.5</version>
      </dependency>
      <!--4.h2-->
      <dependency>
          <groupId>com.h2database</groupId>
          <artifactId>h2</artifactId>
          <scope>runtime</scope>
      </dependency>

      <!--模板引擎 依赖:mybatis-plus代码生成的时候报异常-->
      <dependency>
          <groupId>org.apache.velocity</groupId>
          <artifactId>velocity-engine-core</artifactId>
          <version>2.0</version>
      </dependency>
      <!--配置ApiModel在实体类中不生效-->
      <dependency>
          <groupId>com.spring4all</groupId>
          <artifactId>spring-boot-starter-swagger</artifactId>
          <version>1.5.1.RELEASE</version>
      </dependency>
      <!--freemarker-->
      <dependency>
          <groupId>org.freemarker</groupId>
          <artifactId>freemarker</artifactId>
          <version>2.3.30</version>
      </dependency>
      <!--beetl-->
      <dependency>
          <groupId>com.ibeetl</groupId>
          <artifactId>beetl</artifactId>
          <version>3.3.2.RELEASE</version>
      </dependency>

写写就行了,不建议用,最起码等等自己完全没问题在用

 

mybatis plus

特点:所有的crud代码都可以自动化完成!

 

特征:1.无侵入

2.损耗小

3.强大的crud操作

4.支持主键生成

5.内置代码生成器

6.内置分页插件

.........

 

 

使用第三方组件一般步骤:

1.导入对应的依赖

2.研究依赖如何配置

3.代码如何编写

4.提高扩展技术能力

 

配置:

 <!--1.数据库驱动-->
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <scope>runtime</scope>
       </dependency>
       <!--2.lombok-->
       <dependency>
           <groupId>org.projectlombok</groupId>
           <artifactId>lombok</artifactId>
       </dependency>
       <!--3.mybatis-plus  版本很重要3.0.5-->
       <dependency>
           <groupId>com.baomidou</groupId>
           <artifactId>mybatis-plus-boot-starter</artifactId>
           <version>3.0.5</version>
       </dependency>
       <!--4.h2-->
       <dependency>
           <groupId>com.h2database</groupId>
           <artifactId>h2</artifactId>
           <scope>runtime</scope>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
       </dependency>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
spring:
datasource:
  driver-class-name: com.mysql.cj.jdbc.Driver
   #url: jdbc:mysql://127.0.0.1:3306/test001?ullNamePatternMatchesAll=true&amp;serverTimezone=GMT%2b8?useUnicode=true&characterEncoding=utf8
  url: jdbc:mysql://127.0.0.1:3306/test001?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
  username: root
  password: 123456


注意:#号后面是平常的,这里如果是这个就会报错,用下面那个。

 

 

这个就写实体类,和mapper接口就可以了

例子:

package com.kuang.demo.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
//get set toString 方法不用写了
//所有的有参构造方法不用写了
//所有的无参构造方法也不用写了
public class User {
   private Long id;
   private String name;
   private Integer age;
   private String email;
}

 

package com.kuang.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.kuang.demo.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
//在对应的mapper上面继承基本的接口 BaseMapper
public interface UserMapper extends BaseMapper<User> {
   List<User> selectList();
   //到这里所有的crud已经完成,不需要配置了
}

 

测试
   package com.kuang.demo;

import com.kuang.demo.mapper.UserMapper;
import com.kuang.demo.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class DemoApplicationTests {
   //继承了BaseMapper,所有的方法来自自己的父类,我们也可以编写自己的方法
   @Autowired
   private UserMapper userMapper;


   @Test
   void contextLoads() {
       //参数是一个wrapper,条件构造器,这里先不用写成null
       //查询全部用户
       List<User> users = userMapper.selectList(null);
       users.forEach(System.out::println);
  }

}

因为plus里面的SQL是不可见的,所以要加日志

在配置文件里面加

mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

这是默认日志,不需要导入依赖。

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

 

主键生成策略

分布式系统唯一id生成(默认的id生成)

1.雪花算法(snowflake)

是推特开源的分布式id生成算法,结果是一个long型的id,可以保证全球唯一。

 

我们需要配置主键自增:

1.实体类字段上 @TableId(type=Idtype.AUTO)

2.数据库字段一定要是自增!

3.再次测试即可

 

解释:

public enum IdType {
   AUTO(0),  //数据库id自增
   NONE(1),//为设置主键
   INPUT(2),//手动输入
   ID_WORKER(3),//默认的全局id
   UUID(4), //全局唯一id,UUID
   ID_WORKER_STR(5);//字符串表示法

 

更新操作

 @Test
   public void testUpdate(){
       User user = new User();
      //通过条件自动拼接动态SQL
       user.setName("卡面打");
     // user.setEmail("648532946@qq.com");
       user.setAge(7);
       user.setId(1478543865383448578L);
       int i = userMapper.updateById(user);
       System.out.println(i);
  }

//丢入的是一个对象,而不是某个字段
//setId,是数据库里面有才行

 

自动填充

创建时间 ,修改时间!这些个操作一遍都是自动化完成的,我们不希望手动更新。

阿里巴巴开发手册:所有的数据库:gmt_create,gmt_modified几乎所有的表都要配置上!而且需要自动化!

方法一:数据库级别(不建议使用)

1.在表中新增字段create_time,update_time

数据库类型:datetime

默认:CREATE_TIMESTAMP

更新打钩

2.再次测试插入方法,我们需要先把实体类同步!

 

方式二:代码级别(推荐使用)

1.删除数据库的默认值,更新操作!

2.实体类字段属性上需要增加注解

 //字段添加填充内容
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;

3.编写处理器来处理这个注解即可!

package com.kuang.demo.handler;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.util.Date;

//要被识别,必须要丢到springboot里面,也就是@Component
@Component //处理器加到IOC容器中
@Slf4j
//加一些日志
public class MyHandler implements MetaObjectHandler {
//插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill............");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill............");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}

基本上这个处理器就不变了,就字段跟在来

 

 

程序员灯塔
转载请注明原文链接:mybatisplus
喜欢 (0)