数据库连接的扩展以及动态切换

前几天完成了一个很小的java项目,尽管项目很小,但是有不错的设计,与大家分享下遇到的问题以及解决方案。

问题:项目中需要能够操作多个数据库,并且要有不错的扩展性,随时添加数据库连接。

其实这个需求还是挺正常的,比如说:有一个网站在不同的地区涉及业务,而不同地区的数据存储在不同的数据库,并且日后扩展规模扩展区域会增添数据库。

首先想到的是使用Spring来管理MyBatis的SqlSession,因为最近项目也一直使用Spring,但是Spring容器初始化之后,很难再添加数据源,而且多个数据库在Spring中xml配置文件需要复制多份datasource,sqlSessionFactory以及sqlSession,代码很不优雅,扩展不足。

随后设想使用MyBatis自己来创建SqlSessionFactory以及SqlSession,MyBatis创建SqlSessionFactory是通过读取xml配置文件,每个数据源使用一个配置文件,增加一个配置文件也就能够动态增加一个SqlSession(数据连接)。


部分代码如下:

	area_one.xml中的主要配置(<mappers> 等配置省略):
	<configuration >
		<environments default="development">
			<environment id="development">
				<transactionManager type="JDBC">
			 	   </transactionManager>
		
				<dataSource type="POOLED">
					<property name="driver" value="com.mysql.jdbc.Driver" />
					<property name="url" value="jdbc:localhost:3306/area_one?characterEncoding=utf-8" />
					<property name="username" value="root" />
					<property name="password" value="root" />
				</dataSource>
			</environment>
		</environments>
	</configuration>

	area_two.xml中的主要配置(<mappers> 等配置省略):
	<configuration >
		<environments default="development">
			<environment id="development">
				<transactionManager type="JDBC">
			 	   </transactionManager>
		
				<dataSource type="POOLED">
					<property name="driver" value="com.mysql.jdbc.Driver" />
					<property name="url" value="jdbc:localhost:3306/area_two?characterEncoding=utf-8" />
					<property name="username" value="root" />
					<property name="password" value="root" />
				</dataSource>
			</environment>
		</environments>
	</configuration>

	CustomSqlSessionFactoryBuilder类用来根据xml配置文件创建SqlSessionFctory,并且据此创建SqlSession对象
	public class CustomSqlSessionFactoryBuilder
	{
		public static void buildSqlSessions()	// 静态方法,用来创建以及更新所有的SqlSession,当有新增的xml配置文件添加到res文件夹时更新SqlSesion集
		{
			File resource_directory = new File("res");  // 读取资源文件夹(xml配置文件保存于资源文件夹res中)	
			File[] resources = resource_directory.listFiles();
			for(File resource : resources) // 循环所有配置文件
			{
				if(resource.getName().endsWith(".xml"))
				{
					System.out.println(resource.getName());
					
					if(!CustomSqlSessionHolder.getExistedSqlSessions().keySet().contains(resource.getName())) //CustomSqlSessionHolder类保存已有的SqlSession,若已存在则跳过
					{
						try
						{
							SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
							InputStream is = Resources.getResourceAsStream(resource.getName());
							SqlSessionFactory sqlSessionFactory = builder.build(is);
							SqlSession sqlSession = sqlSessionFactory.openSession();
							String key = resource.getName().substring(0, resource.getName().indexOf(".xml"));
							CustomSqlSessionHolder.getExistedSqlSessions().put(key, sqlSession); // 以地区的名字为key,对应的SqlSession对象为value进行存储
							
							System.out.println(sqlSessionFactory);
						}
						catch (Exception e)
						{
							e.printStackTrace();
						}
					}
				}
			}
			
			System.out.println("SqlSessionHolder Updated!");
		}    

	CustomSqlSessionHolder类用来保存现有的SqlSession,以及当有新增的xml配置文件添加到res文件夹时更新SqlSesion集合
	public class CustomSqlSessionHolder
	{
		private static Map<String, SqlSession> sqlSessions = new HashMap<String, SqlSession>();
		
		public static Map<String, SqlSession> getExistedSqlSessions()
		{
			return sqlSessions;
		}
		
		public static void updateSqlSessions()
		{
			CustomSqlSessionFactoryBuilder.buildSqlSessions();
		}
		
		public static SqlSession getNeededSqlSession(String area_name)
		{
			return getExistedSqlSessions().get(area_name);
		}
	}

可以开启一个线程一天(或12小时,其他固定时间段)运行一次CustomSqlSessionFactoryBuilder.buildSqlSessions()。

这个小项目中仍然使用了Spring不过是用作他途,真正的管理SqlSession主要代码如上,

拥有不错的扩展性与配置性。项目发布到服务器上,使用cron定期执行数据库操作。


One Week Has Gone, Good Bye, Readers! See You Next Post.....


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值