spring+mybatis多数据源(数据库主从)实例

来源:互联网 发布:投稿系统 php 编辑:程序博客网 时间:2024/06/03 20:16

项目中用的的,展示给大家,结构如下


applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd    http://www.springframework.org/schema/aop            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"><description>Spring公共配置 </description><!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 --><context:component-scan base-package="com.test"></context:component-scan><aop:aspectj-autoproxy proxy-target-class="true" /><beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><value>classpath:app.properties</value></property></bean><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dynamicDataSource" /></bean><!-- 使用annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager"proxy-target-class="true" /><!-- MyBatis配置 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="typeAliasesPackage" value="com.test.model" /><property name="mapperLocations" value="classpath*:/mybatis/*Mapper.xml" /><property name="dataSource"><ref bean="dynamicDataSource" /></property></bean><!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.test.dao.mybatis" /><!-- <property name="annotationClass" value="jarlun.framework.core.base.mybatis.MyBatisRepository" /> --></bean><bean id="dynamicDataSource" class="com.test.holder.DynamicDataSource"><!-- 通过key-value的形式来关联数据源 --><property name="targetDataSources"><map key-type ="java.lang.String"><entry value-ref="master" key="master"></entry><entry value-ref="slave" key="slave"></entry></map></property><property name="defaultTargetDataSource" ref="master" /></bean><!-- JSR303 Validator定义 --><!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册 --><!-- 建立视图内拦截器来解决JPA中访问延迟加载属性时产生的无会话异常 LazyInitializationException: could not initialize proxy no session --><!-- 此拦截器会注入到servlet配置中的DefaultAnnotationHandlerMapping中 --><bean id="master" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="${master.jdbc.driver}" /><property name="url" value="${master.jdbc.url}" /><property name="username" value="${master.jdbc.username}" /><property name="password" value="${master.jdbc.password}" /><!-- Connection Pooling Info --><property name="maxActive" value="${master.jdbc.pool.maxActive}" /><property name="maxIdle" value="${master.jdbc.pool.maxIdle}" /><property name="initialSize" value="${master.jdbc.pool.initialSize}" /><property name="defaultAutoCommit" value="false" /><!-- 连接Idle一个小时后超时 --><property name="timeBetweenEvictionRunsMillis" value="3600000" /><property name="minEvictableIdleTimeMillis" value="3600000" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="true" /><property name="testOnReturn" value="false" /><property name="validationQuery" value="SELECT 1" /><property name="logAbandoned" value="false" /><property name="removeAbandoned" value="true" /><property name="removeAbandonedTimeout" value="60" /></bean><bean id="slave" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="${slave.jdbc.driver}" /><property name="url" value="${slave.jdbc.url}" /><property name="username" value="${slave.jdbc.username}" /><property name="password" value="${slave.jdbc.password}" /><!-- Connection Pooling Info --><property name="maxActive" value="${slave.jdbc.pool.maxActive}" /><property name="maxIdle" value="${slave.jdbc.pool.maxIdle}" /><property name="initialSize" value="${slave.jdbc.pool.initialSize}" /><property name="defaultAutoCommit" value="false" /><!-- 连接Idle一个小时后超时 --><property name="timeBetweenEvictionRunsMillis" value="3600000" /><property name="minEvictableIdleTimeMillis" value="3600000" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="true" /><property name="testOnReturn" value="false" /><property name="validationQuery" value="SELECT 1" /><property name="logAbandoned" value="false" /><property name="removeAbandoned" value="true" /><property name="removeAbandonedTimeout" value="60" /></bean></beans>

app.properties

master.jdbc.driver=com.mysql.jdbc.Drivermaster.jdbc.url=jdbc:mysql://120.25.155.55:3306/testmaster.jdbc.username=testmaster.jdbc.password=!QAZxsw2master.jdbc.pool.maxActive=60master.jdbc.pool.maxIdle=20master.jdbc.pool.initialSize=10slave.jdbc.driver=com.mysql.jdbc.Driverslave.jdbc.url=jdbc:mysql://localhost:3306/test?useUnicode=trueslave.jdbc.username=rootslave.jdbc.password=slave.jdbc.pool.maxActive=60slave.jdbc.pool.maxIdle=20slave.jdbc.pool.initialSize=10

