springboot整合mybatis并设置多数据源
2020-03-22 16:06:24来源:博客园 阅读 ()
springboot整合mybatis并设置多数据源
现在springboot的火热程度已经超过了spring了,因为springboot简单快速方便,springboot的基础是“约定大于配置”。整合了所有的框架,就可以把springboot当作一个框架集合。
我们来看看spring官网对springboot的特点的描述:
1. 创建独立的Spring应用程序
2.直接嵌入Tomcat、Jetty或Undertow(不需要部署WAR文件)
3.提供自以为是的“starter”依赖项以简化构建配置
4.尽可能自动配置Spring和第三方库
5.提供生产就绪功能,如度量、运行状况检查和外部化配置
6.完全没有代码生成,也不需要XML配置(重点)
最近在学习springboot。今天来介绍下springboot整合mybatis。
一.springboot项目的搭建
1.springboot项目的创建
2.springboot跳转页面,这里跟spring是一样的。
@RestController public class HelloController { @RequestMapping(value = "/hello") public String hello(){ return "index"; } } 这里的返回的"index"默认位于resources/static下的。
当springboot启动的时候,我们可以看到这两行: Tomcat initialized with port(s): 8080 (http) 这一行说明springboot的默认端口为8080。也可以在application.propertices里面配置: server: port:8088 Starting Servlet engine: [Apache Tomcat/9.0.31] 这一行说明springboot内置的tomcat的版本。
这样启动springboot项目后,在浏览器地址栏上输入localhost:8080/hello。就可以打开一个页面。
二.springboot整合mybatis
本文不使用application.properties文件 而使用更加简洁的application.yml文件。将resource文件夹下原有的application.properties文件删除,创建application.yml配置文件(备注:其实SpringBoot底层会把application.yml文件解析为application.properties),
.yml和.properties没什么区别,差异在于yml会有层级的划分,并且注意在冒号:后面要有空格.
在这里是使用的@MapperScan注解来,而不是用的mybatisConfig.xml配置mybatis的。
1.配置数据源,在application.yml的配置文件中。
spring: datasource: driver-class-class: com.mysql.jdbc.Driver ## type: com.zaxxer.hikari.HikariDataSource jdbcUrl: jdbc:mysql://localhost:3306/zj?serverTimezone=GMT%2B8 username: root password: root
2.配置mybaits的mapper路径
mybatis: mapper-locations: classpath:mapping/*.xml
3.mapper接口
public interface UserMapper { /*** * 根据主键id查询用户 * @param id * @return */ User selectByPrimaryKey(Integer id); }
4.user的实体这里就不说了,这个很容易
5.在resources下面创建一个mapping/UserMapper.xml文件,这里的路径是对应上面第二部配置的mybatis的mapper路径的。mapper.xml的namespace就是mapper类的全类名。
<?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="cn.seven.demo.dao.UserMapper"> <resultMap id="baseResultMap" type="cn.seven.demo.entity.User"> <id column="id" jdbcType="INTEGER" property="id"></id> <result column="realName" jdbcType="VARCHAR" property="realName"></result> <result column="username" jdbcType="VARCHAR" property="username"></result> <result column="sex" jdbcType="INTEGER" property="sex"></result> </resultMap> <!--根据主键查询值--> <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="baseResultMap"> select * from T_USER where id = #{id} </select> </mapper>
6.mybatis的测试类
@SpringBootTest(classes = SpringbootdemoApplication.class) @RunWith(SpringRunner.class)//让测试运行于Spring测试环境 public class MybatisTest { @Resource private UserMapper userMapper; @Test public void test(){ User user = userMapper.selectByPrimaryKey(1); System.out.println(user); } }
到这里springboot整合mybatis就完成了。就是这么简单。
三.配置mybatis多数据源
1. 配置MySQL多数据源
spring: datasource: master: driver-class-class: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource jdbcUrl: jdbc:mysql://localhost:3306/zj?serverTimezone=GMT%2B8 username: root password: root slave: driver-class-class: com.mysql.jdbc.Driver type: com.zaxxer.hikari.HikariDataSource jdbcUrl: jdbc:mysql://localhost:3307/zj?serverTimezone=GMT%2B8 username: root password: root
2.由于是多数据源,所以在pringboot都启动类(*Application.java)上需要禁用默认得数据源组件
//禁用默认的数据源组件 @SpringBootApplication(exclude = DataSourceAutoConfiguration.class)
3.需要自己创建一个动态数据源的组件,这里我创建的是mybatisConfig.java类;
@Configuration @MapperScan(basePackages = "cn.seven.demo.dao")//扫瞄DAO的包 @Slf4j public class MybatisConfig { /** * 创建主数据源 * @return */ @Bean("master") @Primary //设置优先级 @ConfigurationProperties("spring.datasource.master") //配置属性文件 public DataSource master(){ return DataSourceBuilder.create().build();//builder建造者模式 } /** * 创建从数据源 * @return */ @Bean("slave") @Primary @ConfigurationProperties("spring.datasource.slave") public DataSource slave(){ return DataSourceBuilder.create().build(); } /** * 生成自定义的数据源 * @return */ @Bean("dynamicDataSource") public DataSource dynamicDataSource(){ DynamicDataSource dynamicDataSource = new DynamicDataSource(); Map<Object,Object> mapDataSource = new HashMap<Object,Object>(2); mapDataSource.put("master",master()); mapDataSource.put("slave",slave()); //将master数据源作为指定的数据源 dynamicDataSource.setDefaultDataSource(master()); //将master和slave数据源作为指定的数据源 dynamicDataSource.setDataSource(mapDataSource); return dynamicDataSource; } @Bean public SqlSessionFactoryBean sqlSessionFactoryBean() throws IOException { SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean(); //配置数据源,此处配置为关键配置,如果没有将dynamicDataSource作为数据源则不能实现切换 sessionFactoryBean.setDataSource(dynamicDataSource()); //扫描model-entity的包 sessionFactoryBean.setTypeAliasesPackage("cn.seven.demo.entity"); //扫描映射文件 PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); sessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:mapping/*.xml")); return sessionFactoryBean; } /** * 配置事务管理,使用事务时哎方法头部添加@Transactional注解即可 * @return */ @Bean public PlatformTransactionManager transactionManager(){ return new DataSourceTransactionManager(dynamicDataSource()); } }
4.数据源的注解接口
@Target({ElementType.METHOD,ElementType.TYPE,ElementType.PARAMETER})//设置注解的作用范围 @Retention(RetentionPolicy.RUNTIME) @Documented public @interface DataSource { String value() default "master"; }
5.自定义的动态数据源
public class DynamicDataSource extends AbstractRoutingDataSource { /** * 如果不希望数据源在启动配置时就加载好,可以定制这个方法,从任何你希望的地方读取并返回数据源, * 比如从数据库,文件,外部接口等读取数据源信息,并最终返回一个DataSource实现类对象即可 * @return */ @Override protected DataSource determineTargetDataSource() { return super.determineTargetDataSource(); } /** * 如果希望所有的数据源在启动配置时加载好,这里通过设置数据源key值来切换数据源,定制这个方法 * @return */ @Override protected Object determineCurrentLookupKey() { return DynamicDataSourceContextHolder.getDataSourceKey(); } /** * 设置默认的数据源 * @param defaultDataSource */ public void setDefaultDataSource(Object defaultDataSource){ super.setDefaultTargetDataSource(defaultDataSource); } /** * 社渚数据源 * @param dataSource */ public void setDataSource(Map<Object,Object> dataSource){ super.setTargetDataSources(dataSource); //将数据源的key放到数据源上下文的key集合中,用于切换时判断数据源是否有效 DynamicDataSourceContextHolder.addDataSourceKey(dataSource.keySet()); } }
6.动态数据源上下文
public class DynamicDataSourceContextHolder { /** * 用于存放数据源的本地线程 */ private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>(){ /** * 讲master数据源的key作为默认的数据源的key * @return */ @Override protected String initialValue() { // return super.initialValue();// return "master"; } }; /**数据源的key集合,用于切换时判断数据源是否存在*/ private static List<Object> dataSourceKey = new ArrayList<Object>(); /** * @return the value of contextHolder */ public static ThreadLocal<String> getContextHolder() { return contextHolder; } /** * @return the value of dataSourceKey */ public static List<Object> getDataSourceKey() { return dataSourceKey; } /** * Sets the dataSourceKey * * @param dataSourceKey dataSourceKey */ public static void setDataSourceKey(String dataSourceKey) { contextHolder.set(dataSourceKey); } /** * 重置数据源 */ public static void cleanDataSource(){ contextHolder.remove(); } /** * 判断是否包含数据源 * @param key 数据源的key * @return yes no */ public static boolean containDataSourceKey(String key){ return dataSourceKey.contains(key); } /** * 添加数据源key,支持加多个,所以需要用collection * @param keys 数据源key * @return */ public static boolean addDataSourceKey(Collection<? extends Object> keys){ return dataSourceKey.add(keys); } }
7. 动态数据源的切面类
@Aspect @Order(-1) //优先于事务注解执行 @Component @Slf4j public class DynamicDataSourceAspect { @Before("@annotation(dataSource)") public void switchDataSource(JoinPoint point,DataSource dataSource){ if(!DynamicDataSourceContextHolder.containDataSourceKey(dataSource.value())){ System.out.println("数据库不匹配 : "+ dataSource.value()); }else{ System.out.println("数据库切换 : "+ dataSource.value()); DynamicDataSourceContextHolder.setDataSourceKey(dataSource.value()); } } /** * 清空数据源 * @param point * @param dataSource */ @After("@annotation(dataSource)") public void restoreDataSource(JoinPoint point,DataSource dataSource){ DynamicDataSourceContextHolder.cleanDataSource(); System.out.println("数据库连接清空:"+dataSource.value()); } }
8.注意mapper接口的userMapper的查询方法上设置:@DataSource("slave"),由于我们的默认数据库是master,所以这里需要设置成slave;
/*** * 配置多数据源 注解后面的表示方法 * @param id * @return */ @DataSource("slave") User selectByPrimaryKey(Integer id);
同时由于在mybaitsConfig里写了扫描映射文件的代码: //扫描映射文件 PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver(); sessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources("classpath:mapping/*.xml")); 所以需要将之前在yml文件里设置的读取mapper.xml文件的路径删除。
9.使用上面的测试类测试
到这,springboot整合mybatis并设置多数据源就已经完成了。
欢迎大家下载源码:https://files.cnblogs.com/files/pluto-charon/springbootdemo.rar
原文链接:https://www.cnblogs.com/pluto-charon/p/12549521.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- springboot2配置JavaMelody与springMVC配置JavaMelody 2020-06-11
- MyBatis中的$和#,用不好,准备走人! 2020-06-11
- SpringBoot 2.3 整合最新版 ShardingJdbc + Druid + MyBatis 2020-06-11
- 掌握SpringBoot-2.3的容器探针:实战篇 2020-06-11
- nacos~配置中心功能~springboot的支持 2020-06-10
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash