javaweb各种框架组合案例(五):springboot+mybatis+generator
阅读原文时间:2020年09月21日阅读:1

一、介绍

1.springboot是spring项目的总结+整合

  当我们搭smm,ssh,ssjdbc等组合框架时,各种配置不胜其烦,不仅是配置问题,在添加各种依赖时也是让人头疼,关键有些jar包之间还会出现冲突,让你的项目出现难以解决的问题。基于这种情况,springboot横空出世,在考虑到Struts控制层框架有漏洞,springboot放弃(大多数企业同样如此)了Struts,转而代之是springMVC,不过,springboot是自动集成springMVC的,不需要任何配置,不需要任何依赖,直接使用各种控制层注解。springboot是springcloud的基础,是开启微服务时代的钥匙。

二、新建springboot工程

1. 使用idea2019新建project,选择spring Initializr,next

2. 填写坐标信息,next

3. web选择Spring Web Starter,SQL选择MyBatis Framework、MySQL Driver,next

4. 填写项目名已经存放位置,finish

三、使用mybatis generator构建项目

1. 数据库

  创建数据库

create database ssdj;

  创建phone表 

CREATE TABLE `phone` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`brand` varchar(255) DEFAULT NULL,
`user_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_8t3jhwmmlxpq3qcwcy1a3alts` (`user_id`),
CONSTRAINT `FK_8t3jhwmmlxpq3qcwcy1a3alts` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

  创建user表

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`password` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;

  插入数据

user                    phone

  

   实现了一个用户拥有多部手机的业务

2. pom.xml

  在创建springboot工程创建时勾选的Dependencies会在pom中添加,所以pom.xml基本不需要自己添加依赖

  为pom.xml添加generator插件,其它不用动


org.mybatis.generator mybatis-generator-maven-plugin ${basedir}/src/main/resources/generatorConfig.xml true true

  springboot方便之处就是“自以为是”的为工程添加默认中间件,并且不需要自己添加依赖,不需要写额外配置,如数据库连接池用的是HirikaCP,其它的中间件用的都是市场上评价最好最稳定的

3. application.properties

  在src/main/resource下找到application.properties文件

   因为properties文件可读性差,将其更名为application.yml,并在其中添加

spring:
profiles:
active: dev

4. application-dev.yml

  在resource下创建application-dev.yml文件,并在其中添加

server:
port: 8080

spring:
datasource:
username: root
password: root
url: jdbc:mysql://localhost:3306/ssdj?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver

mybatis:
mapper-locations: classpath:mapper/*Mapper.xml
type-aliases-package: club.xcreeper.ssm_generator_restful.entity

#showSql
logging:
level:
club:
xcreeper:
ssm_generator_restful:
dao:
debug

5. generatorConfig.xml

  在resource目录下创建generatorConfig.xml文件,在其中添加

6\. logback-spring.xml   在resource目录下创建logback-spring.xml文件,在其中添加


<!--<include resource="org/springframework/boot/logging/logback/base.xml" />-->

<contextName>logback</contextName>  
<!-- name的值是变量的名称,value的值时变量定义的值。通过定义的值会被插入到logger上下文中。定义变量后,可以使“${}”来使用变量。 -->  
<property name="log.path" value="D:/nmyslog/nmys" />

<!-- 彩色日志 -->  
<!-- 彩色日志依赖的渲染类 -->  
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />  
<conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />  
<conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />  
<!-- 彩色日志格式 -->  
<property name="CONSOLE\_LOG\_PATTERN" value="${CONSOLE\_LOG\_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG\_LEVEL\_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(\[%15.15t\]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG\_EXCEPTION\_CONVERSION\_WORD:-%wEx}}"/>

<!--输出到控制台-->  
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">  
    <!--此日志appender是为开发使用,只配置最底级别,控制台输出的日志级别是大于或等于此级别的日志信息-->  
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">  
        <level>info</level>  
    </filter>  
    <encoder>  
        <Pattern>${CONSOLE\_LOG\_PATTERN}</Pattern>  
        <!-- 设置字符集 -->  
        <charset>UTF-8</charset>  
    </encoder>  
</appender>

<!--输出到文件-->

<!-- 时间滚动输出 level为 DEBUG 日志 -->  
<appender name="DEBUG\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <!-- 正在记录的日志文件的路径及文件名 -->  
    <file>${log.path}/log\_debug.log</file>  
    <!--日志文件输出格式-->  
    <encoder>  
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} \[%thread\] %-5level %logger{50} - %msg%n</pattern>  
        <charset>UTF-8</charset> <!-- 设置字符集 -->  
    </encoder>  
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->  
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
        <!-- 日志归档 -->  
        <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>  
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">  
            <maxFileSize>100MB</maxFileSize>  
        </timeBasedFileNamingAndTriggeringPolicy>  
        <!--日志文件保留天数-->  
        <maxHistory>15</maxHistory>  
    </rollingPolicy>  
    <!-- 此日志文件只记录debug级别的 -->  
    <filter class="ch.qos.logback.classic.filter.LevelFilter">  
        <level>debug</level>  
        <onMatch>ACCEPT</onMatch>  
        <onMismatch>DENY</onMismatch>  
    </filter>  
</appender>

<!-- 时间滚动输出 level为 INFO 日志 -->  
<appender name="INFO\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <!-- 正在记录的日志文件的路径及文件名 -->  
    <file>${log.path}/log\_info.log</file>  
    <!--日志文件输出格式-->  
    <encoder>  
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} \[%thread\] %-5level %logger{50} - %msg%n</pattern>  
        <charset>UTF-8</charset>  
    </encoder>  
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->  
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
        <!-- 每天日志归档路径以及格式 -->  
        <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>  
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">  
            <maxFileSize>100MB</maxFileSize>  
        </timeBasedFileNamingAndTriggeringPolicy>  
        <!--日志文件保留天数-->  
        <maxHistory>15</maxHistory>  
    </rollingPolicy>  
    <!-- 此日志文件只记录info级别的 -->  
    <filter class="ch.qos.logback.classic.filter.LevelFilter">  
        <level>info</level>  
        <onMatch>ACCEPT</onMatch>  
        <onMismatch>DENY</onMismatch>  
    </filter>  
</appender>

<!-- 时间滚动输出 level为 WARN 日志 -->  
<appender name="WARN\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <!-- 正在记录的日志文件的路径及文件名 -->  
    <file>${log.path}/log\_warn.log</file>  
    <!--日志文件输出格式-->  
    <encoder>  
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} \[%thread\] %-5level %logger{50} - %msg%n</pattern>  
        <charset>UTF-8</charset> <!-- 此处设置字符集 -->  
    </encoder>  
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->  
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
        <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>  
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">  
            <maxFileSize>100MB</maxFileSize>  
        </timeBasedFileNamingAndTriggeringPolicy>  
        <!--日志文件保留天数-->  
        <maxHistory>15</maxHistory>  
    </rollingPolicy>  
    <!-- 此日志文件只记录warn级别的 -->  
    <filter class="ch.qos.logback.classic.filter.LevelFilter">  
        <level>warn</level>  
        <onMatch>ACCEPT</onMatch>  
        <onMismatch>DENY</onMismatch>  
    </filter>  
</appender>

<!-- 时间滚动输出 level为 ERROR 日志 -->  
<appender name="ERROR\_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">  
    <!-- 正在记录的日志文件的路径及文件名 -->  
    <file>${log.path}/log\_error.log</file>  
    <!--日志文件输出格式-->  
    <encoder>  
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} \[%thread\] %-5level %logger{50} - %msg%n</pattern>  
        <charset>UTF-8</charset> <!-- 此处设置字符集 -->  
    </encoder>  
    <!-- 日志记录器的滚动策略,按日期,按大小记录 -->  
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">  
        <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>  
        <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">  
            <maxFileSize>100MB</maxFileSize>  
        </timeBasedFileNamingAndTriggeringPolicy>  
        <!--日志文件保留天数-->  
        <maxHistory>15</maxHistory>  
    </rollingPolicy>  
    <!-- 此日志文件只记录ERROR级别的 -->  
    <filter class="ch.qos.logback.classic.filter.LevelFilter">  
        <level>ERROR</level>  
        <onMatch>ACCEPT</onMatch>  
        <onMismatch>DENY</onMismatch>  
    </filter>  
</appender>

<!--  
    <logger>用来设置某一个包或者具体的某一个类的日志打印级别、  
    以及指定<appender>。<logger>仅有一个name属性,  
    一个可选的level和一个可选的addtivity属性。  
    name:用来指定受此logger约束的某一个包或者具体的某一个类。  
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,  
          还有一个特俗值INHERITED或者同义词NULL,代表强制执行上级的级别。  
          如果未设置此属性,那么当前logger将会继承上级的级别。  
    addtivity:是否向上级logger传递打印信息。默认是true。  
-->  
<!--<logger name="org.springframework.web" level="info"/>-->  
<!--<logger name="org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor" level="INFO"/>-->  
<!--  
    使用mybatis的时候,sql语句是debug下才会打印,而这里我们只配置了info,所以想要查看sql语句的话,有以下两种操作:  
    第一种把<root level="info">改成<root level="DEBUG">这样就会打印sql,不过这样日志那边会出现很多其他消息  
    第二种就是单独给dao下目录配置debug模式,代码如下,这样配置sql语句会打印,其他还是正常info级别:  
 -->

<!--  
    root节点是必选节点,用来指定最基础的日志输出级别,只有一个level属性  
    level:用来设置打印级别,大小写无关:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,  
    不能设置为INHERITED或者同义词NULL。默认是DEBUG  
    可以包含零个或多个元素,标识这个appender将会添加到这个logger。  
-->

<!--开发环境:打印控制台-->  
<springProfile name="dev">  
    <logger name="com.xiaog.music4j.dao" level="debug"/>  
</springProfile>

<root level="info">  
    <appender-ref ref="CONSOLE" />  
    <appender-ref ref="DEBUG\_FILE" />  
    <appender-ref ref="INFO\_FILE" />  
    <appender-ref ref="WARN\_FILE" />  
    <appender-ref ref="ERROR\_FILE" />  
</root>

<!--生产环境:输出到文件-->  
<!--<springProfile name="pro">-->  
<!--<root level="info">-->  
<!--<appender-ref ref="CONSOLE" />-->  
<!--<appender-ref ref="DEBUG\_FILE" />-->  
<!--<appender-ref ref="INFO\_FILE" />-->  
<!--<appender-ref ref="ERROR\_FILE" />-->  
<!--<appender-ref ref="WARN\_FILE" />-->  
<!--</root>-->  
<!--</springProfile>-->

7. 运行generatorConfig.xml文件,自动生成代码

  在idea工具的顶部 Run - Edit Configurations

  

  在其左上角“+”号里添加Maven

  在Command line中填写 mybatis-generator:generate -e,ok

  

  在idea顶部 Run - Run 'xxx [mybatis-generator:generate -e]'

  

  ok,再去查看代码是否生成

  若运行generatorConfig.xml报错,不用惊慌,是你直接复制generatorConfig.xml时出现的空格,只需要将文件所有空格删除,变成一行,

再重新格式化就好了。

8. 设置实体关系

  因为一个用户拥有多部手机,所以在User实体类中加入private List phones; 和 getter、setter

   并且去掉Phone实体类中的user_id属性和其getter、setter

    在UserMapper.xml文件中改造ResultMap映射关系

  并且改造selectByPrimaryKey查询语句

9. 再编写service层和controller层即可,可通过postman测试接口

(1)service及其实现

package club.xcreeper.ssm_generator_restful.service;

import club.xcreeper.ssm_generator_restful.entity.User;

public interface UserService { User getUser(int id); }

package club.xcreeper.ssm_generator_restful.service.impl;

import club.xcreeper.ssm_generator_restful.dao.UserMapper;

import club.xcreeper.ssm_generator_restful.entity.User;

import club.xcreeper.ssm_generator_restful___.service.UserService;_

___import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

@Autowired
private UserMapper userMapper;

@Override
public User getUser(int id) {
  return userMapper.selectByPrimaryKey(id);
}
}_

(2) controller

  使用Restful api 风格

package club.xcreeper.ssm_generator_restful.controller;

import club.xcreeper.ssm_generator_restful.entity.User;
import club.xcreeper.ssm_generator_restful.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/user")
public class UserController {

@Autowired  
private UserService userService;

@GetMapping(value = "/getOne/{id}")  
public User getUser(@PathVariable int id){  
    return userService.getUser(id);  
}

}

10. 通过postman进行接口测试