DynamicDataSource.java

package com.test.holder;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource{        @Override      protected Object determineCurrentLookupKey() {          return DBContextHolder.getDBType();      }  }  

DBContextHolder.java

package com.test.holder;public class DBContextHolder {          private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();            public static void setDBType(String dbType) {          contextHolder.set(dbType);      }            public static String getDBType() {          return contextHolder.get();      }            public static void clearDBType() {          contextHolder.remove();  }}

DataSource.java

package com.test.holder;import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.METHOD)@Documentedpublic @interface DataSource {Source value() default Source.master;}

Source.java

package com.test.holder;public enum Source {/* 主库 */master, /* 从库 */slave}
UserMapper.java

package com.test.dao.mybatis;import org.apache.ibatis.annotations.Param;import com.test.model.UserModel;public interface UserMapper {UserModel findByUserId(@Param("userId")Long userId);}

UserModel.java

package com.test.model;public class UserModel {private long id;private String nickname;public long getId() {return id;}public void setId(long id) {this.id = id;}public String getNickname() {return nickname;}public void setNickname(String nickname) {this.nickname = nickname;}}

UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>    <!DOCTYPE mapper        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"        "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.test.dao.mybatis.UserMapper"><resultMap  id="userModel"  type="com.test.model.UserModel" ><result property="id" column="id" /><result property="nickname" column="nickname" />    </resultMap>    <select id="findByUserId"  resultMap="userModel" > select id , nickname from db_user where id=#{userId}</select></mapper>  


UserService.java

package com.test.service;import com.test.model.UserModel;public interface UserService { UserModel findByMasterUserId(long userId); UserModel findBySlaveUserId(long userId);}

UserServiceImpl.java

package com.test.service.impl;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Transactional;import com.test.dao.mybatis.UserMapper;import com.test.holder.DataSource;import com.test.holder.Source;import com.test.model.UserModel;import com.test.service.UserService;@Service("userServiceImpl")public class UserServiceImpl implements UserService{@Autowiredprivate UserMapper userMapper;@Transactional(rollbackFor={Exception.class})@DataSource(value=Source.master)public UserModel findByMasterUserId(long userId){return this.userMapper.findByUserId(userId);}@Transactional(rollbackFor={Exception.class})@DataSource(value=Source.slave)public UserModel findBySlaveUserId(long userId){return this.userMapper.findByUserId(userId);}}

aop拦截

DataSourceContextAop.java

package com.test.aop;import java.lang.reflect.Method;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.core.annotation.Order;import org.springframework.stereotype.Component;import com.test.holder.DBContextHolder;import com.test.holder.DataSource;@Aspect@Order(value=1)@Componentpublic class DataSourceContextAop {@Around("execution(@com.test.holder.DataSource * com.test.service.impl.*.*(..))")public Object setDynamicDataSource(ProceedingJoinPoint pjp) throws Throwable {Method method = this.getMethod(pjp);DataSource dataSource = method.getAnnotation(DataSource.class);if (dataSource != null) {DBContextHolder.setDBType(dataSource.value().name());}return pjp.proceed();}public Method getMethod(JoinPoint pjp) {Method method = null;MethodSignature signature = (MethodSignature) pjp.getSignature();method = signature.getMethod();return method;}}

最后测试

Test.java

