• Mybatis-Plugs开发手册


    Mybatis-Plugs为简化代码而生

    mybatis增强工具包

    [enbatis]

    [Mybatis-Plugs]

    [2022年8月]

    [一阵清风]

    目录

    1. 介绍 1

    1.1简介 1

    1.2目的 1

    1.3特性 1

    2. 快速开始 1

    2.1创建表 1

    2.2 创建springboot项目 1

    2.3配置maven 3

    2.4配置yml 4

    2.4修改启动类 5

    3. 代码生成器 5

    3.1配置代码生成器 5

    3.2使用方法 6

    3.3建立代码包 7

    3.4复制代码 8

    3.5启动项目 8

    4. CRUD 接口 8

    4.1插入接口 9

    4.1.1单条插入 9

    4.1.2批量插入 9

    4.2删除接口 10

    4.2.1单个删除 10

    4.2.2批量删除 11

    4.3 修改接口 11

    4.3.1单个修改 11

    4.3.2批量修改 12

    4.4列表查询接口 13

    4.5分页查询 14

    4.6查询单条 15

    4.7查询数量 15

    5. 条件构造器Wrapper 16

    5.1 eq构造 16

    5.2 ne构造 16

    5.3 like构造 16

    5.4 in构造 17

    6. 登录认证 17

    6.1创建JWT 17

    6.2解析JWT 20

    6.3封装登录实体 21

    7. 拦截器 21

    7.1介绍 21

    7.2拦截请求 23

    7.3放行请求 23

    8. 枚举转换 24

    8.1定义枚举类 24

    8.2实体类引用枚举 26

    8.3增加配置文件 26

    Mybatis-Plugs

    1. 介绍

    1.1简介

    Mybatis-plugs是基于mybatis开发的一款增强的持久层框架。

    只需在springboot项目中引入依赖mybatis-plugs-spring-boot-starter

    即可实现mybatis的CRUD简化操作,不用在书写基本的增删改查sql。

    1.2目的

    Mybatis-plugs为简化代码而生。

    1.3特性

    不对mybatis做任何修改 只做mybatis的扩展增强。

    代码自动生成,根据表名可快速生成xxxMapper.java、xxxService.java、xxxServiceImpl.java、xxxController.java、xxxMapper.xml文件。

    依赖少,仅仅依赖 mybatis-plugs-spring-boot-starter

    自动填充创建时间,更新时间,创建人等信息。

    内置基于Mybatis物理分页的分页插件。

    自动记录sql执行的时间,方便定位慢查询。

    代码简洁,方便理解。

    内置接口拦截器,通过注解确定是否拦截请求。

    1. 快速开始

    我们将通过一个简单的 Demo 来阐述 MyBatis-Plugs 的强大功能,在此之前,我们假设您已经:

    a.拥有 Java 开发环境、相应 IDE以及mysql数据库

    b.熟悉 Spring Boot

    c.熟悉 Maven

    如果从零开始用 MyBatis-Plugs来实现该表的增删改查我们需要做什么呢?

    2.1创建表

    现有一张 sys_user 表,其对应的数据库 Sql 脚本如下:

    CREATE TABLE sys_user ( id bigint NOT NULL COMMENT '主键ID', name varchar(30) COMMENT '姓名', age int COMMENT '年龄', phone varchar(11) COMMENT '电话', PRIMARY KEY (id))

    2.2 创建springboot项目

    使用 idea 创建SpringBoot项目

    第一步:

    第二步:

    第三步:选择LomBok插件

    项目基本结构

    2.3配置maven

    springBoot项目建立好之后,在pom.xml文件加入mybatis-plugs的依赖

    mybatis-plugs-spring-boot-starter

    当前最新版本 mybatis-plugs-spring-boot-starter

    <dependency>  <groupId>com.enbatis</groupId>  <artifactId>mybatis-plugs-spring-boot-starter</artifactId>  <version>当前最新版本</version></dependency>

    小提示:

    引入 mybatis-plugs-spring-boot-starter 之后无需再次引入mybatis

    2.4配置yml

    修改 application.properties 为application.yml

    新增 开发环境:application-dev.yml

    新增 测试环境:application-test.yml

    新增 生产环境:application-pro.yml

    小说明

    1.开发环境为我们进行开发所使用的配置

    2.测试环境为测试人员进行软件测试所使用的配置

    3.生产环境为上线部署所使用的配置

    application.yml

    spring:  profiles:    active: devserver:  port: 8080

    tips:

    spring:  profiles:    active: dev

    指定所使用的环境

    port:8080

    指定项目所启动的端口为8080端口

    application-dev.yml

    2.4修改启动类

    在启动类上加上Mapper扫描的注解

    @MapperScan("com.xxxxx.xxxxx.mapper")

    3. 代码生成器

    我们通过数据库表可以快速生成

    entity,controller,mapper,service,serviceImpl,mapping.xml

    生成代码需要连接数据库,所以我们需要进行数据库的连接,只需要通过配置数据库基本信息,利用mybatis-plugs的代码生成类 CodeGenerator2 即可

    3.1配置代码生成器

    在启动类的同级目录下,建立生成器类 CodeGenerate

    import com.enbatis.mybatisplugs.generate.CodeGenerator2; public class CodeGenerate {   private static String url="jdbc:mysql://127.0.0.1:3306/test?serverTimezone=UTC& useUnicode=true&characterEncoding=utf8&useSSL=false";    private static String user="root";    private static String psd="111111";    private static String filePath="D://generate_code//";    public static void main(String[] args) {     CodeGenerator2 codeGenerator2=new CodeGenerator2(url,user,psd,filePath);     codeGenerator2.generate(CodeGenerate.class);   } } 

    注释:

    url:数据库连接url

    root:数据库用户名

    psd:数据库密码

    filePath:java代码生成位置(防止代码覆盖所以我们不会自动生成到对应的代码位置)

    CodeGenerator2: mybatis-plugs代码核心生成器

    3.2使用方法

    1. 执行main方法

    2. 在控制台输入作者 以及 要生成代码的表

    1. 输入完成之后点击回车

    2. 当输出以下信息表示代码生成成功

    1. 去代码生成的位置查看生成的代码

    3.3建立代码包

    建立代码包:entity、controller、mapper、service、impl以及xml的文件夹

    3.4复制代码

    将生成的代码复制到对应的文件夹

    3.5启动项目

    启动项目 访问 http://localhost:8080/v1/sys_user/list 查询所有用户列表

    4. CRUD 接口

    说明:通过封装mybatis的 BaseService接口即可快速实现数据库的CRUD操作

    泛型 T 为任意实体对象;参数 Serializable 为任意类型主键 Mybatis-Plugs 不推荐使用复合主键约定每一张表都有自己的唯一 id 主键;对象 Wrapper 为 条件构造器。

    4.1插入接口

    4.1.1单条插入

    /**

    * 插入一条记录

    * @param entity 传入的插入对象

    * @return T

    */

    T insert(T entity);

    使用方法:在serviceImpl层写代码示例如下

    SysUser user = new SysUser();user.setName("张三");user.setAge(32);user.setPhone("13615425135");super.insert(user);

    4.1.2批量插入

    /**

    * 批量插入

    * @param entityList

    * @return

    */

    int saveBatch(List entityList);

    使用方法:在serviceImpl层写代码示例如下

    List<SysUser> sysUserList = new ArrayList<>();for (int i = 0; i <10 ; i++) {SysUser sysUser = new SysUser();sysUser.setName("张三"+i);sysUser.setAge(30+i);sysUser.setPhone("1361542513"+i);sysUserList.add(sysUser);}super.saveBatch(sysUserList);

    4.2删除接口

    4.2.1单个删除

    /**

    * 根据id删除一条数据

    * @param id 传入的查询ID

    * @return 删除条数

    */

    int deleteById(Serializable id);

    使用方式:在serviceImpl层写代码示例如下

    super.deleteById(12000012);

    4.2.2批量删除

    /**

    * 批量删除

    * @param wrapper

    * @return

    */

    int delete(Wrapper wrapper);

    使用方式:在serviceImpl层写代码示例如下

    Wrapper wrapper = new Wrapper<SysUser>();wrapper.eq("age",30);wrapper.like("name","张三");super.delete(wrapper);

    说明:关于条件构造器会专门讲解。

    4.3 修改接口

    4.3.1单个修改

    /**

    * 根据id更新一条数据

    * @param bean 传入的更新对象

    * @return 返回更新条数

    */

    int updateById(T bean);

    使用方式:在serviceImpl层写代码示例如下

    SysUser sysUser = new SysUser();sysUser.setId(1234561114L);sysUser.setPhone("13615425135");sysUser.setAge(36);super.updateById(sysUser);

    4.3.2批量修改

    /**

    * 批量修改

    * @param entityList

    * @return

    */

    int updateBatchById(List entityList);

    使用方式:在serviceImpl层写代码示例如下

    List<SysUser> sysUserList = new ArrayList<>();SysUser sysUser = new SysUser();sysUser.setId(111100001101L);sysUser.setAge(35);sysUserList.add(sysUser);SysUser sysUser2 = new SysUser();sysUser2.setId(111100001102L);sysUser2.setAge(32);sysUserList.add(sysUser);super.updateBatchById(sysUserList);

    4.4列表查询接口

    /**

    * 查询列表数据

    * @param wrapper 查询条件

    * @return 集合

    */

    List list(Wrapper wrapper);

    使用方式:在serviceImpl层写代码示例如下

    Wrapper wrapper = new Wrapper<SysUser>();wrapper.like("name","张三");List<SysUser> list = super.list(wrapper);

    4.5分页查询

    /**

    * 分页查询

    * @param page

    * @param wrapper

    * @return

    */

    Page page(Page page, Wrapper wrapper);

    使用方式:在controller层写代码示例如下

    @PostMapping("/page")public ResultReturn<Page<SysUser>> getPage(@RequestBody SysUser user){return success(sysUserService.page( getPage(),new Wrapper(user)));}

    说明:controller需要继承BaseController

    4.6查询单条

    /**

    * 根据id获取

    * @param id 对象ID

    * @return 对象

    */

    T getById(Serializable id);

    使用方式:在controller层写代码示例如下

    @GetMapping("/{id}")public ResultReturn<SysUser> get(@PathVariable("id") Long id) {return success(sysUserService.getById(id));}

    4.7查询数量

    /**

    * 查询count

    * @param wrapper 查询条件

    * @return 数量

    */

    int selectCount(Wrapper wrapper);

    使用方式:在serviceImpl层写代码示例如下

    Wrapper wrapper = new Wrapper<SysUser>();wrapper.like("name","张三");int count = super.selectCount(wrapper);

    5. 条件构造器Wrapper

    5.1 eq构造

    如果我们想快速查询数据库表sys_user 的姓名为 “Tom” 如何进行操作呢?

    回答:只需service调用list 传入 条件构造器Wrapper Wrapper调用 eq 方法,下面的方法即为 查询姓名是Tom的SysUser列表

    sysUserService.list(new Wrapper<>(sysUser).eq("name","Tom"));

    5.2 ne构造

    如果我们想快速查询数据库表sys_user 的姓名不是 “Tom” 如何进行操作呢?

    回答:只需service调用list 传入 条件构造器Wrapper Wrapper调用 ne 方法,下面的方法即为 查询姓名不是Tom的SysUser列表

    sysUserService.list(new Wrapper<>(sysUser).ne("name","Tom"));

    5.3 like构造

    如果我们想根据姓名模糊查询,怎么操作呢?

    回答:只需service调用list 传入 条件构造器Wrapper Wrapper调用 like 方法,下面的方法即为 根据姓名“Tom”模糊查询

    sysUserService.list(new Wrapper<>(sysUser).like("name","Tom"));

    5.4 in构造

    如果我们想查询姓名是“Tom”,“Jack”,“June”怎么操作呢?

    回答:只需service调用list 传入 条件构造器Wrapper Wrapper调用 in 方法,传入ArrayList即可

    List arrayList=new ArrayList<>(); arrayList.add("Tom"); arrayList.add("Jack"); arrayList.add("June");sysUserService.list(new Wrapper<>(sysUser).in("name",arrayList));

    扩展:

    以上只列出部分条件构造器的方法,我们还有notNull(非空查询)、isNull(空值查询)、setSqlSelect(固定列查询)等等, 更多请查看 mybatis-plugs

    6. 登录认证

    Mybatis-Plugs内部封装了JWT token认证,做登录功能时可直接进行使用。

    6.1创建JWT

    Mybatis-Plugs提供了JwtUtil工具类来进行token的创建,具体的方法来介绍下:

    /*** 前三个参数为自己用户token的一些信息比如id,权限,名称等。不要将隐私信息放入(大家都可以获取到)* @param map 需要加密的信息* @param security 加密字符串* @param expire 失效时间 毫秒* @return*/public static String createJwt(Map<String,Object> map,String security,long expire) {//添加构成JWT的参数JwtBuilder builder = Jwts.builder().setHeaderParam("typ", "JWT").setIssuedAt(new Date()).setExpiration(new Date(System.currentTimeMillis()+expire)).setClaims(map).signWith(generalKey(security),SignatureAlgorithm.HS256);//生成JWTreturn builder.compact();}

    如果不传失效时间会默认24小时,我们提供了一个重载的方法

    /*** 创建JWT 默认失效时间是24小时* @param map 需要加密的信息* @param base64Security 加密字符串* @return*/public static String createJwt(Map<String, Object> map, String base64Security) {return createJwt(map,base64Security,EXPIRE);}

    具体如何使用?请参照以下代码:

    //获取登录用户名

    String username =user.getUsername();String password= MD5Util.generate(user.getPassword());List list=list(new Wrapper().eq("username",username).eq("password",password));Optional<SysUser> first= list.stream().filter(dbUser->dbUser.getUsername().equals(username)&&dbUser.getPassword().equals(password)).findFirst();if (first.isPresent()){user.setUsername(username);SysUser sysUser= first.get();Map<String,Object> userMap = new HashMap<>();userMap.put("userId",sysUser.getId()+"");userMap.put("name",sysUser.getName());userMap.put("companyId",sysUser.getCompanyId());userMap.put("username",sysUser.getUsername());userMap.put("effective", System.currentTimeMillis()+(120*60*1000));String token= JwtUtil.createJwt(userMap, JwtUtil.LOGIN_BASE);response.addHeader("authorization",token);Cookie cookie = new Cookie("authorization",token);cookie.setDomain(domain);cookie.setPath("/");response.addCookie(cookie);SysUser user1= first.get();SysUserVO vo = new SysUserVO();BeanUtils.copyProperties(user1,vo);vo.setAuthorization(token);vo.setImgHead(sysUser.getAvatarUrl());return  ResultReturn.success(vo);}

    6.2解析JWT

    Mybatis-Plugs提供了JwtUtil工具类来进行token的解析,具体的方法来介绍下:

    /*** 解密* @param jsonWebToken token字符串* @param security 加密字符串* @return*/public static Claims parseJwt(String jsonWebToken, String security) {try {Jws<Claims> claimsJws = Jwts.parserBuilder().setSigningKey(Keys.hmacShaKeyFor(security.getBytes(StandardCharsets.UTF_8))).build().parseClaimsJws(jsonWebToken);return claimsJws.getBody();} catch (Exception ex) {ex.printStackTrace();return null;}}

    6.3封装登录实体

    登录成功之后,可以用token获取到登录实体Account,用来获取登录用户,具体方法如下:

    public static Account account(String token,String security){Claims claims= JwtUtil.parseJwt(token,security);String userId= (String)claims.get("userId");String username= (String)claims.get("username");Integer companyId= (Integer)claims.get("companyId");Account account = new Account();account.setId(Long.parseLong(userId));account.setUsername(username);if(null!=companyId){account.setCompanyId(Long.parseLong(Integer.toString(companyId)));}return account;}

    其中token是jwt生成的token,security为加密字符串,token可以从head或者cookie里面获取。

    具体的使用方式见如下代码:

    Account account = JwtUtil.account(request.getHeader("Authorization"),"xxxx");

    7. 拦截器

    7.1介绍

    Mybatis-plugs的拦截器有记录请求方法执行时间、过滤非登录用户请求的功能,在controller里面使用注解即可拦截未登录请求。

    使用方法:

    自定义拦截器并继承类:

    com.enbatis.mybatisplugs.commons.Interceptor.Interceptor

    实例代码如下:

    @Componentpublic class ReqInterceptor extends Interceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{return super.preHandle(request,response,handler);}}

    接下来是注册拦截器,新建类WebConfigurer 并实现WebMvcConfigurer接口,代码如下:

    @Configurationpublic class WebConfigurer implements WebMvcConfigurer {@Autowiredprivate ReqInterceptor interceptor;/*** @Description  这个方法是用来配置静态资源的,比如html,js,css,等等* @Param [registry]* @return void**/@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {}/*** @Description  这个方法用来注册拦截器,我们自己写好的拦截器需要通过这里添加注册才能生效* @Date 9:34 2022/2/7* @Param [registry]* @return void**/@Overridepublic void addInterceptors(InterceptorRegistry registry) {// addPathPatterns("/**") 表示拦截所有的请求,registry.addInterceptor(interceptor).addPathPatterns("/**");}}

    配置完成即可实现Mybatis-Plugs拦截器的功能。

    7.2拦截请求

    Controller方法不加任何注解或者加注解 @Login(handler = Handler.INTERCEPT)即可起到拦截请求的功能,如果用户未登录就访问接口,系统会抛出未登录的信息。

    7.3放行请求

    有一部分请求是不需要登录就直接能访问的,比如说注册接口,登录接口等等,这时候使用注解@Login(handler = Handler.PASS)即可放行请求,即不需要登录即可访问,代码示例如下:

    注册接口:

    @Login(handler = Handler.PASS)@PostMapping("/register")public ResultReturn registerUser(@RequestBody SysUserVO sysUser){sysUser.setCompanyId(0L);return  sysUserService.registerUser(sysUser);}

    登录接口:

    @Login(handler = Handler.PASS)@PostMapping("/login")public ResultReturn login(@RequestBody SysUserVO vo){return  sysUserService.login(vo,request,response);}

    8. 枚举转换

    有时候数据库里面存的是数字类型,但是在实体类里面我们要使用枚举类,这种情况Mybatils-Plugs提供了比较方便快捷的方式来实现需求。

    8.1定义枚举类

    先自定义枚举类并实现com.enbatis.mybatisplugs.enums.BaseEnum接口,代码如下:

    import com.enbatis.mybatisplugs.enums.BaseEnum;public enum StatusEnum implements BaseEnum<StatusEnum,Integer> {    ORDERED(0,"已下单"),    PAYED(1,"已付款"),    DELIVER(2,"代发货"),    DELIVERED(3,"已发货"),    RECEIVED(4,"已收货"),    OK(5,"订单完成");
        private final Integer value;    private final String description;
        StatusEnum(Integer value, String description) {        this.value = value;        this.description = description;    }    public StatusEnum getEnumByValue(Long value) {        StatusEnum[] enums = StatusEnum.values();        for (StatusEnum e : enums) {            if (e.getValue().equals(value)) {                return e;            }        }        return null;    }    @Override    public Integer getValue() {        return value;    }
        @Override    public String getDescription() {        return description;    }}

    8.2实体类引用枚举

    需要在实体类里面将字段更改为枚举类型,如下:

    /*** 订单状态(*/private StatusEnum status;

    8.3增加配置文件

    需要在配置文件里面添加对枚举转换的类:

    com.enbatis.mybatisplugs.plugin.parser.AutoEnumTypeHandler

    代码如下:

    mybatis:  mapper-locations: classpath:/mapping/*.xml  type-aliases-package: com.panpan.housesale.entity  configuration:    map-underscore-to-camel-case: true    #log-impl: org.apache.ibatis.logging.stdout.StdOutImpl    default-enum-type-handler: com.enbatis.mybatisplugs.plugin.parser.AutoEnumTypeHandler

    通过这三个步骤的操作,就可以实现,数据库字段类型与枚举类型的匹配。

  • 相关阅读:
    Java 函数式编程思考 —— 授人以渔
    时间序列-ARIMA
    WebStorm 运行 nodejs 脚本 路径不对
    卷积神经网络大致结构、卷积层设计的参数、卷积结果计算公式、卷积参数的共享、池化层、卷积神经网络的具体结构、感受野、推荐使用的卷积神经网络
    【管理工具】CMAK安装和使用(kafka-manager)
    LeetCode刷题---简单组(二)
    【金九银十必问面试题】站在架构师角度分析问题,如何解决TCC中的悬挂问题
    力扣(300,674)补9.11
    Nexus私服仓库Linux、Windows部署教程
    python面试题——怎么实现时间的加减计算
  • 原文地址:https://blog.csdn.net/wwd8979/article/details/126509294