动态数据源3之动态分库反思

       看过我的关于动态分库的文章:http://blog.csdn.net/rainyspring4540/article/details/51828573

一定发现了 这种分库方式有个很要命的缺陷,吃性能!!!,由于本身我们项目特点,不会有太大的访问量,但在测试阶段,测试人员在产品上建了50多个库,虽然并发人数少,单这么多数据源都在内存里,性能可想而知。

       如果项目本身不会跨域的话,事实上有个不错的解决方案。

       根据上一篇文章的表结构设计,只要在创建项目库时的界面上加入IP、端口的设置,是允许同时连接不同ip的库的,即连接域不同,如果你们的所有项目库是在一个ip上,即都在一个服务器上,那么同域多数据源的问题是可以转化成一个数据源了。

       大家都知道,单纯的sql是可以在客户端执行类似于select * from dbA.tableA  a  inner join dbB.tableB b on a.id=b.id的同域跨库语句的

       那么jdbc实现的sql调用可以吗?hibernate框架也允许吗?springmvc封装的jdbcTemplate和HibernateTemplate也可以吗?必须可以!!!

       实践证明:虽然我们在配置jdbc链接时是明确指定了访问具体的库,但其实同一个ip的其他库也可以访问,而且可以进行复杂综合关联查询(这样就不必为了数据一致性来进行项目库和主库的数据反复同步)

       简单的jdbc和jdbcTemplate我就不写例子了,很简单,和普通的sql没啥区别,就是库名+.+表名就ok了

       下面我说下hibernateTemplate(因为我们项目是整合了springmvc4+hibernate4),所有用的是spring管理的hibernate

package com.fulong.construction.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * @author 
 * @date 2015-11-16
 * @description dba库中的国家表
 */
@Entity
@Table(name="tableCountry",catalog="dba")
public class Country2{

	@Id
	private String countryId;
	@Column
	private String countryName;
	
	
	public String getCountryId() {
		return countryId;
	}
	public void setCountryId(String countryId) {
		this.countryId = countryId;
	}
	public String getCountryName() {
		return countryName;
	}
	public void setCountryName(String countryName) {
		this.countryName = countryName;
	}
	
	
}
package com.fulong.construction.entity;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

/**
 * @author 
 * @date 2015-11-16
 * @description dbb库中的公司表
 */
@Entity
@Table(name = "tableCompany",catalog="dbb")
public class Company2 {

	@Id 
	private String companyId;// 公司id
	@Column
	private String companyName;// 公司名称
	
	@ManyToOne(targetEntity=Country2.class,fetch=FetchType.LAZY)
	@JoinColumn(name="countryId")
	private Country2 country;
	
	public String getCompanyId() {
		return companyId;
	}

	public void setCompanyId(String companyId) {
		this.companyId = companyId;
	}

	public String getCompanyName() {
		return companyName;
	}

	public void setCompanyName(String companyName) {
		this.companyName = companyName;
	}

	
	public Country2 getCountry() {
		return country;
	}

	public void setCountry(Country2 country) {
		this.country = country;
	}

	

}

查询:

List<Country2> list4 = session.createQuery("select b from Company2 c inner join c.country b where b.countryId='JPZ'").list();
			for(Country2 c:list4){
				System.out.println(c.getCountryId()+"--3--"+c.getCountryName());
			}
			System.out.println(list4.size());

通过给实体加入catalog属性来实现跨库综合查询没问题的  ^_^


反思上个项目:

根据刚刚的方法可以将上个项目的多数据源变成一个数据源,性能和稳定性(不必同步库间差异信息)都会更好,但有个问题:由于是动态数据源,会导致一个库一套bean实体文件(annotation方式)或多套实体配置文件(xml方式的实体),而动态创建hibernate实体并加载有些复杂,这里有个取巧的解决方式:


经过测试:在多数据源下,如果实体没有指定catalog属性,则当前的数据源是谁,那就是谁的实体,如果指定了catalog,则catalog的属性值即为实体永久的库名,忽略当前数据源

根据这么结论,实际上我们只需要配置2套bean就ok了,一套指定catalog为主库的名字,另一套不指定catalog,为当前切换到指定从库的库名,由于已经不存在从库与从库或  主库与从库的同步数据问题,故2套就ok了


提示:以上结论都指定测试用例上通过,并未真正用在项目上,毕竟已经完结的项目是不允许随意更改核心技术架构的,留着以后用吧

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值