SpringBoot 整合 MyBatis

介绍

mybatis是一个用Java编写的持久层框架,它使用ORM实现了结果集的封装。

ORM是Object Relational Mapping 对象关系映射。简单来说,就是把数据库表和实体类及实体类的属性对应起来,让开发者操作实体类就实现操作数据库表。

它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等烦杂过程。

而MyBatis Generator(简称MBG),如果实际开发中数据库的表特别多,那么我们需要手动去写每一张表的po类,xxxMapper.xml,xxxMapper.java文件,这显然需要花费巨大的精力,而且可能由于表字段太多,写错了而不知道也是可能的。

所以我们在实际开发中,一般使用逆向工程方式来自动生成所需的文件。

mybatis是目前很流行的持久层框架,其逆向工程更是大大缩减了我们的开发时间。所谓mybatis逆向工程,就是mybatis通过相应插件,根据我们设计好的数据表,针对单表自动生成pojo、mapper以及mapper.xml。

mybatis分页可以减少数据的处理量,分页的方式有两种:limit分页、PageHelper分页插件。

使用 Validator 校验参数,主要是用于检查程序代码中参数的有效性。

添加maven依赖

        <!-- 集成mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.2</version>
        </dependency>

        <!-- mysql 数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.30</version>
        </dependency>

        <!-- druid 连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.12</version>
        </dependency>
        	
        <!-- MyBatis Generator 逆向工程-->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.4.1</version>
        </dependency>

        <!-- pagehelper 分页插件 -->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.4.3</version>
        </dependency>

        <!-- 校验 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

逆向工程

新增generatorConfig.xml文件

  1. 连接数据库的配置,包括数据名称,数据库用户名密码等配置
  2. 指定要生成代码的包名,包括实体类po的包名,mapper的包名等
  3. 指定数据库中哪些表需要生成文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <context id="Mysql" targetRuntime="MyBatis3" defaultModelType="flat">

        <!-- 自动检查关键字,为关键字增加反引号 -->
        <property name="autoDelimitKeywords" value="true"/>
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>

        <!--覆盖生成XML文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
        <!-- 生成的实体类添加toString()方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>

        <!-- 不生成注释 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/demo?serverTimezone=Asia/Shanghai"
                        userId="root"
                        password="123456">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>

        <!-- domain类的位置 -->
        <javaModelGenerator targetProject="src\main\java"
                            targetPackage="com.example.demo.entity"/>

        <!-- mapper xml的位置 -->
        <sqlMapGenerator targetProject="src\main\resources"
                         targetPackage="mapper"/>

        <!-- mapper类的位置 -->
        <javaClientGenerator targetProject="src\main\java"
                             targetPackage="com.example.demo.mapper"
                             type="XMLMAPPER"/>

        <!-- 指定数据库表,要生成哪些表,就写哪些表,要和数据库中对应,不能写错! -->
        <table tableName="sys_user" domainObjectName="SysUser"/>

    </context>
</generatorConfiguration>

一般新增的generatorConfig.xml文件都放在项目的 src/main/resources 下面新建一个 generator包里面。

执行generatorConfig.xml文件,生成代码

  • 【方式一】安装插件
  • 【方式二】java代码

注意点:
使用逆向工程时,最好新建一个工程,如果你在原来的工程中使用,也是可以的, 但是有一定的风险,因为mybatis是根据配置文件中配置的路径来生成的文件的,如果你工程中有相同名字的文件,那么就会被新生成的文件所覆盖。所以实际开发中, 我们一般新建一个工程,将生成的文件复制到自己的所需的工程中。

【方式一】安装插件(个人推荐)

            <!-- mybatis generator 自动生成代码插件 -->
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.4.0</version>
                <configuration>
                    <configurationFile>src/main/resources/generator/generatorConfig.xml</configurationFile>
                    <overwrite>true</overwrite>
                    <verbose>true</verbose>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>mysql</groupId>
                        <artifactId>mysql-connector-java</artifactId>
                        <version>8.0.30</version>
                    </dependency>
                </dependencies>
            </plugin>

