SpringBoot和MyBaitsPlus的整合

MyBaits是流行的数据库框架,提供了XML对象转换为SQL的功能,并且在此基础上增加了防注入等功能,首先使用idea创建一个Spring boot项目,并且等待Maven自动安装成功。

接下来配置pom.xml

    <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.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 模板-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--Mybatis-Plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.2.0</version>
        </dependency>
        <!-- MySQL 依赖 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <!-- lombok 依赖 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--hutool工具集-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.0.7</version>
        </dependency>
        <dependency>
            <groupId>org.freemarker</groupId>
            <artifactId>freemarker</artifactId>
            <version>2.3.28</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.47</version>
        </dependency>
    </dependencies>

配置完成后等待Maven安装成功,接下来在项目中的resources文件夹中创建mapper作为可能的XML存储位置,在java源代码文件中创建config文件夹作为配置类的存储文件夹,创建controller文件夹作为控制类文件夹,entity文件夹作为连接数据库的实体文件夹,mapper文件夹作为存储数据SQL(接口)(一般会在XML中指定包名为此mapper文件夹),service文件夹来存储服务类(接口),在service文件夹中创建impl文件夹用来实现服务接口。

接下来是配置编写,编写application.yml(python开发者当然用yaml)编写多配置。

spring:
  profiles:
    active: dev

接下来新建一个application-dev.yml作为开发时使用的配置,配置MySQL以及日志等信息。如下代码所示。

server:
  port: 8080
spring:
  # 图片上传,暂时先配置10MB
  servlet:
    multipart:
      max-request-size: 10MB
      file-size-threshold: 10MB
  # 数据源配置
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    # 配置时区: serverTimezone=GMT%2B8 表示北京时间,UTC 表示全球标准时间,比北京晚了 8 小时。
    # 是否指定 SSL连接: useSSL=false 表示不使用。
    url: jdbc:mysql://localhost:3306/qjh_simple_index?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    username: root
    password: root
  #缓存模式为redis先不用
  #  cache:
  #    type: redis
  #    #redis
  #    redis:
  #     host: XX.XX.XXX.XX
  #     port: 6379
  #     database: 0
  #     password: xxxxx
  #     timeout: 100s
  #     #连接池配置
  #     jedis:
  #       pool:
  #       #最大空闲连接数
  #       max-idle: 500
  #       #最小空闲连接数
  #       min-idle: 50
  #       #等待可用连接最大时间,负数为无限制
  #       max-wait: -1s
  #       #最大活跃连接时间
  #       max-active: -1
  #json返回时间格式设置
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss
    time-zone: GMT+8
    serialization:
      write-dates-as-timestamps: false
  # thymeleaf模板配置
  thymeleaf:
    prefix: classpath:/templates/
    check-template-location: true
    suffix: .html
    encoding: utf-8
    servlet:
      content-type: text/html
    mode: HTML5
    cache: false
#mybatis-plus
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath:mapper/*Mapper.xml
  global-config:
    # 逻辑删除配置
    db-config:
      # 删除前
      logic-not-delete-value: 0
      # 删除后
      logic-delete-value: 1
#分页插件
#pagehelper:
#  helper-dialect: mysql
#  params: count= countSql
#  reasonable: true
#  support-methods-arguments: true

#显示SQL语句日志,扫描项目mapper包下的所有类,对SQL语句进行控制台打印
logging:
  level:
    root: info
  file:
    path: logs

在这里顺带配置了日志存储的位置(根目录logs文件夹中)和日志输出的级别,Spring boot默认增加了日志,打印在命令行窗口中,可以设置为文件保存,这里配置一个logback-sping.xml用来配置各种不同的日志存储位置和按天实现日志的存储,如下代码所示。

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!--输出日志格式-->
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>
                %d - %msg%n
            </pattern>
        </layout>
    </appender>
    <!--只保存info日志-->
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFO</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径 项目里面的文件夹-->
            <fileNamePattern>${LOG_PATH}/info/info.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存warn日志-->
    <appender name="fileWarnLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>${LOG_PATH}/warn/warn.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <!--只保存error日志-->
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <encoder>
            <pattern>
                %d - %msg%n
            </pattern>
        </encoder>
        <!--滚动输出策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--路径-->
            <fileNamePattern>${LOG_PATH}/error/error.%d.log</fileNamePattern>
        </rollingPolicy>
    </appender>

    <root level="info">
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileWarnLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>

配置项目的mapper扫描器,通过装饰器注入,修改main方法所在的代码,如下代码所示。

package com.jsqj;

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

@SpringBootApplication
//配置Mapper扫描
@MapperScan("com.jsqj.mapper")
public class JsqjApplication {
    public static void main(String[] args) {
        SpringApplication.run(JsqjApplication.class, args);
    }
}

首先可以创建一个MyBaits Plus生成器用来将建立的MySQL读取进入服务,如下代码所示。

package com.jsqj.config;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Scanner;

/**
 * 自动生成mybatisplus的相关代码
 */
