spring boot多数据源的代码实现
时间:2022-07-25
本文章向大家介绍spring boot多数据源的代码实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
TargetDataSource
package com.apedad.example.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 用于扫描动态数据源的方法注解
* @version 1.0
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TargetDataSource {
String dataSourceKey() default "master";
}
TargetDataSourceParam
package com.apedad.example.annotation;
import org.springframework.core.annotation.AliasFor;
import java.lang.annotation.*;
/**
* description: 用于切换动态数据源的参数注解
*
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TargetDataSourceParam {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
boolean required() default false;
String defaultValue() default "nttnttnue000ue001ue002nttttn";
}
DynamicDataSourceAspect
package com.apedad.example.commons;
import com.apedad.example.annotation.TargetDataSource;
import com.apedad.example.configuration.DataSourceDTO;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import java.util.List;
/**
* @version 1.0
*/
@Aspect
@Order(-1)
@Component
public class DynamicDataSourceAspect {
@Autowired
private DataSourceDTO dataSourceDTO;
private static final Logger LOG = Logger.getLogger(DynamicDataSourceAspect.class);
@Pointcut(value = "execution(* com.apedad.example.service.*.*(..))")
public void pointCut() {
}
/**
* 执行方法前更换数据源
*/
@Before(value = "pointCut()")
public void doBefore(JoinPoint joinPoint) throws ClassNotFoundException {
LOG.info("我是前置通知,我要获取参数内容了");
String dataSourceKey;
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
//最关键的一步:通过这获取到方法的所有参数名称的字符串数组
//获取被@targetdatasourceparam注解的参数
Annotation[][] paramAnnotations = methodSignature.getMethod().getParameterAnnotations();
int index = -1;
outer:
for (int i = 0; i < paramAnnotations.length; i++) {
for (Annotation a2 : paramAnnotations[i]) {
LOG.info("第" + (i + 1) + "个参数的注解类型名为:" + a2.annotationType().getSimpleName());
if (a2.annotationType().getSimpleName().equals("TargetDataSourceParam")) {
index = i;
break outer;
}
}
}
//通过下标获取到对应的值
Object[] params = joinPoint.getArgs();
if (index != -1) {
dataSourceKey = (String) params[index];
LOG.info("前端传来的 dataSourceKey= " + dataSourceKey);
if (dataSourceDTO.getDatasource().containsKey(dataSourceKey)) {
LOG.info(String.format("设置数据源为 %s", dataSourceKey));
DynamicDataSourceContextHolder.set(dataSourceKey);
} else {
useDefaultDataSource();
}
}
}
void useDefaultDataSource() {
LOG.info(String.format("使用使用默认数据源 %s", "master"));
DynamicDataSourceContextHolder.set("master");
}
/**
* 执行方法后清除数据源设置
*
* @param joinPoint 切点
* @param targetDataSource 动态数据源
*/
@After("@annotation(targetDataSource)")
public void doAfter(JoinPoint joinPoint, TargetDataSource targetDataSource) {
LOG.info(String.format("当前数据源 %s 执行清理方法", DynamicDataSourceContextHolder.get()));
DynamicDataSourceContextHolder.clear();
}
}
DynamicDataSourceContextHolder
package com.apedad.example.commons;
import org.apache.commons.lang3.RandomUtils;
import org.apache.log4j.Logger;
/**
* @version 1.0
*/
public class DynamicDataSourceContextHolder {
private static final Logger LOG = Logger.getLogger(DynamicDataSourceContextHolder.class);
private static final ThreadLocal<String> currentDatesource = new ThreadLocal<>();
/**
* 清除当前数据源
*/
public static void clear() {
currentDatesource.remove();
}
/**
* 获取当前使用的数据源
*
* @return 当前使用数据源的ID
*/
public static String get() {
return currentDatesource.get();
}
/**
* 设置当前使用的数据源
*
* @param value 需要设置的数据源ID
*/
public static void set(String value) {
currentDatesource.set(value);
}
}
DynamicRoutingDataSource
package com.apedad.example.commons;
import org.apache.log4j.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
/**
* @version 1.0
*/
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
private static final Logger LOG = Logger.getLogger(DynamicRoutingDataSource.class);
@Override
protected Object determineCurrentLookupKey() {
LOG.info("当前数据源:{}"+ DynamicDataSourceContextHolder.get());
return DynamicDataSourceContextHolder.get();
}
}
DataSourceDTO
package com.apedad.example.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* description:
*
*/
@Component
@ConfigurationProperties(prefix = "multiple")
public class DataSourceDTO {
/**
* 默认数据源
*/
private String defaultDataSource;
/**
* 接收所有数据源属性值
*/
private Map<String, DataSourcePropertiesDTO> datasource = new HashMap<>();
public Map<String, DataSourcePropertiesDTO> getDatasource() {
return datasource;
}
public void setDatasource(Map<String, DataSourcePropertiesDTO> datasource) {
this.datasource = datasource;
}
public String getDefaultDataSource() {
return defaultDataSource;
}
public void setDefaultDataSource(String defaultDataSource) {
this.defaultDataSource = defaultDataSource;
}
@Override
public String toString() {
StringBuilder result = new StringBuilder();
for (Map.Entry<String, DataSourcePropertiesDTO> entry : getDatasource().entrySet()) {
result.append("数据源名 = " + entry.getKey())
.append("驱动类 = " + entry.getValue().getDriverClassName())
.append("用户名 = " + entry.getValue().getUsername())
.append("密码 = " + entry.getValue().getPassword())
.append("连接串 = " + entry.getValue().getUrl());
}
return result.toString();
}
}
DataSourcePropertiesDTO
package com.apedad.example.configuration;
/**
* description:
*
*/
public class DataSourcePropertiesDTO {
private String driverClassName;
private String username;
private String password;
private String url;
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}
DynamicDataSourceConfiguration
package com.apedad.example.configuration;
import com.alibaba.druid.pool.DruidDataSource;
import com.apedad.example.commons.DynamicRoutingDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.log4j.Logger;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
/**
* @version 1.0
*/
@MapperScan(basePackages = "com.apedad.example.dao")
@Configuration
public class DynamicDataSourceConfiguration {
Logger logger = Logger.getLogger(DynamicDataSourceConfiguration.class);
@Autowired
DataSourceDTO dataSourceDTO;
/**
* 核心动态数据源
*
* @return 数据源实例
*/
@Bean
public DataSource dynamicDataSource() {
DynamicRoutingDataSource dataSource = new DynamicRoutingDataSource();
logger.info(dataSourceDTO.toString());
Map<String, DataSourcePropertiesDTO> dsMap = dataSourceDTO.getDatasource();
DruidDataSource defaultDs = new DruidDataSource();
Map<Object, Object> dataSourceMap = new HashMap<>();
if (null!=dsMap.get(dataSourceDTO.getDefaultDataSource())) {
defaultDs.setDriverClassName(dsMap.get(dataSourceDTO.getDefaultDataSource()).getDriverClassName());
defaultDs.setUrl(dsMap.get(dataSourceDTO.getDefaultDataSource()).getUrl());
defaultDs.setUsername(dsMap.get(dataSourceDTO.getDefaultDataSource()).getUsername());
defaultDs.setPassword(dsMap.get(dataSourceDTO.getDefaultDataSource()).getPassword());
logger.info("当前设置默认数据源key为: "+dataSourceDTO.getDefaultDataSource());
dataSource.setDefaultTargetDataSource(defaultDs);
}
for (String dataSourceKey:dsMap.keySet()){
logger.info("数据源key有: "+ dataSourceKey);
DruidDataSource tempDs = new DruidDataSource();
tempDs.setDriverClassName(dsMap.get(dataSourceKey).getDriverClassName());
tempDs.setUrl(dsMap.get(dataSourceKey).getUrl());
tempDs.setUsername(dsMap.get(dataSourceKey).getUsername());
tempDs.setPassword(dsMap.get(dataSourceKey).getPassword());
dataSourceMap.put(dataSourceKey,tempDs);
}
dataSource.setTargetDataSources(dataSourceMap);
return dataSource;
}
@Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dynamicDataSource());
//此处设置为了解决找不到mapper文件的问题
sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml"));
return sqlSessionFactoryBean.getObject();
}
@Bean
public SqlSessionTemplate sqlSessionTemplate() throws Exception {
return new SqlSessionTemplate(sqlSessionFactory());
}
/**
* 事务管理
*
* @return 事务管理实例
*/
@Bean
public PlatformTransactionManager platformTransactionManager() {
return new DataSourceTransactionManager(dynamicDataSource());
}
}
TestDataSwitch
package com.apedad.example.controller;
import com.apedad.example.annotation.TargetDataSource;
import com.apedad.example.configuration.DataSourceDTO;
import com.apedad.example.service.UserInfoService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* description:
*
*/
@RestController
@RequestMapping("/dataSwitch")
public class TestDataSwitch {
private static final Logger LOG = Logger.getLogger(TestDataSwitch.class);
@Resource(name = "userInfoService")
private UserInfoService userInfoService;
@Autowired
DataSourceDTO dataSourceDTO;
@RequestMapping("/getUserInfoFromDataBase")
public Object getUserInfoFromDataBase(String dataSource){
List result = userInfoService.listAll(dataSource);
LOG.info(result);
return result;
}
@RequestMapping("/getUserInfoFromDataNoAop")
public Object getUserInfoFromDataNoAop(){
List result = userInfoService.listAll();
LOG.info(result);
return result;
}
@RequestMapping("/getDataSourceProperties")
public Object getDataSourceProperties(){
LOG.info(dataSourceDTO.toString());
return dataSourceDTO.toString();
}
}
UserInfoMapper
package com.apedad.example.dao;
import com.apedad.example.annotation.TargetDataSourceParam;
import com.apedad.example.entity.UserInfo;
import java.util.List;
/**
* @version 1.0
*/
public interface UserInfoMapper {
List<UserInfo> listAll(String dataSource);
List<UserInfo> listAll();
int insert(UserInfo userInfo);
}
UserMapper
package com.apedad.example.dao;
import com.apedad.example.entity.User;
import java.util.List;
/**
* @version 1.0
*/
public interface UserMapper {
List<User> listAll();
int insert(User user);
}
User
package com.apedad.example.entity;
import java.util.Date;
/**
* @version 1.0
*/
public class User {
private int id;
private String username;
private String password;
private Date createTime;
private Date updateTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}
UserInfo
package com.apedad.example.entity;
import java.util.Date;
/**
* @version 1.0
*/
public class User {
private int id;
private String username;
private String password;
private Date createTime;
private Date updateTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", createTime=" + createTime +
", updateTime=" + updateTime +
'}';
}
}
UserInfoService
package com.apedad.example.service;
import com.apedad.example.annotation.TargetDataSource;
import com.apedad.example.annotation.TargetDataSourceParam;
import com.apedad.example.entity.UserInfo;
import java.util.List;
/**
* @version 1.0
*/
public interface UserInfoService {
List<UserInfo> listAll(String dataSource);
List<UserInfo> listAll();
int insert(UserInfo userInfo);
}
UserInfoServiceImpl
package com.apedad.example.service.impl;
import com.apedad.example.annotation.TargetDataSource;
import com.apedad.example.annotation.TargetDataSourceParam;
import com.apedad.example.dao.UserInfoMapper;
import com.apedad.example.entity.UserInfo;
import com.apedad.example.service.UserInfoService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* @version 1.0
*/
@Service("userInfoService")
public class UserInfoServiceImpl implements UserInfoService {
private static final Logger LOG = Logger.getLogger(UserInfoServiceImpl.class);
@Autowired
private UserInfoMapper userInfoMapper;
@Override
public List<UserInfo> listAll(@TargetDataSourceParam String dataSource) {
return userInfoMapper.listAll(dataSource);
}
@Override
public List<UserInfo> listAll() {
return userInfoMapper.listAll();
}
@Override
public int insert(UserInfo userInfo) {
return userInfoMapper.insert(userInfo);
}
}
UserService
package com.apedad.example.service.impl;
import com.apedad.example.dao.UserMapper;
import com.apedad.example.entity.User;
import com.apedad.example.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @version 1.0
*/
@Service("userService")
public class UserServiceImpl implements UserService {
private static final Logger LOG = Logger.getLogger(UserServiceImpl.class);
@Resource
private UserMapper userMapper;
@Override
public List<User> listAll() {
return userMapper.listAll();
}
@Override
public int insert(User user) {
return userMapper.insert(user);
}
}
UserServiceImpl
package com.apedad.example.service.impl;
import com.apedad.example.dao.UserMapper;
import com.apedad.example.entity.User;
import com.apedad.example.service.UserService;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
/**
* @version 1.0
*/
@Service("userService")
public class UserServiceImpl implements UserService {
private static final Logger LOG = Logger.getLogger(UserServiceImpl.class);
@Resource
private UserMapper userMapper;
@Override
public List<User> listAll() {
return userMapper.listAll();
}
@Override
public int insert(User user) {
return userMapper.insert(user);
}
}
SpringBootDynamicDatasourceStartedApplication
package com.apedad.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class SpringBootDynamicDatasourceStartedApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDynamicDatasourceStartedApplication.class, args);
}
}
user.sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`password` varchar(512) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`create_time` datetime(0) NOT NULL,
`update_time` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1002 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1000, 'admin', 'admin', '2018-09-28 16:43:38', '2018-09-28 16:43:38');
INSERT INTO `user` VALUES (1001, 'rocliu', 'rocliu', '2018-09-28 16:43:58', '2018-09-28 16:43:38');
SET FOREIGN_KEY_CHECKS = 1;
user_info.sql
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user_info
-- ----------------------------
DROP TABLE IF EXISTS `user_info`;
CREATE TABLE `user_info` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 1001 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user_info
-- ----------------------------
INSERT INTO `user_info` VALUES (1000, 'admin', 'admin@xxx.com.cn');
SET FOREIGN_KEY_CHECKS = 1;
UserInfoMapper.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.apedad.example.dao.UserInfoMapper">
<resultMap id="base_result_map" type="com.apedad.example.entity.UserInfo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="email" property="email"/>
</resultMap>
<sql id="base_sql">
id,name,email
</sql>
<select id="listAll" resultMap="base_result_map">
SELECT
<include refid="base_sql"/>
FROM user_info
</select>
<insert id="insert" parameterType="com.apedad.example.entity.UserInfo">
INSERT INTO user_info
(name,email)
VALUES
(#{name},#{email})
</insert>
</mapper>
UserMapper.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.apedad.example.dao.UserMapper">
<resultMap id="base_result_map" type="com.apedad.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
</resultMap>
<sql id="base_sql">
id,username,password,create_time,update_time
</sql>
<select id="listAll" resultMap="base_result_map">
SELECT
<include refid="base_sql"/>
FROM user
</select>
<insert id="insert" parameterType="com.apedad.example.entity.User">
INSERT INTO user
(username, password, create_time, update_time)
VALUES
(#{username},#{password},#{createTime},#{updateTime})
</insert>
</mapper>
application.yml
multiple:
defaultDataSource: other
datasource:
master:
driver-class-name: com.mysql.jdbc.Driver
password: root
url: jdbc:mysql://localhost:3306/db_master?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
other:
driver-class-name: com.mysql.jdbc.Driver
password: root
url: jdbc:mysql://localhost:3306/db_other?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
slave1:
driver-class-name: com.mysql.jdbc.Driver
password: root
url: jdbc:mysql://localhost:3306/db_slave1?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
slave2:
driver-class-name: com.mysql.jdbc.Driver
password: root
url: jdbc:mysql://localhost:3306/db_slave2?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
mybatis:
mapper-locations: classpath:mapper/*.xml
server:
port: 8088
spring:
datasource:
password: root
url: jdbc:mysql://localhost:3306/db_master?useSSL=false&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&allowMultiQueries=true
username: root
logging:
level:
com:
apedad:
example:
dao: debug
pom.xml
<?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.apedad</groupId>
<artifactId>spring-boot-dynamic-datasource-started</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>spring-boot-dynamic-datasource-started</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.6</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.42</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.7</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- 开始在 GitHub 上写博客
- 微信公众号菜单点击发送天气预报
- SAP CRM Fiori应用如何启用Sales Office和Sales Group两个字段
- 通过注册表调整 Windows 8 窗口边框宽度
- 在 Mac OS X 中创建和使用内存盘
- Mono for Android 下的 ListActivity
- 使用JavaScript Function.prototype进行代码重构的一些例子
- Activity 生命周期及其栈管理方式
- 如何操作SAP UI5应用Footer区域工具栏按钮的背景颜色
- 我的第一个 Mono for Android 应用
- 【DB笔试面试851】在Oracle中,造成“ORA-28040: No matching ...”错误的原因是什么?
- 在 Silverlight 5 项目中使用 async/await
- 开源一个 Sliverlight 导航框架
- 【DB笔试面试852】在Oracle中,什么是静默建库?
- 从 SVN 迁移到 Git