package test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.test.service.UserService;public class Test {public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");       UserService userService = (UserService) ac.getBean("userServiceImpl");       System.out.println(userService.findByMasterUserId(1000001).getNickname());       System.out.println(userService.findBySlaveUserId(1000001).getNickname());  }}

谢谢

而外加个hibernate和mybatis混用的配置

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd    http://www.springframework.org/schema/aop            http://www.springframework.org/schema/aop/spring-aop-3.0.xsd          http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"><description>Spring公共配置 </description><!-- 使用annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入 --><context:component-scan base-package="com.test"></context:component-scan><aop:aspectj-autoproxy proxy-target-class="true" /><beanclass="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><value>classpath:app.properties</value></property></bean><bean id="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dynamicDataSource" /></bean><!-- Jpa Entity Manager 配置 --><bean id="entityManagerFactory"class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><property name="dataSource" ref="dynamicDataSource" /><property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" /><property name="packagesToScan" value="com.test.entity" /><property name="jpaProperties"><props><!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop><prop key="net.sf.ehcache.configurationResourceName">ehcache/ehcache-hibernate.xml</prop> --><!-- 命名规则 My_NAME->MyName --><prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop><prop key="hibernate.show_sql">${hibernate.show_sql}</prop></props></property></bean><bean id="hibernateJpaVendorAdapter"class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"><property name="databasePlatform"><bean factory-method="getDialect"class="org.springside.modules.persistence.Hibernates"><constructor-arg ref="dynamicDataSource" /></bean></property></bean><!-- 使用annotation定义事务 --><tx:annotation-driven transaction-manager="transactionManager"proxy-target-class="true" /><!-- MyBatis配置 自动扫描entity目录, 省掉Configuration.xml里的手工配置 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><property name="typeAliasesPackage" value="com.test.model" /><property name="mapperLocations" value="classpath*:/mybatis/*Mapper.xml" /><property name="dataSource"><ref bean="dynamicDataSource" /></property></bean><!-- 扫描basePackage下所有以@MyBatisRepository标识的 接口 --><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.test.dao.mybatis" /><!-- <property name="annotationClass" value="jarlun.framework.core.base.mybatis.MyBatisRepository" /> --></bean><bean id="dynamicDataSource" class="com.test.holder.DynamicDataSource"><!-- 通过key-value的形式来关联数据源 --><property name="targetDataSources"><map key-type ="java.lang.String"><entry value-ref="master" key="master"></entry><entry value-ref="slave" key="slave"></entry></map></property><property name="defaultTargetDataSource" ref="master" /></bean><!-- JSR303 Validator定义 --><!-- 以下 validator ConversionService 在使用 mvc:annotation-driven 会 自动注册 --><!-- 建立视图内拦截器来解决JPA中访问延迟加载属性时产生的无会话异常 LazyInitializationException: could not initialize proxy no session --><!-- 此拦截器会注入到servlet配置中的DefaultAnnotationHandlerMapping中 --><bean id="master" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="${master.jdbc.driver}" /><property name="url" value="${master.jdbc.url}" /><property name="username" value="${master.jdbc.username}" /><property name="password" value="${master.jdbc.password}" /><!-- Connection Pooling Info --><property name="maxActive" value="${master.jdbc.pool.maxActive}" /><property name="maxIdle" value="${master.jdbc.pool.maxIdle}" /><property name="initialSize" value="${master.jdbc.pool.initialSize}" /><property name="defaultAutoCommit" value="false" /><!-- 连接Idle一个小时后超时 --><property name="timeBetweenEvictionRunsMillis" value="3600000" /><property name="minEvictableIdleTimeMillis" value="3600000" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="true" /><property name="testOnReturn" value="false" /><property name="validationQuery" value="SELECT 1" /><property name="logAbandoned" value="false" /><property name="removeAbandoned" value="true" /><property name="removeAbandonedTimeout" value="60" /></bean><bean id="slave" class="org.apache.commons.dbcp.BasicDataSource"destroy-method="close"><!-- Connection Info --><property name="driverClassName" value="${slave.jdbc.driver}" /><property name="url" value="${slave.jdbc.url}" /><property name="username" value="${slave.jdbc.username}" /><property name="password" value="${slave.jdbc.password}" /><!-- Connection Pooling Info --><property name="maxActive" value="${slave.jdbc.pool.maxActive}" /><property name="maxIdle" value="${slave.jdbc.pool.maxIdle}" /><property name="initialSize" value="${slave.jdbc.pool.initialSize}" /><property name="defaultAutoCommit" value="false" /><!-- 连接Idle一个小时后超时 --><property name="timeBetweenEvictionRunsMillis" value="3600000" /><property name="minEvictableIdleTimeMillis" value="3600000" /><property name="testWhileIdle" value="true" /><property name="testOnBorrow" value="true" /><property name="testOnReturn" value="false" /><property name="validationQuery" value="SELECT 1" /><property name="logAbandoned" value="false" /><property name="removeAbandoned" value="true" /><property name="removeAbandonedTimeout" value="60" /></bean></beans>


1 0
原创粉丝点击