spring mvc和spring4 mybatis 整合怎样算整合成功

三大数据库 mysqloraclesqlsever 更专业、更强悍、适合不同用户群体【新录针对本系统的视频教程,手把手教开发一个模块,快速掌握本系统】A 集成代码生成器(开发利器); 技术:增删改查的处理类,service层,mybatis的xml,SQL( mysql 和oracle)脚本, jsp页面 都生成就不用写搬砖的代码了,生成的放到项目里,可以直接运行B 集成阿里巴巴数据库连接池数据库连接池阿里巴巴的 druid。Druid在监控、可扩展性、稳定性和性能方面都有明显的优势C 集成安全权限框架Shiro 是一个用 Java 语言实现的框架,通过一个简单易用的 API 提供身份验证和授权,更安全,更可靠D 集成ehcache 分布式缓存;是一个纯Java的进程内缓存框架,具有快速、精干等特点,广泛使用的开源Java分布式缓存。E 集成微信接口开发;(后续加入Activiti5 工作流 )赠送一个jbpm工作流大型ERP系统(含OA、财务、分销)参考学习F websocket及时通讯技术;(即时聊天、及时站内信并声音提醒、实时在线管理、websocket及时刷新页面)G 图片爬虫技术;-------------------------------------------------------------------------------------------------------------------------1. 模块化、服务化,流程化,耦合度低、扩展性好,灵活度高,工具类封装完整,干净利索,调用简单方便2. 提供Rest服务,支持APP手机应用(android和ios)接口、php、.net、易语言、VB等第三方接口调用3. 全新高大尚HTML5+css3.0+bootstrap响应式开发界面UI,( 手机 PC 平板 截图在下面)、前沿.spring restful 风格4. 框架搭建完善成熟,在此基础上做过很多项目,系统具有并发处理、分布式、稳定性。5. 系统功能完善,此为框架平台,文档、注释齐全,提供技术支持,专门供二次开发6. 在此基础上可二次开发(OA、ERP、CRM ,医疗管理、金融、网站后台、APP后台、电子商务、商城(赠送UI)等等7.我们这边是公司,主要业务是定制开发,此系统为我们平时给客户做项目用的,经过很多项目实战考验-------------------------------------------------------------------------------------------------------------------------系统模块1. 权限管理:点开二级菜单进入三级菜单显示 角色(基础权限)和按钮权限角色(基础权限): 分角色组和角色,独立分配菜单权限和增删改查权限。按钮权限: 给角色分配按钮权限。2. 按钮管理:自定义按钮管理,维护按钮权限标识等3. 菜单管理:无限级别自定义菜单,自定义菜单图标,业务菜单和系统菜单分离,菜单状态显示隐藏(递归处理)4. 数据字典:无限级别,支持多级别无限分类。内设编号,排序等5. 组织机构:无限级别,公司or部门管理6. 在线管理:websocket技术,实时检测在线用户列表,统计在线人数,可强制用户下线同一用户只能在一个客户端登录7. 系统用户:对各个基本的用户增删改查,单发、群发站内信邮件短信,导入导出excel表格,批量删除8. 会员管理:对前台用户管理,分配会员级别,到期时间,状态,联系信息等资料9. 代码生成:生成完整的模块代码,并保留生成记录模版,可复用 (超强悍开发利器)10. 性能监控:监控整个系统的性能,SQL监控,SQL防火墙,URL监控,SPRING监控,SESSION监控等11. 接口测试:POST or GET 方式检测系统接口,参数加密,json返回结果,计算服务器响应时间12. 发送邮件:单发,群发邮件13. 置二维码:生成二维码图表保存到服务器 or解析读取二维码内信息14. 图表报表:柱状图、饼状图、折线图、各种图表大全15. 地图工具:打开地图, 鼠标点击地图某位置获取经纬度坐标,根据经纬度计算两点距离16. 打印测试:页面打印预览测试17. 图片管理:对批量上传的图片统一管理 ,点击放大,可打开多个,自由切换,绚丽预览效果18. 图片爬虫:输入某网址,爬出其图片显示在页面上,可以放大预览。可保存到服务器上,到图片管理里面19. 站内信:收信箱和发信箱, websocket技术通讯技术做的及时收信提醒,可配置语音提示来信20. 系统设置:修改系统名称,邮件服务器配置,短信账号设置,图片水印配置,微信配置21. 及时聊天:打开聊天窗口,可群聊、一对一聊天-------------------------------------------------------------------------------------------------------------------------菜单权限:分配给每个角色不同的菜单权限, 每个角色看到的菜单不同,无限级别菜单按钮权限:独立分配不同的角色不同的功能权限,增删改查权限分配具体到不同的菜单,自定义按钮管理支持多用户分权限管理后台,权限具体到不同的菜单不同的按钮--------------------------------------------------------------------------------------------------------------信息模块(小项目代码中)新闻管理:新闻的维护、发布、权重排序等 采用百度ueditor富文本框公告管理:公告的维护、发布广告管理:广告的维护、发布,状态维护,上传广告图片友情链接:友情链接的维护、状态维护特别推荐:特别推荐、状态维护微信模块(有指导视频花生壳本地IP映射操作)关注回复:微信用户关注公众号回复文本回复:匹配关键词进行文本回复图文回复:匹配关键词进行图文回复应用命令:匹配关键词进行命令操作,例如微信发送命令,执行服务器重启、关机、锁定等操作-------------------------------------------------------------------------------------------------------------------------技术点1. 导出 导入 excel 文件2导出word文件3. IO 流上传下载文件4. 群发邮件,可以发html、纯文本格式,可以发给任意邮箱(实现批量发送广告邮件)5. 群发or单独 发送短信,支持两种第三方短信商接口6. spring aop事物处理7. 代码生成器 (freemarker), 代码 zip 压缩打包8. MD5加密 SHA加密(登录密码用此加密)接口加密身份校验9. 数据库连接池阿里的 druid。Druid在监控、可扩展性、稳定性和性能方面都有明显的优势,支持并发10.加入安全框架 shiro (登录授权)(session管理)11.根据汉字 解析汉字的全拼(拼音)和首字母(导入excel到用户表,根据用户的汉字姓名生成拼音的用户名)12.app接口@ResponseBody(支持与其它语言数据交互)13.极光推送 (推送给APP及时消息,APP不启动也能收到)14.微信接口(身份验证,文本、图文回复等) 微信远程控制服务器重启、锁定、其它应用程序15.java Quartz 定时器 (定时执行某程序,精确到秒,可设置周期)16.java websocket 即时通讯技术,点对点,群聊,单聊17.新增Lucene全文检索18.Base64传输图片19.图片加水印(图片水印,文字水印)20.生成 or解析 二维码21.HTML5 + JAVAEEWebSocket 通信技术,WebSocket 验证用户登录,强制某用户下线22.批量异步上传图片,可预览,有进度条,支持拖拽上传(百度webuploader )。列表动态滑动放大展示。23.ehcache 自定义二级缓存 ,选择缓存存放目录,处理并发,增加系统性能24.服务器内部GET POST 请求25.uploadify 上传插件,单条、批量上传多线程,带进度条,异步,图片、视频, 其它文件格式均可上传26.地图选点获取经纬度坐标,根据俩经纬度计算距离27.tab标签页面功能,标签自由切换,不重复操作数据库28.站内信语音提醒,js控制音频播放29.百度富文本编辑器,可上传图片30.网页爬虫技术,可根据网页地址爬取图片和网页标题等信息(爬取某商城图片保存本服务器)-------------------------------------------------------------------------------------------------------------------------系统框架为:springmvc +spring+ mybaitsSSM 【 spring3.0 和 spring4.02mybaits 3.2】操作系统:windowslinux mac 等没有限制。 有 maven 和 javaee 版 jdk 1.6 1.7 1.8tomcat 6 7 8开发工具:myeclipseeclipse idea 均可, 没有限制数据库:oracle、msyql、sqlsever (2005及以上均支持)赠送 同UI springmvc + hibernateSpringSecurity Lucene Quartz MySQL、Oracle、SQL Server赠送 同UImaven 分模块项目 springmvc + mybatis系统演示视频:链接:/s/1gdN32Ht 密码:xh7w百度云 最新录的/programs/view/Qv1zuqAGWAA/土豆 最新录的登录界面背景用HTML5特效自动切换(百叶窗,幕布等多种切换方式)&就爱阅读网友整理上传,为您提供最全的知识大全,期待您的分享,转载请注明出处。
欢迎转载:
推荐:    springmvc+mybatis整合_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
springmvc+mybatis整合
上传于||文档简介
&&s​p​r​i​n​g​m​v​c​+​m​y​b​a​t​i​s​整​合
阅读已结束,如果下载本文需要使用1下载券
想免费下载本文?
定制HR最喜欢的简历
下载文档到电脑,查找使用更方便
还剩8页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢trackbacks-0
这里整合分别采用了Hibernate和MyBatis两大持久层框架,Hibernate主要完成增删改功能和一些单一的对象查询功能,MyBatis主要负责查询功能。所以在出来数据库方言的时候基本上没有什么问题,但唯一可能出现问题的就是在hibernate做添加操作生成主键策略的时候。因为我们都知道hibernate的数据库本地方言会针对不同的数据库采用不同的主键生成策略。 所以针对这一问题不得不采用自定义的主键生成策略,自己写一个主键生成器的表来维护主键生成方式或以及使用其他的方式来生成主键,从而避开利用hibernate默认提供的主键生成方式。 所以存在问题有:怎样动态的切换数据库方言? 这个问题还没有解决,没有更多时间来研究。不过想想应该可以配置两个SessionFactory来实现,那又存在怎么样动态切换SessionFactory呢?!需要解决这个问题才行,而这里则演示怎么样动态切换DataSource数据源的方法。 & 二、代码演示
在演示开始之前你的项目已经成功的整合完成的情况下才行,如果你还不知道怎么使用Spring整合MyBatis和Spring整合Hibernate的话。建议参考之前的文章:、这两篇文章结合起来就可以完成整合是几大框架了。这里重点介绍动态切换DataSource数据源的方法!
1、datasource的配置 applicationContext-datasource.xml
&?xml version="1.0" encoding="UTF-8"?&&beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd "&
&!-- 配置c3p0数据源 --&
&bean id="dataSourceOracle" class="com.mchange.boPooledDataSource" destroy-method="close"&
&property name="driverClass" value="${datasource.driver}"/&
&property name="jdbcUrl" value="${datasource.url}"/&
&property name="user" value="${datasource.username}"/&
&property name="password" value="${datasource.password}"/&
&property name="acquireIncrement" value="${c3p0.acquireIncrement}"/&
&property name="initialPoolSize" value="${c3p0.initialPoolSize}"/&
&property name="minPoolSize" value="${c3p0.minPoolSize}"/&
&property name="maxPoolSize" value="${c3p0.maxPoolSize}"/&
&property name="maxIdleTime" value="${c3p0.maxIdleTime}"/&
&property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/&
&property name="maxStatements" value="${c3p0.maxStatements}"/&
&property name="numHelperThreads" value="${c3p0.numHelperThreads}"/&
&property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/&
&property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/&
&bean id="dataSourceMySQL" class="com.mchange.boPooledDataSource" destroy-method="close"&
&property name="driverClass" value="com.mysql.jdbc.Driver"/&
&property name="jdbcUrl" value="jdbc:mysql://172.31.108.178:3306/world?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"/&
&property name="user" value="root"/&
&property name="password" value="jp2011"/&
&property name="acquireIncrement" value="${c3p0.acquireIncrement}"/&
&property name="initialPoolSize" value="${c3p0.initialPoolSize}"/&
&property name="minPoolSize" value="${c3p0.minPoolSize}"/&
&property name="maxPoolSize" value="${c3p0.maxPoolSize}"/&
&property name="maxIdleTime" value="${c3p0.maxIdleTime}"/&
&property name="idleConnectionTestPeriod" value="${c3p0.idleConnectionTestPeriod}"/&
&property name="maxStatements" value="${c3p0.maxStatements}"/&
&property name="numHelperThreads" value="${c3p0.numHelperThreads}"/&
&property name="preferredTestQuery" value="${c3p0.preferredTestQuery}"/&
&property name="testConnectionOnCheckout" value="${c3p0.testConnectionOnCheckout}"/&
&bean id="multipleDataSource" class="com.hoo.framework.spring.support.MultipleDataSource"&
&property name="defaultTargetDataSource" ref="dataSourceOracle"/&
&property name="targetDataSources"&
&!-- 注意这里的value是和上面的DataSource的id对应,key要和下面的CustomerContextHolder中的常量对应 --&
&entry value-ref="dataSourceOracle" key="oracleDataSource"/&
&entry value-ref="dataSourceMySQL" key="mySqlDataSource"/&
&/property&
&!-- Annotation 配置sessionFactory,配置数据库连接,注入hibernate数据库配置 --&
&bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"&
&property name="dataSource" ref="multipleDataSource"/&
&property name="packagesToScan" value="com.hoo.**.entity"/&
&property name="hibernateProperties"&
&!-- prop key="hibernate.dialect"&org.hibernate.dialect.OracleDialect&/prop--&
&!-- 链接释放策略 on_close | after_transaction | after_statement | auto
&prop key="hibernate.connection.release_mode"&after_transaction&/prop&
&prop key="hibernate.show_sql"&true&/prop&
&prop key="hibernate.format_sql"&true&/prop&
&!--prop key="hibernate.hbm2ddl.auto"&update&/prop--&
&/property&
&!-- property name="configLocation" value="classpath:hibernate.cfg.xml" /--&
&property name="namingStrategy"&
&bean class="com.hoo.framework.hibernate.PrefixedNamingStrategy" /&
&/property&
&!-- 事务管理器,注入sessionFactory
&bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"&
&property name="sessionFactory" ref="sessionFactory" /&
&!-- 配置事务的传播特性 --&
&tx:advice id="txAdvice" transaction-manager="transactionManager"&
&tx:attributes&
&tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="edit*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="remove*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="execute*" propagation="REQUIRED" rollback-for="java.lang.Exception"/&
&tx:method name="*" read-only="true" /&
&/tx:attributes&
&/tx:advice&
&!-- 配置那些类、方法纳入到事务的管理 --&
&aop:config&
&aop:pointcut expression="execution(* com.hoo.**.service.impl.*.*(..))" id="transactionManagerMethod"/&
&aop:advisor advice-ref="txAdvice" pointcut-ref="transactionManagerMethod" /&
&/aop:config&
&!-- 配置SqlSessionFactoryBean --&
&bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"&
&property name="dataSource" ref="multipleDataSource"/&
&property name="configLocation" value="classpath:mybatis.xml"/&
&!-- mapper和resultmap配置路径 --&
&property name="mapperLocations"&
&!-- 表示在com.hoo目录下的任意包下的resultmap包目录中,以-resultmap.xml或-mapper.xml结尾所有文件 --&
&value&classpath:com/hoo/framework/mybatis/mybatis-common.xml&/value&
&value&classpath:com/hoo/**/resultmap/*-resultmap.xml&/value&
&value&classpath:com/hoo/**/mapper/*-mapper.xml&/value&
&value&classpath:com/hoo/**/mapper/**/*-mapper.xml&/value&
&/property&
&!-- 通过扫描的模式,扫描目录在com/hoo/任意目录下的mapper目录下,所有的mapper都需要继承SqlMapper接口的接口 --&
&bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"&
&property name="basePackage" value="com.hoo.**.mapper"/&
&property name="markerInterface" value="com.hoo.framework.mybatis.SqlMapper"/&
&/bean&&/beans&
上面分配配置了Oracle和MySQL数据源,MultipleDataSource为自定义的DataSource,它是继承AbstractRoutingDataSource实现抽象方法即可。
2、MultipleDataSource实现AbstractRoutingDataSource抽象数据源中方法,定义CustomerContextHolder来动态切换数据源。代码如下:
package com.hoo.framework.spring.&import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataS&/** * &b&function:&/b& Spring
多数据源实现 * @author hoojo * @createDate
上午11:24:53 * @file MultipleDataSource.java * @package com.hoo.framework.spring.support * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */public class MultipleDataSource extends AbstractRoutingDataSource {&
@Override
protected Object determineCurrentLookupKey() {
return CustomerContextHolder.getCustomerType();
CustomerContextHolder
package com.hoo.framework.spring.&/** * &b&function:&/b& 多数据源 * @author hoojo * @createDate
上午11:36:57 * @file CustomerContextHolder.java * @package com.hoo.framework.spring.support * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */public abstract class CustomerContextHolder {&
public final static String DATA_SOURCE_ORACLE = "oracleDataSource";
public final static String DATA_SOURCE_MYSQL = "mySqlDataSource";
private static final ThreadLocal&String& contextHolder = new ThreadLocal&String&();
public static void setCustomerType(String customerType) {
contextHolder.set(customerType);
public static String getCustomerType() {
return contextHolder.get();
public static void clearCustomerType() {
contextHolder.remove();
其中,常量对应的applicationContext-datasource.xml中的multipleDataSource中的targetDataSource的key,这个很关键不要搞错了。
3、测试看能否切换数据源
package com.hoo.framework.service.&import org.junit.Timport org.junit.runner.RunWimport org.springframework.beans.factory.annotation.Aimport org.springframework.beans.factory.annotation.Qimport org.springframework.test.context.ContextCimport org.springframework.test.context.junit4.SpringJUnit4ClassR&import com.hoo.framework.dao.BaseDimport com.hoo.framework.log.ApplicationLimport com.hoo.framework.spring.support.CustomerContextH&&/** * &b&function:&/b&多数据源测试服务接口测试 * @author hoojo * @createDate
上午11:18:18 * @file MultipleDataSourceServiceImplTest.java * @package com.hoo.framework.service.impl * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */@ContextConfiguration({ "classpath:applicationContext-datasource.xml", "classpath:applicationContext-base.xml" })@RunWith(SpringJUnit4ClassRunner.class)public class MultipleDataSourceServiceImplTest extends ApplicationLogging {&
@Autowired
private BaseD
public void testDao() {
info(dao.toString());
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
info(dao.findBySql("select * from devicestate_tab where rownum & 2").toString());
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
info(dao.findBySql("select * from city limit 2").toString());
运行上面的测试用例后可以发现能查询到数据,如果我们注释掉其中的一项setCustomerType就会出现查询错误。在其中一个数据库没有找到对应的table。
至此,切换数据源也算成功了大半,剩下的就是如何在实际的业务中完成数据源的“动态”切换呢?!难道还是要像上面一样在每个方法上面写一个setCustomerType来手动控制数据源!答案是“当然不是”。我们用过Spring、hibernate后就会知道,先去使用hibernate的时候没有用spring,事务都是手动控制的。自从用了Spring大家都轻松了很多,事务交给了Spring来完成。所以到了这里你大概知道怎么做了,如果你还不知道~嘿嘿……(Spring那你就懂了个皮毛,最经典的部分你没有学到)
所以就是利用Spring的Aop进行切面编程,拦截器Interceptor在这里是一个很好的选择。它可以在方法之前或方法之后完成一些操作,而且控制的粒度可以细到具体的方法中的参数、返回值、方法名等。在这里控制数据源动态切换最好不过了!
4、上面是手动切换数据源,我们用Spring的Aop拦截器整个更自动化的方法来切换数据源。
Spring配置文件 applicationContext-base.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:aop="http://www.springframework.org/schema/aop"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd"&&
&context:component-scan base-package="com.hoo.**.dao.impl"/&
&context:component-scan base-package="com.hoo.**.service.impl"/&
&context:component-scan base-package="com.hoo.**.interceptor"/&
&!-- 启用Aop AspectJ注解 --&
&aop:aspectj-autoproxy/&
&!-- 注入配置文件 --&
&util:properties id="systemConfig" location="classpath:system.properties" /&
&!-- 启用表达式配置xml内容 --&
&bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&
&property name="propertiesArray"&
&util:list&
&util:properties location="classpath:system.properties"/&
&util:properties location="classpath:datasource.properties"/&
&/util:list&
&/property&
&!-- 配置一个拦截器对象,处理具体的切换数据源的业务 --&
&bean id="dataSourceMethodInterceptor" class="com.hoo.framework.spring.interceptor.DataSourceMethodInterceptor"/&
&!-- 参与动态切换数据源的切入点对象 (切入点对象,确定何时何地调用拦截器) --&
&bean id="methodCachePointCut" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"&
&!-- 配置缓存aop切面 --&
&property name="advice" ref="dataSourceMethodInterceptor" /&
&!-- 配置哪些方法参与缓存策略 --&
.表示符合任何单一字元
+表示符合前一个字元一次或多次
*表示符合前一个字元零次或多次
\Escape任何Regular expression使用到的符号
&!-- .*表示前面的前缀(包括包名) 表示print方法--&
&property name="patterns"&
&value&com.hoo.*.service.impl.*Service*\.*.*&/value&
&value&com.hoo.*.mapper.*Mapper*\.*.*&/value&
&/property&
&/bean&&/beans&
上面的拦截器是拦截Service和Mapper的Java对象中的执行方法,所有在service.impl包下的ServiceImpl和mapper包下的Mapper接口将会被DataSourceMethodInterceptor拦截到,并通过其中的规律动态设置数据源。
3、拦截器DataSourceMethodInterceptor.java拦截具体的业务,并通过业务代码中的方法和接口、实现类的规律进行动态设置数据源
package com.hoo.framework.spring.&import java.lang.reflect.Pimport org.aopalliance.intercept.MethodIimport org.aopalliance.intercept.MethodIimport mons.lang.ClassUimport org.springframework.beans.factory.InitializingBimport com.hoo.framework.log.ApplicationLimport com.hoo.framework.spring.support.CustomerContextH&/** * &b&function:&/b& 动态设置数据源拦截器 * @author hoojo * @createDate
下午02:00:13 * @file DataSourceMethodInterceptor.java * @package com.hoo.framework.spring.interceptor * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */public class DataSourceMethodInterceptor extends ApplicationLogging implements MethodInterceptor, InitializingBean {&
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Class&?& clazz = invocation.getThis().getClass();
String className = clazz.getName();
if (ClassUtils.isAssignable(clazz, Proxy.class)) {
className = invocation.getMethod().getDeclaringClass().getName();
String methodName = invocation.getMethod().getName();
Object[] arguments = invocation.getArguments();
trace("execute {}.{}({})", className, methodName, arguments);
if (className.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (className.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
} else if (methodName.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (methodName.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
CustomerContextHolder.clearCustomerType();
if (className.contains("MySQL") || methodName.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (className.contains("Oracle") || methodName.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
CustomerContextHolder.clearCustomerType();
Object result = invocation.proceed();
@Override
public void afterPropertiesSet() throws Exception {
log.trace("afterPropertiesSet……");
上面的代码是在接口或实现中如果出现MySQL就设置数据源为DATA_SOURCE_MYSQL,如果有Oracle就切换成DATA_SOURCE_ORACLE数据源。
4、编写实际的业务接口和实现来测试拦截器是否有效
MultipleDataSourceService 接口
package com.hoo.server.datasource.&&/** * &b&function:&/b& 多数据源测试服务接口 * @author hoojo * @createDate
上午11:07:31 * @file MultipleDataSourceService.java * @package com.hoo.server.datasource.service * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */public interface MultipleDataSourceService {
public void execute4MySQL() throws E
public void execute4Oracle() throws E}
package com.hoo.server.datasource.service.&import org.springframework.beans.factory.annotation.Aimport org.springframework.stereotype.S&import com.hoo.framework.dao.BaseDimport com.hoo.framework.service.impl.AbstractSimport com.hoo.server.datasource.service.MultipleDataSourceS&/** * &b&function:&/b& 多数据源测试服务接口实现 * @author hoojo * @createDate
上午11:09:54 * @file MultipleDataSourceServiceImpl.java * @package com.hoo.server.datasource.service.impl * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */@Servicepublic class MultipleDataSourceServiceImpl extends AbstractService implements MultipleDataSourceService {
@Autowired
private BaseD
@Override
public void execute4MySQL() throws Exception {
info(dao.findBySql("select * from city limit 2").toString());
@Override
public void execute4Oracle() throws Exception {
info(dao.findBySql("select * from devicestate_tab where rownum & 2").toString());
测试上面的服务层代码,看看能否利用拦截器实现数据源动态切换
在上面的MultipleDataSourceServiceImplTest中加入如下代码
@Autowired@Qualifier("multipleDataSourceServiceImpl")private MultipleDataSourceS&@Testpublic void testService() {
service.execute4MySQL();
service.execute4Oracle();
} catch (Exception e) {
e.printStackTrace();
运行上面的代码后可以看到能够成功查询到结果
5、测试实现类带Oracle或MySQL字符串的
package com.hoo.server.datasource.service.&import org.springframework.beans.factory.annotation.Aimport org.springframework.stereotype.Simport com.hoo.framework.dao.BaseDimport com.hoo.framework.service.impl.AbstractSimport com.hoo.server.datasource.service.MultipleDataSourceS&/** * &b&function:&/b& 多数据源测试服务接口实现 * @author hoojo * @createDate
上午11:09:54 * @file MultipleDataSourceServiceImpl.java * @package com.hoo.server.datasource.service.impl * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */@Servicepublic class MySQLDataSourceServiceImpl extends AbstractService implements MultipleDataSourceService {
@Autowired
private BaseD
@Override
public void execute4MySQL() throws Exception {
info(dao.findBySql("select * from city limit 2").toString());
@Override
public void execute4Oracle() throws Exception {
info(dao.findBySql("select * from devicestate_tab where rownum & 2").toString());
package com.hoo.server.datasource.service.&import org.springframework.beans.factory.annotation.Aimport org.springframework.stereotype.Simport com.hoo.framework.dao.BaseDimport com.hoo.framework.service.impl.AbstractSimport com.hoo.server.datasource.service.MultipleDataSourceS&/** * &b&function:&/b& 多数据源测试服务接口实现 * @author hoojo * @createDate
上午11:09:54 * @file MultipleDataSourceServiceImpl.java * @package com.hoo.server.datasource.service.impl * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */@Servicepublic class OracleDataSourceServiceImpl extends AbstractService implements MultipleDataSourceService {
@Autowired
private BaseD
@Override
public void execute4MySQL() throws Exception {
info(dao.findBySql("select * from city limit 2").toString());
@Override
public void execute4Oracle() throws Exception {
info(dao.findBySql("select * from devicestate_tab where rownum & 2").toString());
这里的两个实现类的类名都含有不同规则的数据源标识符字符串,而且方法名也含有相关字符串,这些都匹配拦截器中的规则。
在MultipleDataSourceServiceImplTest 中加入测试代码
@Autowired@Qualifier("oracleDataSourceServiceImpl")private MultipleDataSourceService oracleS&@Autowired@Qualifier("mySQLDataSourceServiceImpl")private MultipleDataSourceService mySQLS&@Testpublic void testOracleService() {
oracleService.execute4MySQL();
} catch (Exception e1) {
e1.printStackTrace();
oracleService.execute4Oracle();
} catch (Exception e) {
e.printStackTrace();
}}&@Testpublic void testMySQLService() {
mySQLService.execute4MySQL();
} catch (Exception e1) {
e1.printStackTrace();
mySQLService.execute4Oracle();
} catch (Exception e) {
e.printStackTrace();
执行上面的测试用例会发现有一个查询会失败,那是因为我们按照拦截器中的业务规则切换数据源就匹配到了其中一个,就是通过类名进行数据源切换,所以只定位到其中一个数据源。
6、测试MyBatis的数据源切换方法
MyBatis的查询接口
package com.hoo.server.datasource.&import java.util.Limport java.util.M&import com.hoo.framework.mybatis.SqlM&/** * &b&function:&/b& MyBatis 多数据源 测试查询接口 * @author hoojo * @createDate
下午04:18:08 * @file MultipleDataSourceMapper.java * @package com.hoo.server.datasource.mapper * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */public interface MultipleDataSourceMapper extends SqlMapper {&
public List&Map&String, Object&& execute4MySQL() throws E
public List&Map&String, Object&& execute4Oracle() throws E}
multiple-datasource-mapper.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.hoo.server.datasource.mapper.MultipleDataSourceMapper"&
&select id="execute4Oracle" resultType="map"&
deviceInfo_tab t where rownum & 10
&select id="execute4MySQL" resultType="map"&
city limit 2
&/select&&/mapper&
测试MyBatis的mapper查询接口,在MultipleDataSourceServiceImplTest加入以下代码
@Autowiredprivate MultipleDataSourceM&@Testpublic void testMapper() {
trace(mapper.execute4MySQL());
} catch (Exception e1) {
e1.printStackTrace();
trace(mapper.execute4Oracle());
} catch (Exception e) {
e.printStackTrace();
运行以上测试代码也能发现可以正常的查询到Oracle和MySQL数据库中的数据。MyBatis的在这里只负责查询,而增删改是hibernate完成的任务,所以这里也就不再测试modified部分。
7、上面的拦截器是需要在配置文件中进行配置的,这里利用annotation的配置的拦截器进行业务拦截,也许有些人更喜欢用annotation
package com.hoo.framework.spring.&import java.lang.reflect.Pimport mons.lang.ClassUimport org.aspectj.lang.JoinPimport org.aspectj.lang.annotation.Aimport org.aspectj.lang.annotation.Bimport org.import com.hoo.framework.log.ApplicationLimport com.hoo.framework.spring.support.CustomerContextH&/** * &b&function:&/b& 多数据源动态配置拦截器 * @author hoojo * @createDate
上午11:35:54 * @file MultipleDataSourceInterceptor.java * @package com.hoo.framework.spring.interceptor * @project SHMB * @blog http://blog.csdn.net/IBM_hoojo * @email hoojo_&# * @version 1.0 */@Component@Aspectpublic class MultipleDataSourceInterceptor extends ApplicationLogging {&
* &b&function:&/b& 动态设置数据源
* @author hoojo
* @createDate
上午11:38:45
* @throws Exception
@Before("execution(* com.hoo..service.impl.*ServiceImpl.*(..)) || execution(* com.hoo..mapper.*Mapper.*(..))")
public void dynamicSetDataSoruce(JoinPoint joinPoint) throws Exception {
Class&?& clazz = joinPoint.getTarget().getClass();
String className = clazz.getName();
if (ClassUtils.isAssignable(clazz, Proxy.class)) {
className = joinPoint.getSignature().getDeclaringTypeName();
String methodName = joinPoint.getSignature().getName();
Object[] arguments = joinPoint.getArgs();
trace("execute {}.{}({})", className, methodName, arguments);
if (className.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (className.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
} else if (methodName.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (methodName.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
CustomerContextHolder.clearCustomerType();
if (className.contains("MySQL") || methodName.contains("MySQL")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_MYSQL);
} else if (className.contains("Oracle") || methodName.contains("Oracle")) {
CustomerContextHolder.setCustomerType(CustomerContextHolder.DATA_SOURCE_ORACLE);
CustomerContextHolder.clearCustomerType();
这种拦截器就是不需要在配置文件中加入任何配置进行拦截,算是一种扩展的方法。
多数据源动态切换的主要地方在于我们要定义一个自己的数据源来实现AbstractRoutingDataSource中的determineCurrentLookupKey方法,然后通过CustomerContextHolder来实现数据源的切换工作。而数据源的动态切换也就在于我们利用了Spring的Aop中的拦截器Interceptor进行业务类的方法进行拦截,通过类名或方法名中的有效字符串来动态切换到我们定义好的规则对应的数据源。
阅读(9363)
、 、 、 、
&re: Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法[未登录]
在一个事务中如何切换呢?&&&&&&
&re: Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
支持博主&&&&&&
&re: Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
@python下一篇文章解决了&&&&&&
&re: Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法[未登录]
这个是全局的吧?多个用户使用的情况下,一个用户切换了,就把其他用户都给切换了&&&&&&
&re: Spring3.3 整合 Hibernate3、MyBatis3.2 配置多数据源/动态切换数据源 方法
com.hoo.framework.mybatis.SqlMapper这个类贴一下呢&&&&&&
hoojo 所有文章遵循,要求署名、非商业、保持一致。在满足的基础上可以转载,但请以超链接形式注明出处。
2013年10月
2930123456789101113141516171920212324252627282930123456789
随笔分类(210)
随笔档案(60)
积分与排名
阅读排行榜
评论排行榜

我要回帖

更多关于 spring与mybatis整合 的文章

 

随机推荐