spring+hibernate实现分库分表操作

分库的实现:


写一个动态的数据源类

public class DynamicDataSource extends AbstractRoutingDataSource {


@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
return DbContextHolder.getDbType();
}


}


public class DbContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();


public static void setDbType(String dbType) {
contextHolder.set(dbType);
}


public static String getDbType() {
String str = (String) contextHolder.get();
if (StringUtils.isEmpty(str))
str = "1";
return str;
}


public static void clearDbType() {
contextHolder.remove();
}
}


这里主要用到一个线程本地化,实现同一个线程中的数据传递,我的理解是:请求过来,controller->service->dao->datasource这是在同一个线程 里,而要想从controller传一个数据到datasource,所有可以使用threadLocal


配制如下:































class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">



${hibernate.dialect}
${hibernate.show_sql}





classpath:com/lin/domain




测试:

@Autowired
private StudentService studentService;
@RequestMapping("/add")
public @ResponseBody String add(String type){
if(type==null)type="default";
DbContextHolder.setDbType(type);
Student student=new Student();
student.setAge(10);
student.setName("fdf"+type);
studentService.save(student);
return type;
}


传一个type,定向到哪一个数据库,就可以了

分表的实现:

主要是使用了hibernate的拦截器


public class QueryResInterceptor extends EmptyInterceptor {
private static final long serialVersionUID = 8307241774485402107L;


private String viewName;
private String fix;


public QueryResInterceptor(String viewName,String fix) {// 写个构造方法,根据参数来确定是增删改查那张表
this.viewName = viewName;
this.fix=fix;
}


@Override
public String onPrepareStatement(String sql) {
//重写该方法,hibernate是封装了jdbc的,但他底层还是通过sql来操作的。
if(viewName.equals("order")){//只有order表才使用多表
sql = sql.replace(viewName,viewName+"_"+fix);
System.out.println("sql_______"+sql);
}
       return sql;
}


}

通过拦截器改变sq语句的表名 


dao层的实现如下:

@Override
public void saveOrder(Order order,String fix) {
//加一个难截器,实现多表插入
QueryResInterceptor interceptor = new QueryResInterceptor("order",fix);
Session session = this.getHibernateTemplate().getSessionFactory()
.openSession(interceptor);
session.save(order);
}


@Override
public List selectList(String fix) {
QueryResInterceptor interceptor=new QueryResInterceptor("order", fix);
Session session=this.getHibernateTemplate().getSessionFactory().openSession(interceptor);
List orders=session
.createQuery("select o from "+Order.class.getSimpleName()+" o")
.list();
return orders;
}


就这样就可以了


测试如下:

@Test
public void add(){
OrderService orderService=(OrderService)context.getBean("orderServiceImpl");
Order order=new Order();
order.setContent("jfkd");
String fix="4";//多表中的后缀
orderService.save(order,fix);
}

@Test
public void select(){
OrderService orderService=(OrderService)context.getBean("orderServiceImpl");
Listorders=orderService.selectList("2");
for (Order order : orders) {
System.out.println(order.getId());
}
}



你可能感兴趣的:(hibernate,spring,分表,分库)