这个是我写的第一个随手小记,一晃眼做后端开发也有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. Apache DolphinScheduler 使用文档(5/8):使用与测试

    本文章经授权转载,原文链接: https://blog.csdn.net/MiaoSO/article/details/104770720 目录 5. 使用与测试 5.1 安全中心(Security) ...

  2. EMAS Serverless到底有多便利?

    EMAS Serverless 简介 EMAS Serverless 是阿里云提供的基于Serverless技术的一站式后端开发平台,为开发者提供高可用.弹性伸缩的云开发服务,包含云函数.云数据库.云 ...

  3. Live2d Widget

    写在最前 最早的时候看别人的博客很多都有一个可爱的看板娘,然后就找了教程给自己也整了一个.因为找到的教程都是稂莠不齐的,原作者自己说的也略显含糊(其实是我自己看不懂).总之秉承着一如既往的小白风格.把 ...

  4. 【MySQL】从入门到精通8-SQL数据库编程

    上期:[MySQL]从入门到精通7-设计多对多数据库 第零章:Mac用户看这里: mac终端写MySQL和windows基本相同,除了配置环境变量和启动有些许不同以外. 先配置环境变量,在终端输入vi ...

  5. 【java】学习路径21-基本类型的包装类

    int i =100; //Integer i2 = new Integer(100); //我们发现已被弃用,现在我们一般的方法是使用valueOf Integer i2 = null; i2 = ...

  6. 一款类似B站的开源弹幕播放器,太酷了

    今天小编推荐一款开源的弹幕视频播放器,由Typescript加Sass编写,无任何第三方运行时依赖,Gzip大小只有21KB,兼容IE11,支持SSR,支持直播.该播放器高度可定制,所有图标.按钮.色 ...

  7. SDIO移植

    1.拷贝 STM32F4xx_DSP_StdPeriph_Lib_V1.8.0\Utilities\STM32_EVAL\STM324x7I_EVAL 目录下的stm324x7i_eval_sdio_ ...

  8. limits.conf 配置不生效问题排查

    在部署数据库时,经常会遇到打开最大文件数限制 too many open files 的警告,通常我们只需要修改/etc/security/limits.conf该文件,增加两行,重新登录即可解决. ...

  9. 创建x11vnc系统进程

    〇.前言 为方便使用vnc,所以寻找到一个比较好用的vnc服务端那就是x11vnc,索性就创建了一个系统进程 一.环境 系统:银河麒麟v4-sp2-server 软件:x11vnc[linux下].V ...

  10. Elasticsearch-shell脚本实现定时删除指定时间以前索引

    〇.前言 因为elastiflow的数据量还是挺大的,接入了两台交换机的flow数据量已经开始有点大了.所以得写个脚本专门来清理索引 一.如何使用elastic的API 1.手动查询所有索引 在ELK ...