springboot + mybatis + gradle项目构建过程

Posted lzj123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot + mybatis + gradle项目构建过程相关的知识,希望对你有一定的参考价值。

1.从Spring boot官网根据需求下载脚手架或者到GitHub上去搜索对应的脚手架项目,D_iao ^0^

• 文件目录如下(此处generatorConfig.xml 和 log4j2.xml文件请忽略,后续会讲解)


 2.使用Mybatis代码自动构建插件生成代码

•  gradle 相关配置

// Mybatis 代码自动生成所引入的包
compile group: \'org.mybatis.generator\', name: \'mybatis-generator-core\', version: \'1.3.3\'

// MyBatis代码自动生成插件工具
apply plugin: "com.arenagod.gradle.MybatisGenerator"

configurations {
    mybatisGenerator
}

mybatisGenerator {
    verbose = true
    // 配置文件路径
    configFile = \'src/main/resources/generatorConfig.xml\'
}

•  generatorConfig.xml配置详解

<?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>

    <!--数据库驱动包路径 -->
    <classPathEntry
            <!--此驱动包路径可在项目的包库中找到,复制过来即可-->
            location="C:\\Users\\pc\\.gradle\\caches\\modules-2\\files-2.1\\mysql\\mysql-connector-java\\5.1.38\\dbbd7cd309ce167ec8367de4e41c63c2c8593cc5\\mysql-connector-java-5.1.38.jar"/>

    <context id="mysql" targetRuntime="MyBatis3">
        <!--关闭注释 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--数据库连接信息 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/xxx" userId="root"
                        password="">
        </jdbcConnection>

        <!--生成的model 包路径 ,其中rootClass为model的基类,配置之后他会自动继承该类作为基类,trimStrings会为model字串去空格-->
        <javaModelGenerator targetPackage="com.springboot.mybatis.demo.model"
                            targetProject="D:/self-code/spring-boot-mybatis/spring-boot-mybatis/src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
            <property name="rootClass" value="com.springboot.mybatis.demo.model.common.BaseModel"/>
        </javaModelGenerator>

        <!--生成mapper xml文件路径 -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="D:/self-code/spring-boot-mybatis/spring-boot-mybatis/src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成的Mapper接口的路径 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="com.springboot.mybatis.demo.mapper" targetProject="D:/self-code/spring-boot-mybatis/spring-boot-mybatis/src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 对应的表 这个是生成Mapper xml文件的基础,enableCountByExample如果为true则会在xml文件中生成样例,过于累赘所以不要-->
        <table tableName="tb_user" domainObjectName="User"
               enableCountByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               enableUpdateByExample="false"></table>
    </context>


</generatorConfiguration>

以上配置中注意targetProject路径请填写绝对路径,避免错误,其中targetPackage是类所处的包路径(确保包是存在的,否则无法生成),也就相当于

•  代码生成

配置完成之后首先得在数据库中新建对应的表,然后确保数据库能正常访问,最后在终端执行gradle mbGenerator或者点击如下任务

成功之后它会生成model、mapper接口以及xml文件

 


 3.集成日志

• gradle 相关配置

compile group: \'org.springframework.boot\', name: \'spring-boot-starter-log4j2\', version: \'1.4.0.RELEASE\'

// 排除冲突
configurations {
    mybatisGenerator
    compile.exclude module: \'spring-boot-starter-logging\'
}

当没有引入spring-boot-starter-log4j2包时会报错:java.lang.IllegalStateException: Logback configuration error detected Logback 配置错误声明

原因参考链接;https://blog.csdn.net/blueheart20/article/details/78111350?locationNum=5&fps=1

解决方案:排除依赖 spring-boot-starter-logging

what???

排除依赖之后使用的时候又报错:Failed to load class "org.slf4j.impl.StaticLoggerBinder" 加载slf4j.impl.StaticLoggerBinder类失败

原因参考链接:https://blog.csdn.net/lwj_199011/article/details/51853110

解决方案:添加依赖 spring-boot-starter-log4j2 此包所依赖的包如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starters</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>
    <artifactId>spring-boot-starter-log4j2</artifactId>
    <name>Spring Boot Log4j 2 Starter</name>
    <description>Starter for using Log4j2 for logging. An alternative to
        spring-boot-starter-logging</description>
    <url>http://projects.spring.io/spring-boot/</url>
    <organization>
        <name>Pivotal Software, Inc.</name>
        <url>http://www.spring.io</url>
    </organization>
    <properties>
        <main.basedir>${basedir}/../..</main.basedir>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
        </dependency>
    </dependencies>
</project>

它依赖了 log4j-slf4j-impl ,使用的是log4j2日志框架。

