1.springboot+mybatis多数据源配置
pom
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
yaml
spring:
datasource:
ds1:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://localhost:3306/hdh?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 12345
ds2:
driver-class-name: com.mysql.jdbc.Driver
jdbc-url: jdbc:mysql://47.--.--.66:3306/hdh?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 123456
#配置日志
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
数据源1配置
User1Mapper下使用配置1(ds1)
User2Mapper下使用配置2(ds2)
@Configuration
@MapperScan(basePackages = "com.hdh.mybatisds.databases.ds1mapper", sqlSessionFactoryRef = "ds1SqlSessionFactory")
public class DataSourceMybatis1 {
@Bean(name = "ds1DataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "ds1SqlSessionFactory")
@Primary
public SqlSessionFactory ds1SqlSessionFactory(@Qualifier("ds1DataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/ds1/*.xml"));
return bean.getObject();
}
@Bean("ds1SqlSessionTemplate")
@Primary
public SqlSessionTemplate ds1SqlSessionTemplate(
@Qualifier("ds1SqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
数据源2配置
@Configuration
@MapperScan(basePackages = "com.hdh.mybatisds.databases.ds2mapper", sqlSessionFactoryRef = "ds2SqlSessionFactory")
public class DataSourceMybatis2 {
@Bean(name = "ds2DataSource")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSource getDateSource1() {
return DataSourceBuilder.create().build();
}
@Bean(name = "ds2SqlSessionFactory")
public SqlSessionFactory ds2SqlSessionFactory(@Qualifier("ds2DataSource") DataSource datasource)
throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(datasource);
bean.setMapperLocations(
new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/ds2/*.xml"));
return bean.getObject();
}
@Bean("ds2SqlSessionTemplate")
public SqlSessionTemplate ds2SqlSessionTemplate(
@Qualifier("ds2SqlSessionFactory") SqlSessionFactory sessionfactory) {
return new SqlSessionTemplate(sessionfactory);
}
}
2.springboot+JdbcTemplate多数据源配置
yaml
spring:
datasource:
ds1:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hdh?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 12345
ds2:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/hdh?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
username: root
password: 12345
#配置日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
配置类
/**
* JdbcTemplate多数据源配置
* 依赖于数据源配置
*
* @see
*/
@Configuration
public class JdbcTemplateDataSourceConfig {
//JdbcTemplate主数据源ds1数据源
@Primary
@Bean(name = "ds1JdbcTemplate")
public JdbcTemplate ds1JdbcTemplate(@Qualifier("ds1DataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
//JdbcTemplate第二个ds2数据源
@Bean(name = "ds2JdbcTemplate")
public JdbcTemplate ds2JdbcTemplate(@Qualifier("ds2DataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
依赖
/**
* 多数据源配置
*/
@Configuration
public class DataSourceConfig {
//主数据源配置 ds1数据源
@Primary
@Bean(name = "ds1DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds1")
public DataSourceProperties ds1DataSourceProperties() {
return new DataSourceProperties();
}
//主数据源 ds1数据源
@Primary
@Bean(name = "ds1DataSource")
public DataSource ds1DataSource(@Qualifier("ds1DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
//第二个ds2数据源配置
@Bean(name = "ds2DataSourceProperties")
@ConfigurationProperties(prefix = "spring.datasource.ds2")
public DataSourceProperties ds2DataSourceProperties() {
return new DataSourceProperties();
}
//第二个ds2数据源
@Bean("ds2DataSource")
public DataSource ds2DataSource(@Qualifier("ds2DataSourceProperties") DataSourceProperties dataSourceProperties) {
return dataSourceProperties.initializeDataSourceBuilder().build();
}
}
3.springboot+mybatis分页(插件)
pom
<!-- pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
yaml
# pagehelper
pagehelper:
helperDialect: mysql
reasonable: true
supportMethodsArguments: true
params: count=countSql
使用方法
@Test
void user1Mapper() {
PageHelper.startPage(1, 5);
List<User> lists = user1Mapper.selectAll();
PageInfo<User> pageInfo = new PageInfo<User>(lists);
}
4.springboot+mybatis-plus分页(自带)
yaml
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: count=countSql
配置类
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
使用
/**
* 功能描述:QueryWrapper分页
*
* @author:hdh
* @date: 2021/9/1 17:39
*/
@Test
public void pagehelp() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Page<User> page = new Page<>(1, 5);
IPage<Map<String, Object>> iPage = userMapper.selectMapsPage(page, queryWrapper);
System.out.println("总页数:" + iPage.getPages());
System.out.println("总记录数:" + iPage.getTotal());
System.out.println(iPage.getRecords().size());
}
/**
* 功能描述:自定义分页
*
* @author:hdh
* @date: 2021/9/1 17:39
*/
@Test
public void customPagehelp() {
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Page<User> page = new Page<>(1, 5);
IPage<Map<String, Object>> iPage = userMapper.selectAll(page);
System.out.println("总页数:" + iPage.getPages());
System.out.println("总记录数:" + iPage.getTotal());
System.out.println(iPage.getRecords().size());
}
5.springboot+mybatis-plus分页gmtCreate、gmtModified
实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Long id;
private String name;
private Integer age;
private String email;
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
}
配置类
@Slf4j
@Component
// 一定不要忘记把处理器加到IOC容器中!
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill.....");
// setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject
this.setFieldValByName("gmtCreate", new Date(), metaObject);
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
// 更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill.....");
this.setFieldValByName("gmtModified", new Date(), metaObject);
}
}
5.httpclient基本请求
pom
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.3.5</version>
</dependency>
httpUtils
/**
* HttpClient工具类
*/
public class HttpClientUtils
{
private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录
private static RequestConfig requestConfig = null;
static
{
// 设置请求和传输超时时间
requestConfig = RequestConfig.custom().setSocketTimeout(2000).setConnectTimeout(2000).build();
}
/**
* post请求传输json参数
* @param url url地址
* @param jsonParam 参数
* @return
*/
public static JSONObject httpPost(String url, JSONObject jsonParam)
{
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
// 设置请求和传输超时时间
httpPost.setConfig(requestConfig);
try
{
if (null != jsonParam)
{
// 解决中文乱码问题
StringEntity entity = new StringEntity(jsonParam.toString(), "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/json");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
String str = "";
try
{
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
}
catch (Exception e)
{
logger.error("post请求提交失败:" + url, e);
}
}
}
catch (IOException e)
{
logger.error("post请求提交失败:" + url, e);
}
finally
{
httpPost.releaseConnection();
}
return jsonResult;
}
/**
* post请求传输String参数 例如:name=Jack&sex=1&type=2
* Content-type:application/x-www-form-urlencoded
* @param url url地址
* @param strParam 参数
* @return
*/
public static JSONObject httpPost(String url, String strParam)
{
// post请求返回结果
CloseableHttpClient httpClient = HttpClients.createDefault();
JSONObject jsonResult = null;
HttpPost httpPost = new HttpPost(url);
httpPost.setConfig(requestConfig);
try
{
if (null != strParam)
{
// 解决中文乱码问题
StringEntity entity = new StringEntity(strParam, "utf-8");
entity.setContentEncoding("UTF-8");
entity.setContentType("application/x-www-form-urlencoded");
httpPost.setEntity(entity);
}
CloseableHttpResponse result = httpClient.execute(httpPost);
// 请求发送成功,并得到响应
if (result.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
String str = "";
try
{
// 读取服务器返回过来的json字符串数据
str = EntityUtils.toString(result.getEntity(), "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(str);
}
catch (Exception e)
{
logger.error("post请求提交失败:" + url, e);
}
}
}
catch (IOException e)
{
logger.error("post请求提交失败:" + url, e);
}
finally
{
httpPost.releaseConnection();
}
return jsonResult;
}
/**
* 发送get请求
* @param url 路径
* @return
*/
public static JSONObject httpGet(String url)
{
// get请求返回结果
JSONObject jsonResult = null;
CloseableHttpClient client = HttpClients.createDefault();
// 发送get请求
HttpGet request = new HttpGet(url);
request.setConfig(requestConfig);
try
{
CloseableHttpResponse response = client.execute(request);
// 请求发送成功,并得到响应
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
// 读取服务器返回过来的json字符串数据
HttpEntity entity = response.getEntity();
String strResult = EntityUtils.toString(entity, "utf-8");
// 把json字符串转换成json对象
jsonResult = JSONObject.parseObject(strResult);
}
else
{
logger.error("get请求提交失败:" + url);
}
}
catch (IOException e)
{
logger.error("get请求提交失败:" + url, e);
}
finally
{
request.releaseConnection();
}
return jsonResult;
}
}
6.统一返回结果集
/**
* 功能描述:统一返回结果集
*
* @author:hdh
* @date: 2021/9/1 11:13
*/
@Data
public class ResultData {
private String code;
private String msg;
private Object data;
public static ResultData success(Object data) {
return resultData(ResponseCode.SUCCESS.val(), ResponseCode.SUCCESS.msg(), data);
}
public static ResultData success(Object data, String msg) {
return resultData(ResponseCode.SUCCESS.val(), msg, data);
}
public static ResultData fail(String code, String msg) {
return resultData(code, msg, null);
}
public static ResultData fail(String code, String msg, Object data) {
return resultData(code, msg, data);
}
private static ResultData resultData(String code, String msg, Object data) {
ResultData resultData = new ResultData();
resultData.setCode(code);
resultData.setMsg(msg);
resultData.setData(data);
return resultData;
}
}
/**
* 功能描述:响应状态码
*
* @author:hdh
* @date: 2021/9/1 11:02
*/
public enum ResponseCode {
/*
成功
*/
SUCCESS("200", "成功"),
/*
成功
*/
ERROR("500", "失败");
private String val;
private String msg;
private ResponseCode(String value, String msg) {
this.val = value;
this.msg = msg;
}
public String val() {
return val;
}
public String msg() {
return msg;
}
}
7.springBoot 配置Swagger2
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
SwaggerConfig文件
注意扫面路径
.apis(RequestHandlerSelectors.basePackage(“cn.attackme.myuploader.controller”))
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration
@EnableSwagger2
public class SwaggerConfig {
// swagger访问地址http://localhost:端口号/程序上下文/swagger-ui.html
@Bean
public Docket createRestApi() {
return new Docket(DocumentationType.SWAGGER_2)
.apiInfo(apiInfo())
.select()
//为当前包路径
.apis(RequestHandlerSelectors.basePackage("cn.attackme.myuploader.controller"))
.paths(PathSelectors.any())
.build();
}
//构建 api文档的详细信息函数,注意这里的注解引用的是哪个
private ApiInfo apiInfo() {
return new ApiInfoBuilder()
//页面标题
.title("测试swagger")
//创建人
.contact(new Contact("测试swagger", "http://aaaa/aaaa", "123456@qq.com"))
//版本号
.version("1.0")
//描述
.description("接口信息")
.build();
}
}
测试
/**
* 大文件上传
*/
@RestController
@RequestMapping("/BigFile")
@CrossOrigin
@Api(value = "大文件分片上传/断点上传", tags = "大文件分片上传/断点上传")
public class BigFileUploadController {
@Autowired
private FileService fileService;
@PostMapping("/")
@ApiImplicitParams({
@ApiImplicitParam(name = "name", value = "文件名", dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "md5", value = "文件名MD5", dataType = "String", paramType = "query"),
@ApiImplicitParam(name = "size", value = "文件大小", dataType = "Long", paramType = "query"),
@ApiImplicitParam(name = "chunks", value = "文件总片数", dataType = "Integer", paramType = "query"),
@ApiImplicitParam(name = "chunk", value = "当前分片片数", dataType = "Integer", paramType = "query"),
@ApiImplicitParam(name = "file", value = "分片文件", dataType = "File", paramType = "query"),
})
@ApiResponse(response = void.class, code = 200, message = "接口返回对象参数")
public void upload(String name, String md5, Long size, Integer chunks, Integer chunk, MultipartFile file) throws IOException {
if (chunks != null && chunks != 0) {
fileService.uploadWithBlock(name, md5, size, chunks, chunk, file);
} else {
fileService.upload(name, md5, file);
}
}
}
访问swagger页面 http://127.0.0.1:8080/swagger-ui.html
7.过滤器实现
//过滤器的实现是基于实现Filter接口重写Filter中的init(),doFilter()以及 destory() 方法
//在 doFilter()方法参数中 FilterChain filterChain会以参数的形式传递但下个Filter中去形成了以Filter 为A,doFilter为B的A(B)的函数回调。
@Component
//拦截方法:
//1.过滤那些路径 https://localhost:8080/**
//2.配置Bean
//方法一: /**过滤所有请求
@WebFilter(urlPatterns = "/**")
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//初始化
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
//销毁
}
//方法二:将过滤器注入Spring容器
@Bean
public FilterRegistrationBean testFilterRegistration() {
FilterRegistrationBean registration = new FilterRegistrationBean(new MyFilter());
registration.addUrlPatterns("/test");
registration.setName("myFilter");
return registration;
}
}
8.拦截器实现
1.拦截器只能对action请求起作用
public class MyIntercept implements HandlerInterceptor {
//preHandle
//
//调用时间:Controller方法处理之前
//
//执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序一个接一个执行
//
//若返回false,则中断执行,注意:不会进入afterCompletion
//
//
//
// postHandle
//
//调用前提:preHandle返回true
//
//调用时间:Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
//
//执行顺序:链式Intercepter情况下,Intercepter按照声明的顺序倒着执行。
//
//备注:postHandle虽然post打头,但post、get方法都能处理
//
//
//
// afterCompletion
//
//调用前提:preHandle返回true
//
//调用时间:DispatcherServlet进行视图的渲染之后
//
// 多用于清理资源
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//Controller方法处理之前
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//Controller方法处理完之后,DispatcherServlet进行视图的渲染之前,也就是说在这个方法中你可以对ModelAndView进行操作
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//DispatcherServlet进行视图的渲染之后
}
2.配置拦截器
@Configuration
public class MyInterceptConfig implements WebMvcConfigurer {
@Autowired
private HandlerInterceptor handlerInterceptor;
/**
* @Description:注册一个Interceptor
* @Author: hdh
* @Date: 2021-04-21 11:44
**/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//一个*:只匹配字符,不匹配路径(/)
// 两个**:匹配字符,和路径(/)
//addInterceptor()添加一个自定义拦截器
//addPathPatterns()添加一个拦截路径
//excludePathPatterns() 删除一个拦截路径
//order()优先级 越小优先级越高
registry.addInterceptor(handlerInterceptor).addPathPatterns("/**");
}
}