这个是我写的第一个随手小记,一晃眼做后端开发也有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管理应用,用以横向管理数据源的更多相关文章

  1. intellij 创建java web项目(maven管理的SSH)

    intellij 创建java web项目(maven管理的SSH) 环境intellij IDEA14.MAVEN.Spring.Struts2.Hibernate.Java Web.工程搭建. 1 ...

  2. oracle创建表空间自增空间管理

    表空间(tablespace).段(segment).区(extent).块(block),这些都是oracle数据库在数据文件中组织数据的基本单元 1.创建表空间create tablespace ...

  3. 订单业务楼层化 view管理器和model管理器进行了model和view的全面封装处理 三端不得不在每个业务入口上线时约定好降级开关,于是代码中充满了各种各样的降级开关字段

    京东APP订单业务楼层化技术实践解密 原创 杜丹 留成 博侃 京东零售技术 2020-09-29 https://mp.weixin.qq.com/s/2oExMjh70Kyveiwh8wOBVA 用 ...

  4. 云原生应用管理,像管理手机APP一样管理企业应用

    我们在使用智能手机的时候,手机APP从应用市场一键安装,安装好即点即用,当有新版本一键升级,如果不想用了长按图标删除,整个过程非常简单,小朋友都能熟练掌握.而对于企业应用,由于结构复杂.可用性要求高. ...

  5. Linux中断管理 (1)Linux中断管理机制

    目录: <Linux中断管理> <Linux中断管理 (1)Linux中断管理机制> <Linux中断管理 (2)软中断和tasklet> <Linux中断管 ...

  6. Atitit 分布式管理 vs 集中式管理

    Atitit 分布式管理 vs 集中式管理 1. 集中式管理缺点 1 1.1. 单点故障 1 1.2. 没有灵活性 1 1.3. 打败vs 征服 参考 尼可罗·马基雅弗利编著的<君主论> ...

  7. 框架源码系列十一:事务管理(Spring事务管理的特点、事务概念学习、Spring事务使用学习、Spring事务管理API学习、Spring事务源码学习)

    一.Spring事务管理的特点 Spring框架为事务管理提供一套统一的抽象,带来的好处有:1. 跨不同事务API的统一的编程模型,无论你使用的是jdbc.jta.jpa.hibernate.2. 支 ...

  8. Java SSM 客户管理 商户 管理系统 库存管理 销售报表 项目源码

    系统介绍: 1.系统采用主流的 SSM 框架 jsp JSTL bootstrap html5 (PC浏览器使用) 2.springmvc +spring4.3.7+ mybaits3.3  SSM ...

  9. SVN-项目 XXX 受源代码管理。向源代码管理注册此项目时出错。建议不要对此项目进行任何修改

    错误描述:  项目 XXX 受源代码管理.向源代码管理注册此项目时出错.建议不要对此项目进行任何修改 解决办法: 使用记事本打开,项目csproj文件删除图中几行,重新打开解决方案就可以了 原因分析: ...

随机推荐

  1. Linux系列之管理用户环境变量

    前言 环境变量控制你在Linux工作环境中的外观.行为和感觉.一共有两种类型的变量: 环境变量:这些是内置于系统中的进程范围的变量,控制着系统的外观和行为.因为是进程范围的,所以它们被任何子shell ...

  2. 论文解读(GSAT)《Interpretable and Generalizable Graph Learning via Stochastic Attention Mechanism》

    论文信息 论文标题:Interpretable and Generalizable Graph Learning via Stochastic Attention Mechanism论文作者:Siqi ...

  3. 使用flex弹性布局代替传统浮动布局来为微信小程序写自适应页面

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_109 我们知道,写习惯了前端的人,一般切图后布局页面的话,上手最习惯的是基于盒子模型的浮动布局,依赖 display 属性 + p ...

  4. Linux环境监控工具汇总

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. Linux 操作系统有诸多自带和第三方的监控工具,以下从不同维度来整理常用的一些监控工具. CPU top(经典的Linu ...

  5. Canvas 非常重要的三个函数

    beginPath 绘制路径必须添加 beginPath().它标志着一个画笔在画布中哪个地方开始画起.没有它,新起的画笔位置必定与上一次画笔结束的位置相连. // 第一个半圆 ctx.arc(60, ...

  6. iOS影视应用+全网视频下载

    又一个新的iOS影视伪装 打开软件连续点击3次列表,然后关闭重新打开即可变身,无广告全免费高画质,还有电视直播 下载地址:https://apps.apple.com/cn/app/贴画壁纸/id16 ...

  7. [CF1481D] AB Graph(构造)

    题解 给一个 n \tt n n 个点的完全有向图, ( u , v ) \tt(u,v) (u,v) 或者 ( v , u ) \tt(v,u) (v,u) 都有一条边,前提是 u ≠ v \tt ...

  8. SFSafariViewController 加载的网页与原生oc之间的交互

    问题描述: 工作中碰到这样一种场景, WebApp 已经实现了IM即时通讯及基于WebRTC实现的音视频会议,音视频聊天. 也是半路接手的项目,项目整体是使用WKWebView套壳加载h5 页面实现( ...

  9. KingbaseES V8R3 备份恢复案例之--单实例环境sys_rman脚本备份案例

    案例说明: sys_rman是KingbaseES数据库的物理备份工具,支持数据库的全备和增量备份,由于sys_rman工具使用需要配置多个参数,对于一般用户使用不是很方便.为方便用户在Kingbas ...

  10. TFT-eSPI入门使用教程

    一.准备资料 开发板:ESP32-S3 屏驱动是:ST7789_DRIVER 开发环境:VS Code + PlatformIO 注意:以上是我使用的环境,不一定需要和是使用的东西一样,这里主要是学习 ...