这里涉及到log4j、logback、log4j2以及slf4j相关概念,那么它们是啥关系呢?unbelievable...相关知识如下:

slf4j、log4j、logback、log4j2 
日志接口(slf4j) slf4j是对所有日志框架制定的一种规范、标准、接口,并不是一个框架的具体的实现,因为接口并不能独立使用,需要和具体的日志框架实现配合使用(如log4j、logback)
日志实现(log4j、logback、log4j2) log4j是apache实现的一个开源日志组件 logback同样是由log4j的作者设计完成的,拥有更好的特性,用来取代log4j的一个日志框架,是slf4j的原生实现 Log4j2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活,官网地址: http://logging.apache.org/log4j/2.x/manual/configuration.html 为什么需要日志接口,直接使用具体的实现不就行了吗? 接口用于定制规范,可以有多个实现,使用时是面向接口的(导入的包都是slf4j的包而不是具体某个日志框架中的包),即直接和接口交互,不直接使用实现,所以可以任意的更换实现而不用更改代码中的日志相关代码。 比如:slf4j定义了一套日志接口,项目中使用的日志框架是logback,开发中调用的所有接口都是slf4j的,不直接使用logback,调用是 自己的工程调用slf4j的接口,slf4j的接口去调用logback的实现,可以看到整个过程应用程序并没有直接使用logback,当项目需要更换更加优秀的日志框架时(如log4j2)只需要引入Log4j2的jar和Log4j2对应的配置文件即可,完全不用更改Java代码中的日志相关的代码logger.info(“xxx”),也不用修改日志相关的类的导入的包(import org.slf4j.Logger; import org.slf4j.LoggerFactory;)
使用日志接口便于更换为其他日志框架,适配器作用 log4j、logback、log4j2都是一种日志具体实现框架,所以既可以单独使用也可以结合slf4j一起搭配使用)