操作步骤

打开编辑运行对话框点击【编辑配置】(图)
点击加号(+),并选择Maven
在运行那里输入指定字段【mybatis-generator:generate -e】
在名称那里自定义名称编写
最后点击应用和确定,就可以点击右侧的绿色小箭头运行了

在这里插入图片描述
在这里插入图片描述
【方式二】java代码

package com.example.test;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class MybatisGenerator {
    public void testGenerator() throws Exception {
        List<String> warnings = new ArrayList<>();
        boolean overwrite = true;
        //指定逆向工程配置文件
        File configFile = new File("src/main/resources/generator/generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config,callback,warnings);
        myBatisGenerator.generate(null);
    }

    public static void main(String[] args) throws Exception {
        MybatisGenerator generator = new MybatisGenerator();
        generator.testGenerator();
    }
}

直接运行main方法就行了!

最后,注意一下,生成什么表就在generatorConfig.xml文件里面放入什么表,已经生成的表,把注释或者删除就行了,以防重复生成。
mybatis的逆向工程实现起来其实是非常简单的,但是在不同情况下,要特别注意文件路径的问题。
其中,XxxExample.java只能实现简单条件增删改查,复杂的功能还需要自己编写sql代码来实现。
注意,在配置文件中配置对应生成文件的所在目录时,最好使用绝对路径

配置文件application.yml

基础的一些配置:

  1. 设置端口号
  2. 配置数据库连接
  3. 配置mybatis的mapper路径
  4. SQL打印日志
server:
  port: 8087 # 重新设置端口号

spring:
  datasource: #增加数据库链接
    url: jdbc:mysql://localhost:3306/demo?characterEncoding=UTF8&autoReconnect=true&serverTimezone=Asia/Shanghai&allowMultiQueries=true
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:  #配置mybatis所有Mapper.xml所在的路径
  mapper-locations: classpath:/mapper/**/*.xml

logging: #SQL日志打印
  level:
    com.example.demo.mapper: trace

在SpringBoot项目的启动类上面添加@MapperScan注解

package com.example.demo;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("com.example.demo.mapper")
public class DemoApplication {

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

}

简单的增删改查

【controller】

这里我没有用数据库表的实体类,是用了实体类的复制版本,在日常的开发当中,需求不一样,如果都用实体类来做,容易乱,为了清晰的区分,像【SysUserSaveReq 】代表新增和更新的参数配置,【SysUserQueryReq 】代表查询(含条件查询)分页数据的参数配置,我们会在ServiceImpl业务实现层去替换成数据库的实体类做增删改查。

package com.example.demo.controller;

import com.example.demo.dto.req.query.SysUserQueryReq;
import com.example.demo.dto.req.save.SysUserSaveReq;
import com.example.demo.dto.resp.PageResp;
import com.example.demo.dto.resp.SysUserResp;
import com.example.demo.service.SysUserService;
import com.example.demo.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequestMapping("/sys/user")
public class SysUserController {

    @Autowired
    private SysUserService sysUserService;

    /**
     * 新增 / 更新
     * @param req
     * @return
     */
    @PostMapping("/save")
    public Result toSave(@Valid @RequestBody SysUserSaveReq req){
        int row = 0;
        if(ObjectUtils.isEmpty(req.getUserId())){
            row = sysUserService.toSave(req);
        }else {
            row = sysUserService.toUpdate(req);
        }
        if(row == 0){
            return Result.error();
        }
        return Result.success();
    }

    /**
     * 查询(含条件查询)
     * @param req
     * @return
     */
    @GetMapping("/list")
    public Result toList(@Valid SysUserQueryReq req){
        PageResp<SysUserResp> pageResp = sysUserService.getList(req);
        if(CollectionUtils.isEmpty(pageResp.getList())){
            return Result.error();
        }
        return Result.success(pageResp);
    }

    /**
     * 账号注销(逻辑删除)
     * @param userId
     * @return
     */
    @PutMapping("/logout/{userId}")
    public Result toLogout(@PathVariable Long userId){
        int row = sysUserService.toLogout(userId);
        if(row == 0){
            return Result.error();
        }
        return Result.success();
    }


}

【serviceImpl】

在业务实现层中的【SnowFlake 】类,是一种雪花算法的ID计算方式,【CopyUtil】类,是封装的对Object对象和List数据的复制方法,我们在复制对象的时候直接调用即可。

package com.example.demo.service.impl;

import com.example.demo.common.GlobalCommon;
import com.example.demo.dto.req.query.SysUserQueryReq;
import com.example.demo.dto.req.save.SysUserSaveReq;
import com.example.demo.dto.resp.PageResp;
import com.example.demo.dto.resp.SysUserResp;
import com.example.demo.entity.SysUser;
import com.example.demo.entity.SysUserExample;
import com.example.demo.mapper.SysUserMapper;
import com.example.demo.service.SysUserService;
import com.example.demo.utils.CopyUtil;
import com.example.demo.utils.SnowFlake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.List;

@Service
public class SysUserServiceImpl implements SysUserService {

    @Autowired
    private SnowFlake snowFlake;

    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 新增
     * @param req
     * @return
     */
    @Override
    public int toSave(SysUserSaveReq req) {
        SysUser sysUser = CopyUtil.copy(req, SysUser.class);
        long id = snowFlake.nextId();
        sysUser.setUserId(id);
        sysUser.setCreateDate(new Date());
        sysUser.setState(GlobalCommon.STATE);
        sysUser.setDelFlag(GlobalCommon.DEL_FLAG);
        int insert = sysUserMapper.insert(sysUser);
        return insert;
    }

    /**
     * 修改
     * @param req
     * @return
     */
    @Override
    public int toUpdate(SysUserSaveReq req) {
        SysUser sysUser = CopyUtil.copy(req, SysUser.class);
        sysUser.setUpdateDate(new Date());
        int update = sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return update;
    }

    /**
     * 查询(含条件查询)
     * @param req
     * @return
     */
    @Override
    public PageResp<SysUserResp> getList(SysUserQueryReq req) {
        // 条件
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        if(StringUtils.hasText(req.getUserName())){
            criteria.andUserNameEqualTo(req.getUserName());
        }
        if(StringUtils.hasText(req.getNickName())){
            criteria.andNickNameEqualTo(req.getNickName());
        }
        if(StringUtils.hasText(req.getPhone())){
            criteria.andPhoneEqualTo(req.getPhone());
        }
        if(!ObjectUtils.isEmpty(req.getSex())){
            criteria.andSexEqualTo(req.getSex());
        }
        if(!ObjectUtils.isEmpty(req.getState())){
            criteria.andStateEqualTo(req.getState());
        }
        if(!ObjectUtils.isEmpty(req.getDelFlag())){
            criteria.andDelFlagEqualTo(req.getDelFlag());
        }
        // 分页
        PageHelper.startPage(req.getPage(),req.getSize());
        // 查询
        List<SysUser> users = sysUserMapper.selectByExample(example);
        PageInfo<SysUser> pageInfo = new PageInfo<>(users);
        // 复制
        List<SysUserResp> respList = CopyUtil.copyList(users, SysUserResp.class);
        // 返回
        PageResp<SysUserResp> pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(respList);
        return pageResp;
    }

    /**
     * 账号注销(逻辑删除)
     * @param userId
     * @return
     */
    @Override
    public int toLogout(Long userId) {
        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setState(GlobalCommon.NO_STATE);
        sysUser.setDelFlag(GlobalCommon.N0_DEL_FLAG);
        sysUser.setUpdateDate(new Date());
        int update = sysUserMapper.updateByPrimaryKeySelective(sysUser);
        return update;
    }



}

运行测试

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结

以上就是 SpringBoot 整合 Mybatis 的一些内容,如果你觉得有帮助,请o( ̄▽ ̄)d点赞收藏!多多支持!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值