1. Entity Student.java package com.seawaterbt.ssm.entity;
import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import lombok.Data;
@Api(“学生实体对象”) @Data @TableName(“t_student”) public class Student {
@ApiModelProperty("学生id") @TableId(type = IdType.AUTO) private Integer id; @ApiModelProperty("学生姓名") private String name; @ApiModelProperty("学生年龄") private Integer age; @ApiModelProperty("学生班级") private String classname;}Student.java Teacher.java package com.seawaterbt.ssm.entity;
import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import io.swagger.annotations.Api; import io.swagger.annotations.ApiModelProperty; import lombok.Data;
@Api(“老师实体对象”) @Data @TableName(“t_teacher”) public class Teacher {
@ApiModelProperty("老师id") @TableId(type = IdType.AUTO) private Integer id; @ApiModelProperty("老师姓名") private String name; @ApiModelProperty("老师年龄") private Integer age; @ApiModelProperty("老师所教学科") private String subject;}Teacher.java
Mapper 接口及其xml StudentMapper.java package com.seawaterbt.ssm.mapper;import com.baomidou.mybatisplus.mapper.BaseMapper; import com.seawaterbt.ssm.entity.Student;
public interface StudentMapper extends BaseMapper { }StudentMapper.java StudentMapper.xml
<?xml version="1.0" encoding="UTF-8"?>StudentMapper.xml TeacherMapper.java package com.seawaterbt.ssm.mapper;
import com.baomidou.mybatisplus.mapper.BaseMapper; import com.seawaterbt.ssm.entity.Teacher;
public interface TeacherMapper extends BaseMapper { }
TeacherMapper.java TeacherMapper.xml <?xml version="1.0" encoding="UTF-8"?>
TeacherMapper.xml3. Service 接口及其实现类 StudentService.java package com.seawaterbt.ssm.service;
import com.baomidou.mybatisplus.service.IService; import com.seawaterbt.ssm.entity.Student;
public interface StudentService extends IService { }
StudentService.java StudentServiceImpl.java package com.seawaterbt.ssm.service.impl;
import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.seawaterbt.ssm.entity.Student; import com.seawaterbt.ssm.mapper.StudentMapper; import com.seawaterbt.ssm.service.StudentService; import org.springframework.stereotype.Service;
@Service public class StudentServiceImpl extends ServiceImpl<StudentMapper,Student> implements StudentService { }StudentServiceImpl.java TeacherService.java package com.seawaterbt.ssm.service;
import com.baomidou.mybatisplus.service.IService; import com.seawaterbt.ssm.entity.Teacher;
public interface TeacherService extends IService { }TeacherService.java TeacherServiceImpl.java package com.seawaterbt.ssm.service.impl;
import com.baomidou.mybatisplus.mapper.Wrapper; import com.baomidou.mybatisplus.plugins.Page; import com.baomidou.mybatisplus.service.impl.ServiceImpl; import com.seawaterbt.ssm.annotation.DataSource; import com.seawaterbt.ssm.entity.Teacher; import com.seawaterbt.ssm.enums.DataSourceEnum; import com.seawaterbt.ssm.mapper.TeacherMapper; import com.seawaterbt.ssm.service.TeacherService; import org.springframework.stereotype.Service;
import java.io.Serializable; import java.util.Collection; import java.util.List; import java.util.Map;
@Service public class TeacherServiceImpl extends ServiceImpl<TeacherMapper,Teacher> implements TeacherService {
@Override @DataSource(DataSourceEnum.DB2) public boolean insert(Teacher entity) { return super.insert(entity); } @Override @DataSource(DataSourceEnum.DB2) public boolean deleteById(Serializable id) { return super.deleteById(id); } @Override @DataSource(DataSourceEnum.DB2) public boolean updateById(Teacher entity) { return super.updateById(entity); } @Override @DataSource(DataSourceEnum.DB2) public Teacher selectById(Serializable id) { return super.selectById(id); } @Override @DataSource(DataSourceEnum.DB2) public List<Teacher> selectList(Wrapper<Teacher> wrapper) { return super.selectList(wrapper); } @Override @DataSource(DataSourceEnum.DB2) public Page<Teacher> selectPage(Page<Teacher> page) { return super.selectPage(page); } @Override @DataSource(DataSourceEnum.DB2) public Page<Teacher> selectPage(Page<Teacher> page, Wrapper<Teacher> wrapper) { return super.selectPage(page, wrapper); }} TeacherServiceImpl.java
4. Vo StudentVo.java package com.seawaterbt.ssm.vo;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;
@Data @ApiModel(“学生vo”) public class StudentVo {
@ApiModelProperty("学生姓名") private String name; @ApiModelProperty("学生年龄") private Integer age; @ApiModelProperty("学生班级") private String classname;}StudentVo.java TeacherVo.java package com.seawaterbt.ssm.vo;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data;
@Data @ApiModel(“老师vo”) public class TeacherVo {
@ApiModelProperty("老师姓名") private String name; @ApiModelProperty("老师年龄") private Integer age; @ApiModelProperty("老师教的学科") private String subject;}TeacherVo.java 5. Controller StudentController.java package com.seawaterbt.ssm.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.seawaterbt.ssm.entity.Student; import com.seawaterbt.ssm.service.StudentService; import com.seawaterbt.ssm.vo.StudentVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(“对学生表CRUD”) @RestController @RequestMapping("/student") public class StudentController {
@Autowired private StudentService studentService; @ApiOperation("添加学生") @PostMapping("/add") public String add(@RequestBody StudentVo student){ Student stu = new Student(); stu.setName(student.getName()); stu.setAge(student.getAge()); stu.setClassname(student.getClassname()); return studentService.insert(stu)?"添加成功":"添加失败"; } @ApiOperation("删除学生") @DeleteMapping("/delete/{id}") public String delete(@ApiParam("学生的主键id")@PathVariable(value = "id") Integer id){ return studentService.deleteById(id)?"删除成功":"删除失败"; } @ApiOperation("修改学生") @PostMapping("/update") public String update(@RequestBody Student student){ return studentService.updateById(student)?"修改成功":"修改失败"; } @ApiOperation(value = "查询学生") @GetMapping("/list") public List<Student> list(){ Wrapper<Student> wrapper = new EntityWrapper<>(); return studentService.selectList(wrapper); }}StudentController.java TeacherController.java package com.seawaterbt.ssm.controller;
import com.baomidou.mybatisplus.mapper.EntityWrapper; import com.baomidou.mybatisplus.mapper.Wrapper; import com.seawaterbt.ssm.entity.Teacher; import com.seawaterbt.ssm.service.TeacherService; import com.seawaterbt.ssm.vo.TeacherVo; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;
import java.util.List;
@Api(“对老师表CRUD”) @RestController @RequestMapping("/teacher") public class TeacherController {
@Autowired private TeacherService teacherService; @ApiOperation(value = "添加老师") @PostMapping("/add") public String add(@RequestBody TeacherVo teacher){ Teacher tea = new Teacher(); tea.setName(teacher.getName()); tea.setAge(teacher.getAge()); tea.setSubject(teacher.getSubject()); return teacherService.insert(tea)?"添加成功":"添加失败"; } @ApiOperation("删除老师") @DeleteMapping("/delete/{id}") public String delete(@ApiParam("老师的主键id")@PathVariable(value = "id") Integer id){ return teacherService.deleteById(id)?"删除成功":"删除失败"; } @ApiOperation("修改老师") @PostMapping("/update") public String update(@RequestBody Teacher teacher){ return teacherService.updateById(teacher)?"修改成功":"修改失败"; } @ApiOperation(value = "查询老师") @GetMapping("/list") public List<Teacher> list(){ Wrapper<Teacher> wrapper = new EntityWrapper<>(); return teacherService.selectList(wrapper); }}
package com.seawaterbt.ssm.config;
import com.alibaba.druid.support.http.StatViewServlet; import com.alibaba.druid.support.http.WebStatFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;
@Configuration public class DruidConfiguration {
@Bean public ServletRegistrationBean startViewServlet(){ ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*"); // IP白名单 servletRegistrationBean.addInitParameter("allow","127.0.0.1"); // IP黑名单(共同存在时,deny优先于allow) servletRegistrationBean.addInitParameter("deny","127.0.0.1"); //控制台管理用户 servletRegistrationBean.addInitParameter("loginUsername","admin"); servletRegistrationBean.addInitParameter("loginPassword","123456"); //是否能够重置数据 servletRegistrationBean.addInitParameter("resetEnable","false"); return servletRegistrationBean; } @Bean public FilterRegistrationBean statFilter(){ FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new WebStatFilter()); //添加过滤规则 filterRegistrationBean.addUrlPatterns("/*"); //忽略过滤的格式 filterRegistrationBean.addInitParameter("exclusions","*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"); return filterRegistrationBean; }}DruidConfiguration.java MyBatiesPlusConfiguration.java package com.seawaterbt.ssm.config;
import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.baomidou.mybatisplus.MybatisConfiguration; import com.baomidou.mybatisplus.entity.GlobalConfiguration; import com.baomidou.mybatisplus.mapper.LogicSqlInjector; import com.baomidou.mybatisplus.plugins.PaginationInterceptor; import com.baomidou.mybatisplus.plugins.PerformanceInterceptor; import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean; import com.seawaterbt.ssm.enums.DataSourceEnum; import com.seawaterbt.ssm.multiple.MultipleDataSource; import org.apache.ibatis.plugin.Interceptor; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.type.JdbcType; import org.mybatis.spring.annotation.MapperScan; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Profile;
import javax.sql.DataSource; import java.util.HashMap; import java.util.Map;
@Configuration @MapperScan(“com.seawaterbt.ssm.mapper*”) public class MyBatiesPlusConfiguration {
/* * 分页插件,自动识别数据库类型 * 多租户,请参考官网【插件扩展】 */ @Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); // 开启 PageHelper 的支持 paginationInterceptor.setLocalPage(true); return paginationInterceptor; } /** * SQL执行效率插件 */ @Bean @Profile({"dev","qa"})// 设置 dev test 环境开启 public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor(); performanceInterceptor.setMaxTime(1000); performanceInterceptor.setFormat(true); return performanceInterceptor; } @Bean(name = "db1") @ConfigurationProperties(prefix = "spring.datasource.druid.db1" ) public DataSource db1() { return DruidDataSourceBuilder.create().build(); } @Bean(name = "db2") @ConfigurationProperties(prefix = "spring.datasource.druid.db2" ) public DataSource db2() { return DruidDataSourceBuilder.create().build(); } /** * 动态数据源配置 * @return */ @Bean @Primary public DataSource multipleDataSource(@Qualifier("db1") DataSource db1, @Qualifier("db2") DataSource db2) { MultipleDataSource multipleDataSource = new MultipleDataSource(); Map< Object, Object > targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceEnum.DB1.getValue(), db1); targetDataSources.put(DataSourceEnum.DB2.getValue(), db2); //添加数据源 multipleDataSource.setTargetDataSources(targetDataSources); //设置默认数据源 multipleDataSource.setDefaultTargetDataSource(db1); return multipleDataSource; } @Bean("sqlSessionFactory") public SqlSessionFactory sqlSessionFactory() throws Exception { MybatisSqlSessionFactoryBean sqlSessionFactory = new MybatisSqlSessionFactoryBean(); sqlSessionFactory.setDataSource(multipleDataSource(db1(),db2())); //sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mapper/*/*Mapper.xml")); MybatisConfiguration configuration = new MybatisConfiguration(); //configuration.setDefaultScriptingLanguage(MybatisXMLLanguageDriver.class); configuration.setJdbcTypeForNull(JdbcType.NULL); configuration.setMapUnderscoreToCamelCase(true); configuration.setCacheEnabled(false); sqlSessionFactory.setConfiguration(configuration); sqlSessionFactory.setPlugins(new Interceptor[]{ //PerformanceInterceptor(),OptimisticLockerInterceptor() paginationInterceptor() //添加分页功能 }); //sqlSessionFactory.setGlobalConfig(globalConfiguration()); return sqlSessionFactory.getObject(); } /*@Bean public GlobalConfiguration globalConfiguration() { GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector()); conf.setLogicDeleteValue("-1"); conf.setLogicNotDeleteValue("1"); conf.setIdType(0); //conf.setMetaObjectHandler(new MyMetaObjectHandler()); conf.setDbColumnUnderline(true); conf.setRefresh(true); return conf; }*/}MyBatiesPlusConfiguration.java SwaggerConfiguration.java package com.seawaterbt.ssm.config;
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 SwaggerConfiguration {
@Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.basePackage("com.seawaterbt.ssm.controller")) .paths(PathSelectors.any()) .build() .apiInfo(apiInfo()); } private ApiInfo apiInfo(){ return new ApiInfoBuilder() .title("多数据源 SSM 测试服务") .description("多数据源 SSM 测试文档") .termsOfServiceUrl("http://www.seawaterbt.com") //.contact(new Contact("海水不甜","http://www.seawaterbt.com","809318068@qq.com")) .version("1.0") .build(); }}
DataSource.java
package com.seawaterbt.ssm.annotation;
import com.seawaterbt.ssm.enums.DataSourceEnum;
import java.lang.annotation.*;
@Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource {
DataSourceEnum value() default DataSourceEnum.DB1;}
DataSourceAspect.java
@Component @Slf4j @Aspect @Order(-1) public class DataSourceAspect {
@Pointcut("@within(com.seawaterbt.ssm.annotation.DataSource) || @annotation(com.seawaterbt.ssm.annotation.DataSource)") public void pointCut(){ } @Before("pointCut() && @annotation(dataSource)") public void doBefore(DataSource dataSource){ log.info("选择数据源---"+dataSource.value().getValue()); DataSourceContextHolder.setDataSource(dataSource.value().getValue()); } @After("pointCut()") public void doAfter(){ DataSourceContextHolder.clear(); }}
DataSourceEnum.java
package com.seawaterbt.ssm.enums;
public enum DataSourceEnum {
DB1("db1"),DB2("db2"); private String value; DataSourceEnum(String value){this.value=value;} public String getValue() { return value; }}
MultipleDataSource.java
package com.seawaterbt.ssm.multiple;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class MultipleDataSource extends AbstractRoutingDataSource {
@Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSource(); }}
DataSourceContextHolder.java
package com.seawaterbt.ssm.multiple;
public class DataSourceContextHolder {
private static final ThreadLocal<String> contextHolder = new InheritableThreadLocal<>(); /** * 设置数据源 * @param db */ public static void setDataSource(String db){ contextHolder.set(db); } /** * 取得当前数据源 * @return */ public static String getDataSource(){ return contextHolder.get(); } /** * 清除上下文数据 */ public static void clear(){ contextHolder.remove(); }}
application.yml