• 到此我们使用的是Log4j2日志框架,接下来是配置log4j(可以使用properties、xml以及yml三种方式配置,这里使用xml形式;有关log4j详细配置讲解参考链接:https://blog.csdn.net/menghuanzhiming/article/details/77531977),具体配置详解如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
 <!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<Configuration status="WARN">

    <!--定义一些属性-->
    <Properties>
        <Property name="PID">????</Property>
        <Property name="LOG_PATTERN">
            [%d{yyyy-MM-dd HH:mm:ss.SSS}] - ${sys:PID} --- %c{1}: %m%n
        </Property>
    </Properties>

    <!--输出源,用于定义日志输出的地方-->
    <Appenders>

        <!--输出到控制台-->
        <Console name="Console" target="SYSTEM_OUT" follow="true">
            <PatternLayout
                    pattern="${LOG_PATTERN}">
            </PatternLayout>
        </Console>

        <!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用-->
        <!--append为TRUE表示消息增加到指定文件中,false表示消息覆盖指定的文件内容,默认值是true-->
        <!--<File name="File" fileName="logs/log.log" append="false">-->
            <!--<PatternLayout>-->
                <!--<pattern>[%-5p] %d %c - %m%n</pattern>-->
            <!--</PatternLayout>-->
        <!--</File>-->

        <!--这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档 -->
        <RollingFile name="RollingAllFile" fileName="logs/all/all.log"
                     filePattern="logs/all/$${date:yyyy-MM}/all-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout
                    pattern="${LOG_PATTERN}" />
            <Policies>
                <!--以下两个属性结合filePattern使用,完成周期性的log文件封存工作-->
                <!--TimeBasedTriggeringPolicy 基于时间的触发策略,以下是它的两个参数:
                    1.interval,integer型,指定两次封存动作之间的时间间隔。单位:以日志的命名精度来确定单位,比如yyyy-MM-dd-HH 单位为小时,yyyy-MM-dd-HH-mm 单位为分钟
                    2.modulate,boolean型,说明是否对封存时间进行调制。若modulate=true,则封存时间将以0点为边界进行偏移计算。比如,modulate=true,interval=4hours,那么假设上次封存日志的时间为03:00,则下次封存日志的时间为04:00,之后的封存时间依次为08:00,12:00,16:00-->
                <!--<TimeBasedTriggeringPolicy/>-->
                <!--SizeBasedTriggeringPolicy 基于日志文件大小的触发策略,以下配置解释为:
                    当单个文件达到20M后,会自动将以前的内容,先创建类似 2014-09(年-月)的目录,然后按 "xxx-年-月-日-序号"命名,打成压缩包-->
                <SizeBasedTriggeringPolicy size="200 MB"/>
            </Policies>
        </RollingFile>

        <!-- 
添加过滤器ThresholdFilter,可以有选择的输出某个级别及以上的类别 onMatch="ACCEPT" onMismatch="DENY" 意思是匹配就接受,否则直接拒绝。
如果有组合过滤的话会用到NEUTRA·L,表示中立,eg:
<Filters>
    <ThresholdFilter level="error" onMatch="DENY" onMismatch="NEUTRAL"/>
    <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
      </Filters>
上面的意思就是:如果匹配到error及以上的日志级别就拒接,没有匹配到的则保持中立即不拒绝也不接受,等待下一个过滤器过滤;然后第二个过滤器匹配到warn及以上的就接受,未匹配到的就拒绝,由于第一个拒绝了error及以上的所以这个组合过滤的结果就是只记录warn日志
--> <RollingFile name="RollingErrorFile" fileName="logs/error/error.log" filePattern="logs/error/$${date:yyyy-MM}/%d{yyyy-MM-dd}-%i.log.gz"> <ThresholdFilter level="ERROR"/> <PatternLayout pattern="${LOG_PATTERN}" /> <Policies> <!--<TimeBasedTriggeringPolicy/>--> <SizeBasedTriggeringPolicy size="200 MB"/> </Policies> </RollingFile> <RollingFile name="RollingWarnFile" fileName="logs/warn/warn.log" filePattern="logs/warn/$${date:yyyy-MM}/%d{yyyy-MM-dd}-%i.log.gz"> <Filters> <ThresholdFilter level="WARN"/> <ThresholdFilter level="ERROR" onMatch="DENY" onMismatch="NEUTRAL"/> </Filters> <PatternLayout pattern="${LOG_PATTERN}" /> <Policies> <!--<TimeBasedTriggeringPolicy/>--> <SizeBasedTriggeringPolicy size="200 MB"/> </Policies> </RollingFile> </Appenders> <!--然后定义Loggers,只有定义了Logger并引入的Appender,Appender才会生效--> <Loggers> <Logger name="org.hibernate.validator.internal.util.Version" level="WARN"/> <Logger name="org.apache.coyote.http11.Http11NioProtocol" level="WARN"/> <Logger name="org.apache.tomcat.util.net.NioselectorPool" level="WARN"/> <Logger name="org.apache.catalina.startup.DigesterFactory" level="ERROR"/> <Logger name="org.springframework" level="INFO" /> <Logger name="com.springboot.mybatis.demo" level="DEBUG"/>
    <Logger  name="validateEventLog" level="info" additivity="false">
    <AppenderRef ref="RollingFileAbandonEvent"/>
    </Logger>

    <!--
这里的name是在声明 log 对象时传进去的名字,eg: private final Logger LOG = LogManager.getLogger("logName");
一般我们会使用类的全限定名作为log的名字,eg: private final Logger LOG = LogManager.getLogger(this.getClass());
-->
<!--以上的logger会继承Root,也就是说如果在Logger里头没有配置appender,日志就会默认输出到Root下定义的符合条件的Appender中,若不想让它继承可以设置 additivity="false" 并可以在Logger中设置 <AppenderRef ref="Console"/> 指定输出到Console--> <Root level="INFO"> <AppenderRef ref="Console" /> <AppenderRef ref="RollingAllFile"/> <AppenderRef ref="RollingErrorFile"/> <AppenderRef ref="RollingWarnFile"/> </Root> </Loggers> </Configuration>

yml配置案例:

Configuration:  
  status: info  
  Properties: # 定义全局变量  
    Property: # 缺省配置(用于开发环境)。其他环境需要在VM参数中指定,如下:  
      - name: log.path  
        value: ./logs/
      - name: project.name  
        value: xx
      - name: info.file.name
        value: ${log.path}/${project.name}.info.log
      - name: error.file.name
        value: ${log.path}/${project.name}.error.log
      - name: kafka.sync.file.name
        value: ${log.path}/${project.name}.kafka.sync.log
  Appenders:  
    Console:  #输出到控制台  
      name: POSEIDON  
      target: SYSTEM_OUT  
      ThresholdFilter:  
        level: info # “sys:”表示:如果VM参数中没指定这个变量值,则使用本文件中定义的缺省全局变量值  
        onMatch: ACCEPT  
        onMismatch: DENY  
      PatternLayout:  
        pattern: "%d{MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"  
    RollingFile: # 输出到文件,超过128MB归档  
      - name: infolog
        ThresholdFilter: 
          level: info # “sys:”表示:如果VM参数中没指定这个变量值,则使用本文件中定义的缺省全局变量值
          onMatch: ACCEPT 
          onMismatch: DENY   
        ignoreExceptions: false  
        fileName: ${info.file.name}  
        PatternLayout: 
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n"
        filePattern: ${log.path}/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.error.log.gz
        PatternLayout:  
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n" 
        Policies:  
          SizeBasedTriggeringPolicy:  
            size: "128 MB"  
        DefaultRolloverStrategy:  
          max: 1000
      - name: ROLLINGFILEERROR 
        ThresholdFilter: 
          level: error
          onMatch: ACCEPT
          onMismatch: DENY
        fileName: ${error.file.name}
        PatternLayout: 
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n"
        filePattern: ${log.path}/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.error.log.gz
        PatternLayout:
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n"
        Policies:
          SizeBasedTriggeringPolicy:
            size: "128 MB"
        DefaultRolloverStrategy:
          max: 1000
      - name: kafkaSyncLog
        ThresholdFilter:
          level: info
          onMatch: ACCEPT
          onMismatch: DENY
        fileName: ${kafka.sync.file.name}
        PatternLayout:
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n"
        filePattern: ${log.path}/$${date:yyyy-MM}/${project.name}-%d{yyyy-MM-dd}-%i.kafka.sync.log.gz
        PatternLayout:
          pattern: "%d{yyyy-MM-dd HH:mm:ss,SSS}:%4p %t (%F:%L) - %m%n"
     // 以下是清理策略:每个log文件达到128M时则会打成一个zip包,最大允许1000个zip包,超过的会删除掉老的zip包 Policies: SizeBasedTriggeringPolicy: size: "128 MB" DefaultRolloverStrategy: max: 1000 Loggers: Root: // 所有文件的对应级别的日志都会往Root里面配置的对应级别的日志文件里打 level: info AppenderRef: - ref: POSEIDON - ref: infolog - ref: ROLLINGFILEERROR Logger: - name: com.xx.log.common level: error - name: com.xx.xx.xx.xx.xx.kafka // 这里指定某个类的日志输出到自定义的logger文件里,注意:additivity = false为此类的日志不会输出到Root里面的logger文件里;kafkaSyncLog不加入到Root里是因为也不想让其他文件的日志打印到kafkaSyncLog日志文件里 additivity: false level: info AppenderRef: - ref: kafkaSyncLog

 到此我们就算是把日志集成进去了,可以在终端看到各种log,very exciting!!! 

log4j还可以发送邮件

添加依赖:

compile group: \'org.springframework.boot\', name: \'spring-boot-starter-mail\', version: \'2.0.0.RELEASE\'

修改log4j配置:

在appender中添加如下:
 <!-- subject: 邮件主题  to: 接收人,多个以逗号隔开  from: 发送人  replyTo: 发送账号 smtp: QQ查看链接https://service.mail.qq.com/cgi-bin/help?subtype=1&no=167&id=28 smtpDebug: 开启详细日志 smtpPassword: 授权码,参看https://service.mail.qq.com/cgi-bin/help?subtype=1&&id=28&&no=1001256 smtpUsername: 用户名-->
 <SMTP name="Mail" subject="Error Log" to="xxx.com" from="xxx@qq.com" replyTo="xxx@qq.com"
              smtpProtocol="smtp" smtpHost="smtp.qq.com" smtpPort="587" bufferSize="50" smtpDebug="false"
              smtpPassword="授权码" smtpUsername="xxx.com">
 </SMTP>

在root里添加上面的appender让其生效
<AppenderRef ref="Mail" level="error"/>

 搞定!

总结:Log4j其主要就是Appender和Logger两部分,前者负责指定日志输出位置,后者指定日志输入来源。

注:以上仅仅是个人经验总结,Log4j的功能还有很多很多,比如日志输出到ArangoDB、MySQL、Kafka等等,详细可查看官方文档,很详细!!!


 4.集成MybatisProvider

• Why ?

    有了它我们可以通过注解的方式结合动态SQL实现基本的增删改查操作,而不需要再在xml中写那么多重复繁琐的SQL了

• Come on ↓

  First: 定义一个Mapper接口并实现基本操作,如下:

package com.springboot.mybatis.demo.mapper.common;

import com.springboot.mybatis.demo.mapper.common.provider.AutoSqlProvider;
import com.springboot.mybatis.demo.mapper.common.provider.MethodProvider;
以上是关于springboot + mybatis + gradle项目构建过程的主要内容,如果未能解决你的问题,请参考以下文章

SpringBoot使用·下篇(SpringBoot集成MyBatis+日志打印+MyBatis-plus)

SpringBoot 整合其他框架 -- SpringBoot整合Mybatis

springboot.springboot用最简单的方式整合mybatis

yml的mybatis的sql查看;Mybatis+Springboot 控制台查看日志,Mybatis结合springboot打印日志

企业分布式微服务云SpringCloud SpringBoot mybatis (十三)Spring Boot整合MyBatis

SpringBoot.04.SpringBoot整合MyBatis