public class GeneratorCodeConfig {

    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }

    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("stiller");
        gc.setOpen(false);
        //实体属性 Swagger2 注解
        gc.setSwagger2(false);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://127.0.0.1:3306/qjh_simple_index?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&useSSL=false&allowPublicKeyRetrieval=true");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
//        pc.setModuleName(scanner("模块名"));
        pc.setParent("com.jsqj");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setServiceImpl("service.impl");
        mpg.setPackageInfo(pc);

        // 自定义配置
//        InjectionConfig cfg = new InjectionConfig() {
//            @Override
//            public void initMap() {
//                // to do nothing
//            }
//        };

        // 如果模板引擎是 freemarker
//        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity
        // String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
//        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
//        focList.add(new FileOutConfig(templatePath) {
//            @Override
//            public String outputFile(TableInfo tableInfo) {
//                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
//                return projectPath + "/src/main/resources/mapper/" + pc.getModuleName()
//                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
//            }
//        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录");
                return false;
            }
        });
        */
//        cfg.setFileOutConfigList(focList);
//        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setSuperEntityClass("com.baomidou.mybatisplus.extension.activerecord.Model");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);

        strategy.setEntityLombokModel(true);
        // 公共父类
//        strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
        // 写于父类中的公共字段
//        strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }
}

MyBaits提供了单表的类ORM操作,同时也支持MyBaits的SQL创建和使用,可以在静态资源mapper文件夹中建立一个XML文件,如下代码所示。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jsqj.mapper.SysAdminUserMapper">
    <select id="findSysUser" resultType="com.jsqj.entity.SysAdminUser">
        select * from sys_admin_user WHERE username=#{username} and password=#{password}
    </select>
</mapper>
  1. 在XML指定了namespace为代码包中的mapper文件(有的也会命名为DAO)

  2. 在对应的mapper中编写传递的参数,如下代码所示

java @Mapper public interface SysAdminUserMapper extends BaseMapper<SysAdminUser> { public SysAdminUser findSysUser(@Param("username") String username, @Param("password") String password); }

  1. 在对应的service中设置此方法,如下代码所示

java public interface ISysAdminUserService extends IService<SysAdminUser> { public SysAdminUser findSysUser(String username,String password); }

  1. 在接口实现中实现此接口,return结果。
@Service
public class SysAdminUserServiceImpl extends ServiceImpl<SysAdminUserMapper, SysAdminUser> implements ISysAdminUserService {

    @Autowired
    private SysAdminUserMapper sysAdminUserMapper;

    @Override
    public SysAdminUser findSysUser(String username, String password) {
        return sysAdminUserMapper.findSysUser(username, password);
    }
}
  1. 这样就可以在controller中使用项目代码了。
    private ISysAdminUserService sysAdminUserService;

    @PostMapping("/check-user")
    public xxx checkUser(String username,String password){
//        判断用户是否存在登录成功
        SysAdminUser user = sysAdminUserService.findSysUser(username, password);
    }

链接