自主创建mybtis管理应用,用以横向管理数据源
这个是我写的第一个随手小记,一晃眼做后端开发也有7年多了,现在也准备将一些杂七杂八的资料整理下。也算是回顾这7年中做的比较有意思的东西了。
这个需求是我17年做的,当时的应用场景是仓储库比较多,随时会动态的开启和关闭。好在数据库的表结构是一致的。需要针对不同的库将商品进行有效的管理起来。考虑到数据源是动态变化的,那么使用spring架构下的多数据源配置是行不通。因为表名一致,而且数据源是动态变化的,最少也有90多家的数据,手工配置会死人的。那换成java的jdbc管理呢,最基本的那个,考虑到现在都到mybatis进行数据库管理了。往回退也不好。那么就花了几天出了这个方案。废话不说了,开工...... 第一次写博客还是有点小激动啊。
首先需要手动获取spring的application,从而手动进行资源的注入。将代码的独立性做起来。
/**
* Created by Dean on 2017/10/19.
* 获取SpringApplicationContext信息获取 该方法可以不用通过注入形式获取相关数据
*/
@Component
public class SpringApplictionAuto implements ApplicationContextAware {
// Spring应用上下文环境
private static ApplicationContext applicationContext;
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境
*
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringApplictionAuto.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象
*
* @param name
* @return Object
* @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
图1: Mybatis的大致结构
1 public SqlSessionTemplate getLocalMybatislSession() {
2 ApplicationContext applicationContext = SpringApplictionAuto.getApplicationContext();
3 SqlSessionFactory defaultSqlSessionFactory = (SqlSessionFactory) applicationContext.getBean("sqlSessionFactory");
4 SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(defaultSqlSessionFactory);
5 return sqlSessionTemplate;
6 }
获取本地SqlSessionTemplate
本地SqlSession获取好后那么后面就是重头戏了。
我们首先需要获取的有以下几点:
- 数据库连接说明
- 数据库账号信息(没有相关信息也连不上数据库,当然数据库密码小伙伴们打算用密文还是明文,都是随意的。密文的话需要双向加密方式,明文吗,倒是随时可以查其他系统数据库了)
- 数据库mapper组信息
- 数据库mapper具体地址
- 数据库mapper组和mapper的具体关联
- 数据库配置参数表,其中还有类型处理器
后面就是依次创建SqlSessionFactoryBean,SqlSessionFactory,DruidDataSource,Configuration,TypeHandler[]
1 /**
2 * 通过数据库相关信息与mybatis相对应的信息创建 SqlSessionFactory
3 *
4 * @param hospitalDbInfoEntity 数据库相关信息
5 * @param hospitalMapperEntityArrayList 该数据源下存在相应的mapper信息
6 * @return 返回SqlSessionFactory
7 * @throws Exception 创建失败时会返回异常
8 */
9 public SqlSessionFactory buildSqlSessionFactory(SqlSessionFactoryBean factoryBean, HospitalDbInfoEntity hospitalDbInfoEntity, ArrayList<HosMapper> hospitalMapperEntityArrayList) throws Exception {
10 DruidDataSource dataSource =new DruidDataSource();
11 dataSource.setDefaultAutoCommit(true);
12 dataSource.setUrl(hospitalDbInfoEntity.getUrl());
13 dataSource.setPassword(hospitalDbInfoEntity.getPassword());
14 dataSource.setUsername(hospitalDbInfoEntity.getUser());
15 dataSource.setDriverClassName(hospitalDbInfoEntity.getDriver_name());
16
17 dataSource.setInitialSize(50);
18 dataSource.setMaxActive(100);
19 dataSource.setMaxIdle(50);
20 dataSource.setMinIdle(30);
21 dataSource.setRemoveAbandoned(true);
22 dataSource.setRemoveAbandonedTimeout(180);
23 dataSource.setFilters("stdout");
24 dataSource.setResetStatEnable(false);
25 dataSource.setMaxWait(600000);
26 dataSource.setTimeBetweenEvictionRunsMillis(300000);
27 dataSource.setMinEvictableIdleTimeMillis(600000);
28 dataSource.setValidationQuery("SELECT 1 from dual");
29 dataSource.setTestOnBorrow(true);
30 dataSource.setTestOnReturn(false);
31 dataSource.setTestWhileIdle(true);
32 factoryBean.setDataSource(dataSource);
33 String paths = "";
34 factoryBean.setMapperLocations(getMapperResource(hospitalMapperEntityArrayList));
35 Configuration configuration = buildConfiguration();
36 factoryBean.setConfiguration(configuration);
37 factoryBean.setTypeHandlers(buildTypeHandlers(configuration));
38 SqlSessionFactory sqlSessionFactory = factoryBean.getObject();
39 return sqlSessionFactory;
40 }
部分创建代码
上面这块设置好后就是后面拿结果了,结果还是封装到了SqlSessionTemplate中。
1 /**
2 * 创建SqlSession信息通过医院Id值
3 *
4 * @param hospitalId 数据库中对应的唯一键值
5 * @return 返回创建好的数据库连接信息
6 */
7 public SqlSessionTemplate buildSqlSession(Integer hospitalId) {
8 SqlSession localSession = getLocalSession();
9 HosConnIdMapper hosConnIdMapper = localSession.getMapper(HosConnIdMapper.class);
10 HosMapperMapper hosMapperMapper = localSession.getMapper(HosMapperMapper.class);
11 HospitalDbInfoEntity hospitalDbInfoEntity = hosConnIdMapper.findHospitalEntity(hospitalId);
12
13 if (hospitalDbInfoEntity == null) {
14 return null;
15 }
16 ArrayList<HosMapper> hospitalMapperEntityArrayList = (ArrayList<HosMapper>) hosMapperMapper.findByHospitalId(hospitalId);
17 if (hospitalMapperEntityArrayList.size() == 0) {
18 return null;
19 }
20 SqlSessionFactory sqlSessionFactory;
21 try {
22 sqlSessionFactory = buildSqlSessionFactory(hospitalId.toString(), hospitalDbInfoEntity, hospitalMapperEntityArrayList);
23 } catch (Exception e) {
24 e.printStackTrace();
25 return null;
26 }
27 sqlSessionFactoryHashMap.put(hospitalId.toString(), sqlSessionFactory);
28 SqlSessionTemplate sqlSession = new SqlSessionTemplate(sqlSessionFactory);
29 dataPools.put(hospitalId.toString(), sqlSession);
30 return sqlSession;
31 }
创建SqlSessionTemplate
最后就是准备拿结果了:
1 /**
2 * 获取mybatis中Mapper信息
3 *
4 * @param mapper mybatis 相关dao层类名
5 * @param hospitalId mybatis连接的
6 * @param <T> 自定义类型可供不同的mapper进行使用
7 * @return 返回Mapper信息
8 */
9 public <T> T getMapperInstance(Class<T> mapper, Integer hospitalId) {
10 SqlSessionTemplate sqlSession;
11
12 if (hospitalId == 0) {
13 sqlSession = dataPools.get("localSession");//本地连接
14 } else {
15 sqlSession = dataPools.get(hospitalId.toString());
16 }
17 if (sqlSession == null) {
18 sqlSession = buildSqlSession(hospitalId);
19 }
20 return SqlSessionUtils.getSqlSession(sqlSession.getSqlSessionFactory(),sqlSession.getExecutorType(),sqlSession.getPersistenceExceptionTranslator()).getMapper(mapper);
21 }
获取具体的mapper
到此,目的达到了。可以通过入参比如数据源ID,可以动态获取某一个数据源的ID下的具体mapper。
由于当时应该是工作的第二年,很多地方写的也不好,我就将关键的地方放上来了。有些描述不对的,请小伙伴指出来。
图1来源:https://blog.csdn.net/u013541707/article/details/113245421
自主创建mybtis管理应用,用以横向管理数据源的更多相关文章
- intellij 创建java web项目(maven管理的SSH)
intellij 创建java web项目(maven管理的SSH) 环境intellij IDEA14.MAVEN.Spring.Struts2.Hibernate.Java Web.工程搭建. 1 ...
- oracle创建表空间自增空间管理
表空间(tablespace).段(segment).区(extent).块(block),这些都是oracle数据库在数据文件中组织数据的基本单元 1.创建表空间create tablespace ...
- 订单业务楼层化 view管理器和model管理器进行了model和view的全面封装处理 三端不得不在每个业务入口上线时约定好降级开关,于是代码中充满了各种各样的降级开关字段
京东APP订单业务楼层化技术实践解密 原创 杜丹 留成 博侃 京东零售技术 2020-09-29 https://mp.weixin.qq.com/s/2oExMjh70Kyveiwh8wOBVA 用 ...
- 云原生应用管理,像管理手机APP一样管理企业应用
我们在使用智能手机的时候,手机APP从应用市场一键安装,安装好即点即用,当有新版本一键升级,如果不想用了长按图标删除,整个过程非常简单,小朋友都能熟练掌握.而对于企业应用,由于结构复杂.可用性要求高. ...
- Linux中断管理 (1)Linux中断管理机制
目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...
- Atitit 分布式管理 vs 集中式管理
Atitit 分布式管理 vs 集中式管理 1. 集中式管理缺点 1 1.1. 单点故障 1 1.2. 没有灵活性 1 1.3. 打败vs 征服 参考 尼可罗·马基雅弗利编著的<君主论> ...
- 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)
一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...
- Java SSM 客户管理 商户 管理系统 库存管理 销售报表 项目源码
系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3 SSM ...
- SVN-项目 XXX 受源代码管理。向源代码管理注册此项目时出错。建议不要对此项目进行任何修改
错误描述: 项目 XXX 受源代码管理.向源代码管理注册此项目时出错.建议不要对此项目进行任何修改 解决办法: 使用记事本打开,项目csproj文件删除图中几行,重新打开解决方案就可以了 原因分析: ...
随机推荐
- std::hash<std::pair<int, int> >
标题是搞笑的 ! 这个问题只需要 since C++11 问题:怎么让 unordered_map 支持使用 pair 作为 key? 如果你能把两个东西压到一个基本类型里那么就不用解决这个问题了 . ...
- YII自定义小部件
案例如下 common/widgets/TopMenu.php(地址可以自定义位置,命名空间一定要对应) <?php /** * Created by PhpStorm. * Date: 201 ...
- 上穷碧落下凡尘:Win10系统下基于Docker配置Elasticsearch7配合Python3进行全文检索交互
原文转载自「刘悦的技术博客」https://v3u.cn/a_id_166 基于文档式的全文检索引擎大家都不陌生,之前一篇文章:使用Redisearch实现的全文检索功能服务,曾经使用Rediseac ...
- 163_技巧_Power BI 一键批量建立自定义字段参数
163_技巧_Power BI 一键批量建立自定义字段参数 一.背景 在 2022 年 5 月开始,Power BI 新增了一个非常有用的功能字段参数.再也不用写一串的 SWITCH 了.字段参数的效 ...
- Linux 09 Vim
参考源 https://www.bilibili.com/video/BV187411y7hF?spm_id_from=333.999.0.0 版本 本文章基于 CentOS 7.6 概述 Vi Vi ...
- PerfView专题 (第六篇):如何洞察 C# 中 GC 的变化
一:背景 在洞察 GC 方面,我觉得市面上没有任何一款工具可以和 PerfView 相提并论,这也是为什么我会在 WinDbg 之外还要学习这么一款工具的原因,这篇我们先简单聊聊 PerfView 到 ...
- Redis进阶篇:发布订阅模式原理与运用
"65 哥,如果你交了个漂亮小姐姐做女朋友,你会通过什么方式将这个消息广而告之给你的微信好友?" "那不得拍点女朋友的美照 + 亲密照弄一个九宫格图文消息在朋友圈发布大肆 ...
- 【Go实战基础】创建并完成第一个可执行的 go 程序
实战需求:创建并完成第一个可执行的 go 程序.项目目录:go-001具体实战步骤如下: 一.进入工程目录 cd go-001/ 二. 创建 g001.go 文件 /* * @Author: 菜鸟实战 ...
- 获取jdbc中resultSet结果集的大小
当我们执行完一条Sql语句,获取到一个 ResultSet 对象后,有时我们需要立即知道到底返回了多少个元素,但是 ResultSet 并没有提供一个 size() 方法 or length 的属性, ...
- 深入分析JVM执行引擎
程序和机器沟通的桥梁 一.闲聊 相信很多朋友在出国旅游,或者与外国友人沟通的过程中,都会遇到语言不通的烦恼.这时候我们就需要掌握对应的外语或者拥有一部翻译机.而笔者只会中文,所以需要借助一部翻译器才能 ...