@TOC
一、我的项目背景
作为技术人员的你,你可能遇到频繁的小我的项目一直的在创立(包含生产或技术语言),根底性能代码类似度达到 90%,零碎的根底接口、流程、参数等几近类似。每次新建我的项目就算你在相熟,你也得花很大部分的工夫(从数据库层到服务层到应用层到根底配置,我置信你在这里起码要花差不多半天的工夫),不过你还是一直的创立相似我的项目、一直的增加数据库操作层、一直的服务接口和实现层,最初还要为内部提供 API 接口,其实当你我的项目做多了你就晓得你始终在干反复的工作,在吸食没有养分的垃圾实物。你把大量的工夫节约在根底我的项目框架搭建、根底代码的编写。
1、手动创立我的项目型问题
你花了很多的工夫仅仅是在做如下的工作:
- 创立 WEB 零碎后盾框架
你须要新建合乎本人的我的项目,增加 Spring 工具、数据库工具、JSon 解决、Redis 解决、日志解决等,每次须要依据本人的需要去增加反复的 maven 依赖;
- 数据库 MyBatis 接口实现及映射配置
咱们在后盾常常应用 MyBtis 或 JPA 去做数据拜访层,你须要编写对应的接口,还须要编写接口对应的 SQL 语句和映射关系,你须要对你设计的所有的 table 一一一字不差的编写以便能顺利调试通过 DAO 接口,甚至你要增加很多个通过任意字段的组合都能够查问的通用接口,甚是吃力、吃力还不肯定精确。
- 创立零碎的实体模型
要实现与数据库的数据面向对象交互,咱们必须提供与表绝对应的 PO 对象,也就是咱们零碎中必须用到的 entity,不同的零碎尽管对应的 model 不太一样,但也就是 model 的名称和字段不一样而已,不过雷同的是有一个名字、有 n 个不同名称的字段!为什么不能从数据中将表转换为实体,这样不就大大减少了代码量?
- 创立面向业务的服务接口
DAO 是面向数据库层的,然而业务个别是变动的,所以咱们个别零碎中咱们要抽离一层 service 接口进去面向零碎业务实现事务操作,所以为了个别状况下针对业务层咱们要实现业务接口层、业务接口实现层的所有代码,业务层在通过 DAO 层来实现数据库的 CURD 操作,其实你会发现这层的业务根底的逻辑简直与 DAO 层齐全类似(仅仅是个别的面向零碎业务的接口须要个性化减少)。
- 创立面向利用的管制层接口
为了能提供对外接口,在 MVC 模式中咱们还必须要提供对外的 Controller 层,也就是咱们所说的 API 层,咱们须要将对应的业务裸露给内部或第三方平台,要求标准内部申请参数、申请形式、申请接口地址等,所以不得已咱们还必须实现一层业务管制层代码,通过调用业务服务层代码实现零碎的业务性能。
- 创立系统配置
所以的利用启动都必须通过启动配置进行启动,能够包含开发环境配置、生产环境配置、测试环境配置等,其实这一类的配置也几近是雷同的,能够对立起来配置,个性化的配置才须要用户本人增加。
- 创立日志配置
日志是零碎必不可少的组件,咱们的零碎必须要配置对应的日志信息,包含保留目录、存储形式、日志级别等。不过这一部分基本上咱们能够约定,差异性的才须要用户去更新,所以这部分的工作也能够兼顾起来,应用代码生成。
- 工具集成配置
我的项目开发过程中咱们须要借助很多工具来保证系统的稳固运行,包含分布式日志、SQL 性能监控、跨域拜访、JSON 转换、文本转换、日期转换、加解密、文件操作、HTTP 调用等等等,不过你会发现没新建一个我的项目你都会急不可待的将你封装的、感觉很好用的工具通通都打包进去,因为你晓得这个工具是很罕用也基本上用的到,所以你每次都会拷贝它,我就想问,你每次这么做是不是感觉好累,导出查找地位、拷贝粘贴、批改包名!(当然,最好的办法不是拷贝进去二十封装层本人的一个 jar 包库到零碎中)。
2、我的项目复制型新建我的项目问题
如果你发现这个多货色都是可复制的,只须要作为模板,而后依照模板批改就能够新建成另一个我的项目,不过你会发现即便你拷贝成另外一个我的项目你也会面对如下问题:
- 删除太多不必要的货色
被复制的我的项目个别蕴含了大量的与该零碎业务相干的代码,所以你拿过来之后你须要删除所有与业务相干的代码;
- 接口实现大量改变
因为业务不同导致数据库设计不同所带来的问题就是基本上所有重要的代码都要删除或重构,包含零碎实体模型、数据 mapper 层、业务 service 层、service 实现层、管制层。你会发现你基本上还不如重建一个新我的项目还来得罗唆!
- 环境兼容性
开发环境中,不是你改一个名字就能够到处运行,因为很多时候你批改的并不彻底,改完之后始终到其余中央或环境发现是谬误、红点,不相熟的开发人员根本无法解决对应的红色问题。
既然以上两种计划有如此多的问题,既然代码工作重复性如此之大,为何你仍然执著于重建重减轻改?那倒不如将反复的工作集成到一个我的项目中,当前创立我的项目的时候只须要专一于写好本人的 SQL 脚本,而后通过 web 网页或 swagger 输出本人的我的项目信息一键生成本人的我的项目,零打碎敲,何乐而不为?这也是自己的初衷,也算是为公司为各位网友节俭大量的开发工夫和人力老本。
二、我的项目成绩
对技术人员来说,技术都不是问题,缺的就是想法,基本上没有实现不了的事,剩下的就是工夫的问题了,通过 2 - 3 天的开发,基本上成型,实现了主动生成 SpringBoot 后盾代码的初衷。
1、代码生成服务
我将实现了代码生成的服务代码成了安装包,如下所示:
启动后如下所示(确保运行机器装置 JDK 并且 80 端口未被占用且按装置了 mysql):
启动后近程机器监听的 80 端口,咱们间接通过浏览器拜访对应机器 ip 即可:
http://192.168.8.18 进入登录页面
通过用户名 admin,明码:123456 进入零碎即可(留神 session 在 30 分钟内过期从新登录)
2、我的项目创立
1、设计数据库
正如我说的,有了框架生成服务咱们只须要专一于本人的数据库设计即可,这里我的业务是在音视频这块的利用,我设计了 2 个表,数据库脚本如下所示:
-- ------------------------------------------------------
-- 创立并应用数据库
-- ------------------------------------------------------
set charset utf8;
create database if not exists mclz character set UTF8;
use mclz;
--
-- 客户端链接信息表
--
create table if not exists t_connection
(clientId bigint(20) NOT NULL, /* 客户端标识 */
ip varchar(16) default NULL, /* srs 拜访的地址 */
vhost varchar(64) default NULL, /* 虚拟主机 */
app varchar(64) default NULL, /* 利用名称 */
tcUrl varchar(256) default NULL, /* 拜访地址 */
pageUrl varchar(256) default NULL, /* 拜访页面 */
reserver1 varchar(128) default NULL, /* 保留字段 */
reserver2 varchar(128) default NULL, /* 保留字段 */
primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client connection information';
--
-- 视频公布信息表
--
create table if not exists t_publish
(clientId bigint(20) NOT NULL, /* 客户端标识 */
ip varchar(16) default NULL, /* srs 拜访的地址 */
vhost varchar(64) default NULL, /* 虚拟主机 */
app varchar(64) default NULL, /* 利用名称 */
tcUrl varchar(256) default NULL, /* 拜访地址 */
stream varchar(64) default NULL, /* 流名称 */
param varchar(128) default NULL, /* 携带参数 */
reserver1 varchar(128) default NULL, /* 保留字段 */
reserver2 varchar(128) default NULL, /* 保留字段 */
primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client publish stream';
--
-- 视频播放信息表
--
create table if not exists t_play
(clientId bigint(20) NOT NULL, /* 客户端标识 */
ip varchar(16) default NULL, /* srs 拜访的地址 */
vhost varchar(64) default NULL, /* 虚拟主机 */
app varchar(64) default NULL, /* 利用名称 */
stream varchar(64) default NULL, /* 流名称 */
param varchar(128) default NULL, /* 携带参数 */
reserver1 varchar(128) default NULL, /* 保留字段 */
reserver2 varchar(128) default NULL, /* 保留字段 */
primary key(clientId)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='client play stream';
我的业务中简略的就三个表,客户端连贯表、视频公布表、视频播放表,设计实现我的业务之后咱们就能够通过上传该脚本生成本人的 web 后盾零碎,该零碎包含了所有操作这 3 个表的 DAO 层、mybatis 的 XML 配置、service 层、service 实现层、controller 层以及以下动态网页。
2、创立我的项目
通过下面的步骤咱们登陆到框架生成零碎中,如下所示
这里的我的项目创立界面比拟简洁,我算是偷个懒,有空的时候在为大家优化一下界面。须要留神些的都曾经注明:
- 应用流程:设计数据库脚本 => 填写我的项目信息 => 上传数据库脚本 => 创立我的项目
- 后续开发中, 用户只须要关注数据库设计即可一键生成, 不须要节约大量工夫构建后盾零碎代码
- 系统生成的后盾应用的技术框架:SpringBoot+MyBtis+MySql 的三层 MVC 服务架构
- 零碎提供了如系统配置、日志配置、数据库配置、拦截器配置、转换器配置、Druid 配置等相干配置代码的生成
- 零碎提供了如管制层、服务接口层、服务实现层、数据拜访层、Mybatis 映射 XML 脚本等根底服务代码的生成
- 数据库表不反对联结主键类型的解决
我的 sql 脚本中创立的数据库名称为 ”mclz”, 所以我填入的我的项目信息如下所示:
我的项目包名:com.easystudy #该项作为所有包的根底包名利用到我的项目中
利用名称:hello #项目名称也是利用名称对应我的项目 Context 名
利用端口:6666 #我的项目对应的服务端口,http 拜访需明确指定
数据库地址:127.0.0.1 #部署机器必须装置 mysql 用户 sql 执行转化
数据库端口:3306 #服务临时仅反对 mysql 数据库操作
数据库名称:mclz #设计的 SQL 中创立并应用的数据库名称
数据库用户:root #运行脚本的 mysql 连贯用户名
数据库明码:root #运行脚本的 mysql 连贯明码
数据库脚本:通过抉择 sql 脚本文件上传后返回的 sql 长期文件名
点击“提交并创立我的项目”按钮新建我的项目,胜利后主动下载新建实现后的我的项目!
咱们间接下载我的项目并导入到 eclipse 中即可,最初间接运行
依据咱们创立的我的项目名为 hello, 我的项目监听端口 6666,咱们间接浏览器拜访:
http://localhost:6666/hello/
能够看到后盾框架零碎曾经生成,接口也曾经生成提供(前面一起看看),你只须要实现你的 UI 界面开发即可!
数据库性能监控页面:
http://localhost:6666/hello/druid
3、我的项目构造
生成好后盾我的项目之后,咱们一起来看看生成的我的项目的目录构造,如下所示:
能够看到生成的可运行零碎根本囊括了后盾 SpringBoot 后盾利用框架的所有的代码,包含:
- controller 层代码实现
局部代码如下:
package com.easystudy.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.PathVariable;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import com.easystudy.error.ErrorCode;
import com.easystudy.error.ReturnValue;
import com.easystudy.error.IOException;
import com.easystudy.model.Connection;
import com.easystudy.service.ConnectionService;
/**
* @文件名称: ConnectionController.java
* @性能形容: 管制层对外接口
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
@Slf4j
@RestController
@RequestMapping("/tconnection")
@Api(tags = "Connection 治理接口文档", value = "提供 Connection 治理相干接口")
public class ConnectionController {
@Autowired
private ConnectionService connectionService;
@PostMapping("/add")
@ApiOperation(value="增加 Connection 信息", notes="增加 Connection 信息")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "Connection", name = "connection", value = "Connection 信息", required = true) })
public ReturnValue<String> add(@RequestBody() Connection connection){
try {connectionService.add(connection);
return new ReturnValue<String>();} catch (IOException e) {log.error("增加信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "增加信息异样!");
}
@DeleteMapping("/delete/{clientId}")
@ApiOperation(value="删除 Connection 信息", notes="通过主键删除 Connection 信息")
@ApiImplicitParams({@ApiImplicitParam(paramType = "path", dataType = "Long", name = "clientId", value = "主键标识", required = true)})
public ReturnValue<String> delete(@PathVariable(name="clientId", required=true) Long clientId){
try {Connection temp = new Connection();
temp.setClientId(clientId);
connectionService.delete(temp);
return new ReturnValue<String>();} catch (IOException e) {log.error("删除信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "删除信息异样!");
}
@PutMapping("/update")
@ApiOperation(value="更新 Connection 信息", notes="更新 Connection 信息")
@ApiImplicitParams({@ApiImplicitParam(paramType = "body", dataType = "Connection", name = "connection", value = "Connection 信息", required = true) })
public ReturnValue<String> update(@RequestBody Connection connection) {
try {connectionService.update(connection);
return new ReturnValue<String>();} catch (IOException e) {log.error("更新信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<String>(ErrorCode.ERROR_SERVER_ERROR, "删除信息异样!");
}
@GetMapping("/findById/{clientId}")
@ApiOperation(value="通过主键查找 Connection 信息", notes="通过主键查找 Connection 信息")
@ApiImplicitParams({@ApiImplicitParam(paramType = "path", dataType = "Long", name = "clientId", value = "主键标识", required = true)})
public ReturnValue<Connection> findById(@PathVariable(name="clientId", required=true) Long clientId){
try {Connection connection = connectionService.findById(clientId);
if(null == connection) {return new ReturnValue<Connection>(ErrorCode.ERROR_NOT_FOUND);
}
return new ReturnValue<Connection>(connection);
} catch (IOException e) {log.error("查问信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<Connection>(ErrorCode.ERROR_SERVER_ERROR, "查问信息异样!");
}
@GetMapping("/findMaxByAttributes")
@ApiOperation(value="通过属性查找 Connection 总数", notes="通过属性查找 Connection 总数")
@ApiImplicitParams({@ApiImplicitParam(paramType = "query", dataType = "String", name = "ip", value = "ip", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "vhost", value = "vhost", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "app", value = "app", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "tcUrl", value = "tcUrl", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "pageUrl", value = "pageUrl", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver1", value = "reserver1", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver2", value = "reserver2", required = false)
})
public ReturnValue<Long> findMaxByAttributes(@RequestParam(name="ip",required=false) String ip,
@RequestParam(name="vhost",required=false) String vhost,
@RequestParam(name="app",required=false) String app,
@RequestParam(name="tcUrl",required=false) String tcUrl,
@RequestParam(name="pageUrl",required=false) String pageUrl,
@RequestParam(name="reserver1",required=false) String reserver1,
@RequestParam(name="reserver2",required=false) String reserver2
) {
try {Long count = connectionService.findMaxByAttributes(ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
return new ReturnValue<Long>(count);
} catch (IOException e) {log.error("查问信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<Long>(ErrorCode.ERROR_SERVER_ERROR, "查问信息异样!");
}
@GetMapping("/findByAttributes")
@ApiOperation(value="查找 Connection 信息列表", notes="查找 Connection 信息列表")
@ApiImplicitParams({@ApiImplicitParam(paramType = "query", dataType = "Long", name = "pageIndex", value = "页索引", required = true),
@ApiImplicitParam(paramType = "query", dataType = "Long", name = "pageSize", value = "页大小", required = true),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "orderProp", value = "排序字段", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "order", value = "排序形式(asc、desc)", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "ip", value = "ip", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "vhost", value = "vhost", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "app", value = "app", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "tcUrl", value = "tcUrl", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "pageUrl", value = "pageUrl", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver1", value = "reserver1", required = false),
@ApiImplicitParam(paramType = "query", dataType = "String", name = "reserver2", value = "reserver2", required = false)
})
public ReturnValue<List<Connection>> findByAttributes(@RequestParam(name="pageIndex",required=true) Long pageIndex,
@RequestParam(name="pageSize",required=true) Long pageSize,
@RequestParam(name="orderProp",required=false) String orderProp,
@RequestParam(name="order",required=false) String order,
@RequestParam(name="ip",required=false) String ip,
@RequestParam(name="vhost",required=false) String vhost,
@RequestParam(name="app",required=false) String app,
@RequestParam(name="tcUrl",required=false) String tcUrl,
@RequestParam(name="pageUrl",required=false) String pageUrl,
@RequestParam(name="reserver1",required=false) String reserver1,
@RequestParam(name="reserver2",required=false) String reserver2
) {
try {List<Connection> list = connectionService.findByAttributes(pageIndex,pageSize,orderProp,order,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
return new ReturnValue<List<Connection>>(list);
} catch (IOException e) {log.error("通过属性查问信息异样:{}", e.getMessage());
e.printStackTrace();}
return new ReturnValue<List<Connection>>(ErrorCode.ERROR_SERVER_ERROR, "通过属性查问信息异样!");
}
}
- service 接口层代码
局部代码实例:
package com.easystudy.service;
import com.easystudy.model.Connection;
import com.easystudy.error.IOException;
import java.util.List;
/**
* @文件名称: ConnectionService.java
* @性能形容: 业务服务层接口
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
public interface ConnectionService extends BaseService<Connection> {Long findMaxByAttributes(String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException;
List<Connection> findByAttributes(Long pageIndex,Long pageSize,String orderProp,String order,String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException;
}
- service 接口实现层
局部代码示例:
package com.easystudy.service.impl;
import com.easystudy.model.Connection;
import com.easystudy.error.IOException;
import java.util.List;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.easystudy.mapper.ConnectionMapper;
import com.easystudy.service.ConnectionService;
/**
* @文件名称: ConnectionServiceImpl.java
* @性能形容: 业务服务实现类
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
@Service
public class ConnectionServiceImpl implements ConnectionService {
@Autowired
private ConnectionMapper mapper;
@Override
@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class, isolation = Isolation.REPEATABLE_READ)
public void add(Connection o) throws IOException {mapper.insertSelective(o);
}
@Override
public void delete(Connection o) throws IOException {mapper.deleteByPrimaryKey(o.getClientId());
}
@Override
public void update(Connection o) throws IOException {mapper.updateByPrimaryKeySelective(o);
}
@Override
public Connection findById(Object id) throws IOException {return mapper.selectByPrimaryKey((Long)id);
}
@Override
public List<Connection> findByAttributes(Long pageIndex,Long pageSize,String orderProp,String order,String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException {return mapper.selectByAttributes(pageIndex,pageSize,orderProp,order,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
}
@Override
public Long findMaxByAttributes(String ip,String vhost,String app,String tcUrl,String pageUrl,String reserver1,String reserver2) throws IOException {return mapper.selectMaxByAttributes(ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2);
}
}
- DAO 接口层
局部实现代码:
package com.easystudy.mapper;
import com.easystudy.model.Connection;
import java.util.List;
import org.apache.ibatis.annotations.Param;
/**
* @文件名称: ConnectionMapper.java
* @性能形容: Dao 层数据操作接口
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
public interface ConnectionMapper {int deleteByPrimaryKey(Long clientId);
int insert(Connection connection);
int insertSelective(Connection connection);
Connection selectByPrimaryKey(Long clientId);
int updateByPrimaryKeySelective(Connection connection);
int updateByPrimaryKey(Connection connection);
Long selectMaxByAttributes(@Param("ip")String ip,@Param("vhost")String vhost,@Param("app")String app,@Param("tcUrl")String tcUrl,@Param("pageUrl")String pageUrl,@Param("reserver1")String reserver1,@Param("reserver2")String reserver2);
List<Connection> selectByAttributes(@Param("pageIndex")Long pageIndex,@Param("pageSize")Long pageSize,@Param("orderProp")String orderProp,@Param("order")String order,@Param("ip")String ip,@Param("vhost")String vhost,@Param("app")String app,@Param("tcUrl")String tcUrl,@Param("pageUrl")String pageUrl,@Param("reserver1")String reserver1,@Param("reserver2")String reserver2);
}
- mybatis 脚本层
局部代码示例:
<?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.easystudy.mapper.ConnectionMapper" >
<resultMap id="BaseResultMap" type="com.easystudy.model.Connection" >
<id column="clientId" property="clientId" jdbcType="BIGINT" />
<result column="ip" property="ip" jdbcType="VARCHAR" />
<result column="vhost" property="vhost" jdbcType="VARCHAR" />
<result column="app" property="app" jdbcType="VARCHAR" />
<result column="tcUrl" property="tcUrl" jdbcType="VARCHAR" />
<result column="pageUrl" property="pageUrl" jdbcType="VARCHAR" />
<result column="reserver1" property="reserver1" jdbcType="VARCHAR" />
<result column="reserver2" property="reserver2" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List" >
clientId,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2
</sql>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
select <include refid="Base_Column_List" />from t_connection where clientId = #{clientId,jdbcType=BIGINT}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
delete from t_connection where clientId = #{clientId,jdbcType=BIGINT}
</delete>
<select id="selectMaxByAttributes" resultType="long">
select count(clientId) from t_connection
<where>
<if test="ip != null and ip.length() > 0">
ip like CONCAT('%',#{ip},'%')
</if>
<if test="vhost != null and vhost.length() > 0">
and vhost like CONCAT('%',#{vhost},'%')
</if>
<if test="app != null and app.length() > 0">
and app like CONCAT('%',#{app},'%')
</if>
<if test="tcUrl != null and tcUrl.length() > 0">
and tcUrl like CONCAT('%',#{tcUrl},'%')
</if>
<if test="pageUrl != null and pageUrl.length() > 0">
and pageUrl like CONCAT('%',#{pageUrl},'%')
</if>
<if test="reserver1 != null and reserver1.length() > 0">
and reserver1 like CONCAT('%',#{reserver1},'%')
</if>
<if test="reserver2 != null and reserver2.length() > 0">
and reserver2 like CONCAT('%',#{reserver2},'%')
</if>
</where>
</select>
<select id="selectByAttributes" resultMap="BaseResultMap">
select <include refid="Base_Column_List" /> from t_connection
<where>
<if test="ip != null and ip.length() > 0">
ip like CONCAT('%',#{ip},'%')
</if>
<if test="vhost != null and vhost.length() > 0">
and vhost like CONCAT('%',#{vhost},'%')
</if>
<if test="app != null and app.length() > 0">
and app like CONCAT('%',#{app},'%')
</if>
<if test="tcUrl != null and tcUrl.length() > 0">
and tcUrl like CONCAT('%',#{tcUrl},'%')
</if>
<if test="pageUrl != null and pageUrl.length() > 0">
and pageUrl like CONCAT('%',#{pageUrl},'%')
</if>
<if test="reserver1 != null and reserver1.length() > 0">
and reserver1 like CONCAT('%',#{reserver1},'%')
</if>
<if test="reserver2 != null and reserver2.length() > 0">
and reserver2 like CONCAT('%',#{reserver2},'%')
</if>
</where>
<if test="orderProp != null and orderProp.length() > 0">
order by
<choose>
<when test="order != null and order !='desc'and order !='asc'">
${orderProp} asc
</when>
<when test="order == null">
${orderProp}
</when>
<otherwise>
${orderProp} ${order}
</otherwise>
</choose>
</if>
limit #{pageIndex}, #{pageSize}
</select>
<insert id="insert" parameterType="com.easystudy.model.Connection" >
insert into t_connection(clientId,ip,vhost,app,tcUrl,pageUrl,reserver1,reserver2) values(#{clientId,jdbcType=BIGINT},#{ip,jdbcType=VARCHAR},#{vhost,jdbcType=VARCHAR},#{app,jdbcType=VARCHAR},#{tcUrl,jdbcType=VARCHAR},#{pageUrl,jdbcType=VARCHAR},#{reserver1,jdbcType=VARCHAR},#{reserver2,jdbcType=VARCHAR})
</insert>
<insert id="insertSelective" parameterType="com.easystudy.model.Connection" >
insert into t_connection
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="clientId != null" >
clientId,
</if>
<if test="ip != null" >
ip,
</if>
<if test="vhost != null" >
vhost,
</if>
<if test="app != null" >
app,
</if>
<if test="tcUrl != null" >
tcUrl,
</if>
<if test="pageUrl != null" >
pageUrl,
</if>
<if test="reserver1 != null" >
reserver1,
</if>
<if test="reserver2 != null" >
reserver2,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="clientId != null" >
#{clientId,jdbcType=BIGINT},
</if>
<if test="ip != null" >
#{ip,jdbcType=VARCHAR},
</if>
<if test="vhost != null" >
#{vhost,jdbcType=VARCHAR},
</if>
<if test="app != null" >
#{app,jdbcType=VARCHAR},
</if>
<if test="tcUrl != null" >
#{tcUrl,jdbcType=VARCHAR},
</if>
<if test="pageUrl != null" >
#{pageUrl,jdbcType=VARCHAR},
</if>
<if test="reserver1 != null" >
#{reserver1,jdbcType=VARCHAR},
</if>
<if test="reserver2 != null" >
#{reserver2,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.easystudy.model.Connection" >
update t_connection
<set>
<if test="clientId != null" >
clientId = #{clientId,jdbcType=BIGINT},
</if>
<if test="ip != null" >
ip = #{ip,jdbcType=VARCHAR},
</if>
<if test="vhost != null" >
vhost = #{vhost,jdbcType=VARCHAR},
</if>
<if test="app != null" >
app = #{app,jdbcType=VARCHAR},
</if>
<if test="tcUrl != null" >
tcUrl = #{tcUrl,jdbcType=VARCHAR},
</if>
<if test="pageUrl != null" >
pageUrl = #{pageUrl,jdbcType=VARCHAR},
</if>
<if test="reserver1 != null" >
reserver1 = #{reserver1,jdbcType=VARCHAR},
</if>
<if test="reserver2 != null" >
reserver2 = #{reserver2,jdbcType=VARCHAR},
</if>
</set>
where clientId = #{clientId,jdbcType=BIGINT}
</update>
<update id="updateByPrimaryKey" parameterType="com.easystudy.model.Connection" >
update t_connection
clientId = #{clientId,jdbcType=BIGINT},
ip = #{ip,jdbcType=VARCHAR},
vhost = #{vhost,jdbcType=VARCHAR},
app = #{app,jdbcType=VARCHAR},
tcUrl = #{tcUrl,jdbcType=VARCHAR},
pageUrl = #{pageUrl,jdbcType=VARCHAR},
reserver1 = #{reserver1,jdbcType=VARCHAR},
reserver2 = #{reserver2,jdbcType=VARCHAR}
where clientId = #{clientId,jdbcType=BIGINT}
</update>
</mapper>
- 零碎 model 层
3 个表生成对应 3 个实体类 - 长久化对象(PO)
局部代码示例:
package com.easystudy.model;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
/**
* @文件名称: Connection.java
* @性能形容: 零碎实体类
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Connection {
private Long clientId;
private String ip;
private String vhost;
private String app;
private String tcUrl;
private String pageUrl;
private String reserver1;
private String reserver2;
}
- 系统配置
包含跨域拜访配置、Swagger 配置以及 MVC 配置类
局部示例代码:
package com.easystudy.conf;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
/**
* @文件名称: CORSConfig.java
* @性能形容: 跨域拜访配置
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
@Configuration
public class CORSConfig {
@Bean
public CorsFilter corsFilter() {final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
final CorsConfiguration config = new CorsConfiguration();
// 容许 cookies 跨域
config.setAllowCredentials(true);
// #容许向该服务器提交申请的 URI,* 示意全副容许,在 SpringMVC 中,如果设成 *,会主动转成以后申请头中的 Origin
config.addAllowedOrigin("*");
// #容许拜访的头信息,* 示意全副
config.addAllowedHeader("*");
// 预检申请的缓存工夫(秒),即在这个时间段里,对于雷同的跨域申请不会再预检了
config.setMaxAge(18000L);
// 容许提交申请的办法,* 示意全副容许
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
return new CorsFilter(source);
}
}
swagger 拜访地址:
http://localhost:6666/hello/druid/datasource.html
swagger 接口文档:
- 零碎应用错误码
后盾零碎错误码 VO 值对象类,提供 json 与实体的转化,反对携带错误码和谬误形容
局部示例代码:
package com.easystudy.error;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
/**
* @文件名称: ReturnValue.java
* @性能形容: 零碎返回值 dto 定义
* @版权信息: www.easystudy.com
* @技术交换: 961179337(QQ 群)
* @编写作者: lixx2048@163.com
* @联系方式: 941415509(QQ)
* @开发日期: 2020 年 10 月 19 日
* @历史版本: V1.0
* @备注信息:
*/
@JsonInclude(Include.NON_NULL)
public class ReturnValue<T> {
private Integer error = 0; // 谬误
private String description = ""; // 谬误形容
private T value; // 返回值【当 error 为 ERROR_NO_SUCCESS 才有可能返回值 - 判断值是否为空】// 胜利不带返回值
public ReturnValue(){this.error = ErrorCode.ERROR_SUCCESS.getError();
this.description = "胜利";
}
// 胜利带返回值
public ReturnValue(T value){if(null == value){this.error = ErrorCode.ERROR_NOT_FOUND.getError();
this.description = "没有找到你须要的资源";
} else {this.error = ErrorCode.ERROR_SUCCESS.getError();
this.description = "胜利";
this.value = value;
}
}
// 返回谬误
public ReturnValue(ErrorCode error){this.error = error.getError();
this.description = error.getDescription();}
// 返回谬误 -- 对谬误形容进行更改
public ReturnValue(ErrorCode error, String description){this.error = error.getError();
this.description = description;
}
// 返回谬误
public ReturnValue(Integer error){
this.error = error;
this.description = ErrorCode.getDescription(error);
}
public ReturnValue(Integer error, String description){
this.error = error;
this.description = description;
}
public Integer getError() {return error;}
public boolean success(){return error == ErrorCode.ERROR_SUCCESS.getError();
}
public void setError(Integer error) {this.error = error;}
public String getDescription() {return description;}
public void setDescription(String description) {this.description = description;}
public T getValue() {return value;}
public void setValue(T value) {this.value = value;}
}
- 系统配置
主动生成零碎配置文件
零碎配置文件如下所示:
server:
port: 6666
servlet:
context-path: /hello
#nio 的 web 服务配置
undertow:
#为工作者创立的 I / O 线程数
io-threads: 20
#工作者线程数量
worker-threads: 50
#拜访日志
accesslog:
enabled: false
spring:
application:
name: hello
#NOSQL
redis:
host: localhost
port: 6379
password:
timeout: 6000
pool:
max-active: 20 #连接池最大连接数(应用负值示意没有限度)max-wait: -1
max-idle: 8
min-idle: 0
#数据源
datasource:
name: mclz
type: com.alibaba.druid.pool.DruidDataSource
druid:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/mclz?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&useSSL=false
username: root
password: root
initial-size: 5
min-idle: 5
max-active: 20
max-wait: 60000
time-between-eviction-runs-millis: 60000
min-evictable-idle-time-millis: 300000
validation-query: SELECT 'x'
validation-query-timeout: 6
test-while-idle: true
test-on-borrow: false
test-on-return: false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
filters: stat
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
logging:
config: classpath:logback.xml
mybatis:
mapper-locations: classpath:mapping/*.xml
type-aliases-package: com.easystudy.model
- 动态网页
示例代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title> 欢送登录 hello 零碎 </title>
<link rel="stylesheet" type="text/css" href="../css/login.css"/>
</head>
<body>
<h1>Hello World!</h1>
</body>
</html>
- 零碎 POM 配置
<?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>
<groupId>com.easystudy</groupId>
<artifactId>hello</artifactId>
<version>1.0.1.1</version>
<!-- spring boot 我的项目 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!-- 我的项目属性: 子模块不能引用父我的项目的 properties 变量 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.RELEASE</spring-cloud.version>
<lombok.version>1.16.20</lombok.version>
</properties>
<!-- 我的项目依赖治理申明,对立治理我的项目依赖的版本信息,继承我的项目无需申明版本 -->
<dependencyManagement>
<!-- 依赖治理 -->
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- hystrix 仪表盘 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
<version>${hystrix.dashboard}</version>
</dependency>
<!-- Spring-Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- 阿里巴巴 druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<!-- 阿里巴巴 json 序列化反序列化 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
<!--
RESTFul 接口文档:通过接口拜访文档:http://localhost:8762/swagger-ui.html,8762 为服务配置的监听端口,默认 8080
feign Finchley.RELEASE 2.0.3 版本与 feign 版本抵触,应用 feign 必须要配置 2.5.0 以上版本
-->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.8.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.8.0</version>
</dependency>
<!-- feign: 自身反对 Hystrix 的
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.4.4.RELEASE</version>
</dependency>-->
<!-- 近程调用:2.0.0.RELEASE 版本会导致服务注册到 nacos 上 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
<!-- reids 作为缓存 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.1.4.RELEASE</version>
</dependency>
<!-- 文件上传 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<!-- httpclient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.4.1</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.1</version>
</dependency>
<!-- junit 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- SpringMVC -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- RESTFul 接口文档:通过接口拜访文档:http://localhost:8762/swagger-ui.html,8762 为服务配置的监听端口,默认 8080 -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
</dependency>
<!-- 配置文件读取 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!--Lombok:打消模板代码 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- logback 日志包 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- Spring-Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- 阿里巴巴 druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
</dependencies>
<!-- 编译插件 -->
<build>
<plugins>
<!--spring boot maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<!-- 蕴含本地 jar 包 -->
<configuration>
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
</plugins>
</build>
</project>
- 系统日志配置
系统配置如下:
<configuration>
<!-- 每个 logger 都关联到 logger 上下文,默认上下文名称为“default”, 用于辨别不同应用程序的记录。一旦设置,不能修该 -->
<contextName>hello</contextName>
<!-- 配置常量,在前面的配置中应用 -->
<property name="PROJECT_NAME" value="hello" />
<!-- 配置常量,在前面的配置中应用 -->
<property name="COMPANY_NAME" value="hello" />
<!-- 定义日志文件的存储地址 勿在 LogBack 的配置中应用相对路径 -->
<property name="LOG_HOME" value="/home/${COMPANY_NAME}/logs/${PROJECT_NAME}" />
<!-- 定义日志输入格局: 左对齐级别 - 日期 - 音讯 换行 -->
<property name="LOG_PATTERN" value="[%-5p] - %d{yyyy-MM-dd HH:mm:ss} - %msg%n" />
<!-- 定义日志输入字符集 -->
<property name="LOG_CHARSET" value="UTF-8" />
<!-- 调试日志:输入控制台 -->
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<!-- 定义输入格局 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<!-- 比 INFO 小的日志级别不会被打印进去: 打印所有级别 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!-- 失常 INFO 级别日志: 输入文件 -->
<appender name="INFO-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 定义输入文件名 -->
<file>${LOG_HOME}/info/${PROJECT_NAME}.log</file>
<!-- 定义输入格局 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<!-- 比该配置的小的日志级别不会被打印进去 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<!-- 定义日志滚动的策略 -->
<!-- TimeBasedRollingPolicy 和 SizeBasedTriggeringPolicy 抵触, 应用 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 定义文件滚动时的文件名的格局:dys-warn_2019-01-10-%i.log-->
<fileNamePattern>${LOG_HOME}/info/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- 每个文件大小最大 200M -->
<maxFileSize>200MB</maxFileSize>
<!-- 最大保留 n 天 -->
<maxHistory>7</maxHistory>
<!-- 日志总保留量为 2G:该属性在 1.1.6 版本后 才开始反对 -->
<totalSizeCap>2GB</totalSizeCap>
<!-- 启动时革除有效历史数据 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- 正告日志: 输入文件 -->
<appender name="WARN-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 定义输入文件名 -->
<file>${LOG_HOME}/warn/${PROJECT_NAME}.log</file>
<!-- 定义输入格局 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<!-- 比该配置的小的日志级别不会被打印进去 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
</filter>
<!-- 定义日志滚动的策略 -->
<!-- TimeBasedRollingPolicy 和 SizeBasedTriggeringPolicy 抵触, 应用 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 定义文件滚动时的文件名的格局:dys-warn_2019-01-10-%i.log-->
<fileNamePattern>${LOG_HOME}/warn/${PROJECT_NAME}-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- 每个文件大小最大 200M -->
<maxFileSize>200MB</maxFileSize>
<!-- 最大保留 n 天 -->
<maxHistory>7</maxHistory>
<!-- 日志总保留量为 2G:该属性在 1.1.6 版本后 才开始反对 -->
<totalSizeCap>2GB</totalSizeCap>
<!-- 启动时革除有效历史数据 -->
<cleanHistoryOnStart>true</cleanHistoryOnStart>
</rollingPolicy>
</appender>
<!-- 谬误日志: 输入文件 -->
<appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 定义输入文件名 -->
<file>${LOG_HOME}/error/${PROJECT_NAME}.log</file>
<!-- 定义输入格局 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<!-- 比该配置的小的日志级别不会被打印进去 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<!-- 定义日志滚动的策略 -->
<!-- TimeBasedRollingPolicy 和 SizeBasedTriggeringPolicy 抵触, 应用 SizeAndTimeBasedRollingPolicy -->
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- 定义文件滚动时的文件名的格局:dys-warn_2019-01-10.log-->
<fileNamePattern>${LOG_HOME}/error/${PROJECT_NAME}_%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<!-- 每个文件大小最大 500M -->
<maxFileSize>500MB</maxFileSize>
<!-- 最大保留 n 天 -->
<maxHistory>15</maxHistory>
<!-- 日志总保留量为 2G:该属性在 1.1.6 版本后 才开始反对 -->
<totalSizeCap>2GB</totalSizeCap>
</rollingPolicy>
</appender>
<!-- 根日志输入:root 为默认日志输入 INFO 或以上级别(additivity=true 时被继承,或 name 类无奈找到时被继承 -->
<root level="INFO">
<!-- 输入到控制台 -->
<appender-ref ref="CONSOLE-LOG" />
<!-- 输入到各个类型日志文件 -->
<appender-ref ref="INFO-LOG" />
<appender-ref ref="WARN-LOG" />
<appender-ref ref="ERROR-LOG" />
</root>
<!-- 调试日志:输入控制台 -->
<appender name="CONSOLE-LOG2" class="ch.qos.logback.core.ConsoleAppender">
<!-- 定义输入格局 -->
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${LOG_PATTERN}</pattern>
<charset>${LOG_CHARSET}</charset>
</encoder>
<!-- 比 DEBUG 小的日志级别不会被打印进去: 打印所有级别 -->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>DEBUG</level>
</filter>
</appender>
<!-- mybatis 输入:不继承根配置 -->
<logger name="com.easystudy.mapper" level="DEBUG" additivity="false">
<!-- 输入到控制台 -->
<appender-ref ref="CONSOLE-LOG2" />
</logger>
</configuration>
以上就是残缺的、最根底的我的项目的代码生成介绍,该我的项目次要通过如下形式实现:
- 约定的名称、门路等
系统生成代码通过约定的值进行的,包含日志存储地位、名称、默认依赖。
- 默认的代码格调款式
代码格调应用比拟标准的款式进行生成
- 默认的模板
所有的代码是依赖模板生成的,有模板的拷贝替换、模板依葫芦画瓢,这里可能有作者代码的身影在外面,见谅!
二、单干应用
源码获取、单干、技术交换请获取如下联系方式:
QQ 交换群:961179337
微信账号:lixiang6153
公众号:IT 技术快餐
电子邮箱:lixx2048@163.com