最近用到了MyBatis配置多數(shù)據(jù)源,原以為簡單配置下就行了,實際操作后發(fā)現(xiàn)還是要費些事的,這里記錄下,以作備忘
不多廢話,直接上代碼,后面會有簡單的實現(xiàn)介紹
jdbc和log4j的配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
#定義輸出格式 ConversionPattern=%d %-5p [%t] %c - %m%n log4j.rootLogger=DEBUG,Console log4j.logger.com.cnblogs.lzrabbit=DEBUG log4j.logger.org.springframework=ERROR log4j.logger.org.mybatis=ERROR log4j.logger.org.apache.ibatis=ERROR log4j.logger.org.quartz=ERROR log4j.logger.org.apache.axis2=ERROR log4j.logger.org.apache.axiom=ERROR log4j.logger.org.apache=ERROR log4j.logger.httpclient=ERROR #log4j.additivity.org.springframework=false #Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.Threshold=DEBUG log4j.appender.Console.Target=System.out log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=${ConversionPattern} #log4j.appender.Console.encoding=UTF-8 #org.apache.log4j.DailyRollingFileAppender log4j.appender.DailyFile=org.apache.log4j.DailyRollingFileAppender log4j.appender.DailyFile.DatePattern= '.' yyyy-MM- dd '.log' log4j.appender.DailyFile.File=${myApp.root} /logs/daily .log log4j.appender.DailyFile.Append= true log4j.appender.DailyFile.Threshold=DEBUG log4j.appender.DailyFile.layout=org.apache.log4j.PatternLayout log4j.appender.DailyFile.layout.ConversionPattern=${ConversionPattern} log4j.appender.DailyFile.encoding=UTF-8 # %c 輸出日志信息所屬的類的全名 # %d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss},輸出類似:2002-10-18- 22:10:28 # %f 輸出日志信息所屬的類的類名 # %l 輸出日志事件的發(fā)生位置,即輸出日志信息的語句處于它所在的類的第幾行 # %m 輸出代碼中指定的信息,如log(message)中的message # %n 輸出一個回車換行符,Windows平臺為“rn”,Unix平臺為“n” # %p 輸出優(yōu)先級,即DEBUG,INFO,WARN,ERROR,F(xiàn)ATAL。如果是調(diào)用debug()輸出的,則為DEBUG,依此類推 # %r 輸出自應(yīng)用啟動到輸出該日志信息所耗費的毫秒數(shù) # %t 輸出產(chǎn)生該日志事件的線程名 |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
#============================================================================ # MySQL #============================================================================ jdbc.mysql.driver=com.mysql.jdbc.Driver jdbc.mysql.url=jdbc:mysql: //127 .0.0.1:3306 /test ?useUnicode= true &characterEncoding=UTF-8&allowMultiQueries= true jdbc.mysql.username=root jdbc.mysql.password=root #============================================================================ # MS SQL Server #============================================================================ #jdbc.sqlserver.driver=com.microsoft.sqlserver.jdbc.SQLServerDriver #jdbc.sqlserver.url=jdbc:sqlserver://127.0.0.1:1433;database=test; #jdbc.sqlserver.username=sa #jdbc.sqlserver.password=sa #============================================================================ # MS SQL Server (JTDS) #============================================================================ jdbc.sqlserver.driver=net.sourceforge.jtds.jdbc.Driver jdbc.sqlserver.url=jdbc:jtds:sqlserver: //127 .0.0.1:1433 /test jdbc.sqlserver.username=sa jdbc.sqlserver.password=sa #============================================================================ # 通用配置 #============================================================================ jdbc.initialSize=5 jdbc.minIdle=5 jdbc.maxIdle=20 jdbc.maxActive=100 jdbc.maxWait=100000 jdbc.defaultAutoCommit= false jdbc.removeAbandoned= true jdbc.removeAbandonedTimeout=600 jdbc.testWhileIdle= true jdbc.timeBetweenEvictionRunsMillis=60000 jdbc.numTestsPerEvictionRun=20 jdbc.minEvictableIdleTimeMillis=300000 |
單數(shù)據(jù)源時的Spring配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<? 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:aop = "http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> < bean id = "propertyConfigurer" class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > < property name = "location" value = "classpath:jdbc.properties" /> </ bean > < bean id = "dataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" > < property name = "driverClassName" value = "${jdbc.mysql.driver}" /> < property name = "url" value = "${jdbc.mysql.url}" /> < property name = "username" value = "${jdbc.mysql.username}" /> < property name = "password" value = "${jdbc.mysql.password}" /> < property name = "initialSize" value = "${jdbc.initialSize}" /> < property name = "minIdle" value = "${jdbc.minIdle}" /> < property name = "maxIdle" value = "${jdbc.maxIdle}" /> < property name = "maxActive" value = "${jdbc.maxActive}" /> < property name = "maxWait" value = "${jdbc.maxWait}" /> < property name = "defaultAutoCommit" value = "${jdbc.defaultAutoCommit}" /> < property name = "removeAbandoned" value = "${jdbc.removeAbandoned}" /> < property name = "removeAbandonedTimeout" value = "${jdbc.removeAbandonedTimeout}" /> < property name = "testWhileIdle" value = "${jdbc.testWhileIdle}" /> < property name = "timeBetweenEvictionRunsMillis" value = "${jdbc.timeBetweenEvictionRunsMillis}" /> < property name = "numTestsPerEvictionRun" value = "${jdbc.numTestsPerEvictionRun}" /> < property name = "minEvictableIdleTimeMillis" value = "${jdbc.minEvictableIdleTimeMillis}" /> </ bean > < bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > < property name = "dataSource" ref = "dataSource" /> </ bean > <!-- mybatis.spring自動映射 --> < bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" > < property name = "basePackage" value = "com.cnblogs.lzrabbit" /> </ bean > <!-- 自動掃描,多個包以 逗號分隔 --> < context:component-scan base-package = "com.cnblogs.lzrabbit" /> < aop:aspectj-autoproxy /> </ beans > |
多數(shù)據(jù)源時Spring配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
|
<? 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:aop = "http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> < bean id = "propertyConfigurer" class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > < property name = "location" value = "classpath:jdbc.properties" /> </ bean > < bean id = "sqlServerDataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" > < property name = "driverClassName" value = "${jdbc.sqlserver.driver}" /> < property name = "url" value = "${jdbc.sqlserver.url}" /> < property name = "username" value = "${jdbc.sqlserver.username}" /> < property name = "password" value = "${jdbc.sqlserver.password}" /> < property name = "initialSize" value = "${jdbc.initialSize}" /> < property name = "minIdle" value = "${jdbc.minIdle}" /> < property name = "maxIdle" value = "${jdbc.maxIdle}" /> < property name = "maxActive" value = "${jdbc.maxActive}" /> < property name = "maxWait" value = "${jdbc.maxWait}" /> < property name = "defaultAutoCommit" value = "${jdbc.defaultAutoCommit}" /> < property name = "removeAbandoned" value = "${jdbc.removeAbandoned}" /> < property name = "removeAbandonedTimeout" value = "${jdbc.removeAbandonedTimeout}" /> < property name = "testWhileIdle" value = "${jdbc.testWhileIdle}" /> < property name = "timeBetweenEvictionRunsMillis" value = "${jdbc.timeBetweenEvictionRunsMillis}" /> < property name = "numTestsPerEvictionRun" value = "${jdbc.numTestsPerEvictionRun}" /> < property name = "minEvictableIdleTimeMillis" value = "${jdbc.minEvictableIdleTimeMillis}" /> </ bean > < bean id = "mySqlDataSource" class = "org.apache.commons.dbcp.BasicDataSource" destroy-method = "close" > < property name = "driverClassName" value = "${jdbc.mysql.driver}" /> < property name = "url" value = "${jdbc.mysql.url}" /> < property name = "username" value = "${jdbc.mysql.username}" /> < property name = "password" value = "${jdbc.mysql.password}" /> < property name = "initialSize" value = "${jdbc.initialSize}" /> < property name = "minIdle" value = "${jdbc.minIdle}" /> < property name = "maxIdle" value = "${jdbc.maxIdle}" /> < property name = "maxActive" value = "${jdbc.maxActive}" /> < property name = "maxWait" value = "${jdbc.maxWait}" /> < property name = "defaultAutoCommit" value = "${jdbc.defaultAutoCommit}" /> < property name = "removeAbandoned" value = "${jdbc.removeAbandoned}" /> < property name = "removeAbandonedTimeout" value = "${jdbc.removeAbandonedTimeout}" /> < property name = "testWhileIdle" value = "${jdbc.testWhileIdle}" /> < property name = "timeBetweenEvictionRunsMillis" value = "${jdbc.timeBetweenEvictionRunsMillis}" /> < property name = "numTestsPerEvictionRun" value = "${jdbc.numTestsPerEvictionRun}" /> < property name = "minEvictableIdleTimeMillis" value = "${jdbc.minEvictableIdleTimeMillis}" /> </ bean > < bean id = "multipleDataSource" class = "com.cnblogs.lzrabbit.MultipleDataSource" > < property name = "defaultTargetDataSource" ref = "mySqlDataSource" /> < property name = "targetDataSources" > < map > < entry key = "mySqlDataSource" value-ref = "mySqlDataSource" /> < entry key = "sqlServerDataSource" value-ref = "sqlServerDataSource" /> </ map > </ property > </ bean > < bean id = "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" > < property name = "dataSource" ref = "multipleDataSource" /> </ bean > <!-- mybatis.spring自動映射 --> < bean class = "org.mybatis.spring.mapper.MapperScannerConfigurer" > < property name = "basePackage" value = "com.cnblogs.lzrabbit" /> </ bean > <!-- 自動掃描,多個包以 逗號分隔 --> < context:component-scan base-package = "com.cnblogs.lzrabbit" /> < aop:aspectj-autoproxy /> </ beans > |
MultipleDataSource實現(xiàn)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.cnblogs.lzrabbit; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; /** * Created by rabbit on 14-5-25. */ public class MultipleDataSource extends AbstractRoutingDataSource { private static final ThreadLocal<String> dataSourceKey = new InheritableThreadLocal<String>(); public static void setDataSourceKey(String dataSource) { dataSourceKey.set(dataSource); } @Override protected Object determineCurrentLookupKey() { return dataSourceKey.get(); } } |
MyBatis接口Mapper定義,直接使用注解方式實現(xiàn)
1
2
3
4
5
6
7
8
9
|
public interface MySqlMapper { @Select ( "select * from MyTable" ) List<Map<String,Object>> getList(); } public interface SqlServerMapper { @Select ( "select * from MyTable" ) List<Map<String,Object>> getList(); } |
手動數(shù)據(jù)源切換調(diào)用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package com.cnblogs.lzrabbit; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by rabbit on 14-5-25. */ public class Main { public static void main(String[] args) { //初始化ApplicationContext ApplicationContext applicationContext = new ClassPathXmlApplicationContext( "applicationContext.xml" ); MySqlMapper mySqlMapper = applicationContext.getBean(MySqlMapper. class ); SqlServerMapper sqlServerMapper = applicationContext.getBean(SqlServerMapper. class ); //設(shè)置數(shù)據(jù)源為MySql,使用了AOP測試時請將下面這行注釋 MultipleDataSource.setDataSourceKey( "mySqlDataSource" ); mySqlMapper.getList(); //設(shè)置數(shù)據(jù)源為SqlServer,使用AOP測試時請將下面這行注釋 MultipleDataSource.setDataSourceKey( "sqlServerDataSource" ); sqlServerMapper.getList(); } } |
使用SpringAOP方式實現(xiàn)自動切換
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package com.cnblogs.lzrabbit; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Component @Aspect public class MultipleDataSourceAspectAdvice { @Around ( "execution(* com.cnblogs.lzrabbit.*.*(..))" ) public Object doAround(ProceedingJoinPoint jp) throws Throwable { if (jp.getTarget() instanceof MySqlMapper) { MultipleDataSource.setDataSourceKey( "mySqlDataSource" ); } else if (jp.getTarget() instanceof SqlServerMapper) { MultipleDataSource.setDataSourceKey( "sqlServerDataSource" ); } return jp.proceed(); } } |
調(diào)用日志
1
2
3
4
5
6
7
8
|
2014-05-25 20:02:04,319 DEBUG [main] com.jb51.lzrabbit.MySqlMapper.getList - ooo Using Connection [jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true, [email protected], MySQL Connector Java] 2014-05-25 20:02:04,333 DEBUG [main] com.jb51.lzrabbit.MySqlMapper.getList - ==> Preparing: select * from MyTable 2014-05-25 20:02:04,371 DEBUG [main] com.jb51.lzrabbit.MySqlMapper.getList - ==> Parameters: 2014-05-25 20:02:04,396 DEBUG [main] com.jb51.lzrabbit.MySqlMapper.getList - <== Total: 8 2014-05-25 20:02:04,620 DEBUG [main] com.jb51.lzrabbit.SqlServerMapper.getList - ooo Using Connection [jdbc:jtds:sqlserver://127.0.0.1:1433/test, UserName=sa, jTDS Type 4 JDBC Driver for MS SQL Server and Sybase] 2014-05-25 20:02:04,620 DEBUG [main] com.jb51.lzrabbit.SqlServerMapper.getList - ==> Preparing: select * from TmallCityMap 2014-05-25 20:02:04,621 DEBUG [main] com.jb51.lzrabbit.SqlServerMapper.getList - ==> Parameters: 2014-05-25 20:02:04,681 DEBUG [main] com.jb51.lzrabbit.SqlServerMapper.getList - <== Total: 397 |
這里就上面的實現(xiàn)做個簡單解釋,在我們配置單數(shù)據(jù)源時可以看到數(shù)據(jù)源類型使用了org.apache.commons.dbcp.BasicDataSource,而這個代碼實現(xiàn)了javax.sql.DataSource接口
配置sqlSessionFactory時org.mybatis.spring.SqlSessionFactoryBean注入?yún)?shù)dataSource類型就是javax.sql.DataSource
實現(xiàn)多數(shù)據(jù)源的方法就是我們自定義了一個MultipleDataSource,這個類繼承自AbstractRoutingDataSource,而AbstractRoutingDataSource繼承自AbstractDataSource ,AbstractDataSource 實現(xiàn)了javax.sql.DataSource接口,所以我們的MultipleDataSource也實現(xiàn)了javax.sql.DataSource接口,可以賦值給sqlSessionFactory的dataSource屬性
1
2
3
|
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean {} public abstract class AbstractDataSource implements DataSource {} |
再來說下MultipleDataSource的實現(xiàn)原理,MultipleDataSource實現(xiàn)AbstractRoutingDataSource抽象類,然后實現(xiàn)了determineCurrentLookupKey方法,這個方法用于選擇具體使用targetDataSources中的哪一個數(shù)據(jù)源
1
2
3
4
5
6
7
8
9
|
< bean id = "multipleDataSource" class = "com.cnblogs.lzrabbit.MultipleDataSource" > < property name = "defaultTargetDataSource" ref = "mySqlDataSource" /> < property name = "targetDataSources" > < map > < entry key = "mySqlDataSource" value-ref = "mySqlDataSource" /> < entry key = "sqlServerDataSource" value-ref = "sqlServerDataSource" /> </ map > </ property > </ bean > |
可以看到Spring配置中multipleDataSource設(shè)置了兩個屬性defaultTargetDataSource和targetDataSources,這兩個屬性定義在AbstractRoutingDataSource,當(dāng)MyBatis執(zhí)行查詢時會先選擇數(shù)據(jù)源,選擇順序時現(xiàn)根據(jù)determineCurrentLookupKey方法返回的值到targetDataSources中去找,若能找到怎返回對應(yīng)的數(shù)據(jù)源,若找不到返回默認的數(shù)據(jù)源defaultTargetDataSource,具體參考AbstractRoutingDataSource的源碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
public abstract class AbstractRoutingDataSource extends AbstractDataSource implements InitializingBean { private Map<Object, Object> targetDataSources; private Object defaultTargetDataSource; /** * Retrieve the current target DataSource. Determines the * {@link #determineCurrentLookupKey() current lookup key}, performs * a lookup in the {@link #setTargetDataSources targetDataSources} map, * falls back to the specified * {@link #setDefaultTargetDataSource default target DataSource} if necessary. * @see #determineCurrentLookupKey() */ protected DataSource determineTargetDataSource() { Assert.notNull( this .resolvedDataSources, "DataSource router not initialized" ); Object lookupKey = determineCurrentLookupKey(); DataSource dataSource = this .resolvedDataSources.get(lookupKey); if (dataSource == null && ( this .lenientFallback || lookupKey == null )) { dataSource = this .resolvedDefaultDataSource; } if (dataSource == null ) { throw new IllegalStateException( "Cannot determine target DataSource for lookup key [" + lookupKey + "]" ); } return dataSource; } /** * Determine the current lookup key. This will typically be * implemented to check a thread-bound transaction context. * <p>Allows for arbitrary keys. The returned key needs * to match the stored lookup key type, as resolved by the * {@link #resolveSpecifiedLookupKey} method. */ protected abstract Object determineCurrentLookupKey(); ............. } |
在動態(tài)切換數(shù)據(jù)源方法時選擇了AOP方式實現(xiàn),這里實現(xiàn)的簡單粗暴,具體應(yīng)用時根據(jù)實際需要靈活變通吧
題外話,這里提下SqlServer驅(qū)動選擇的問題,目前SqlServer的驅(qū)動主要有微軟的官方驅(qū)動和JTDS驅(qū)動兩種,關(guān)于這兩個驅(qū)動我做過測試,批量更新,在小數(shù)據(jù)量(100以下)時,JTDS相對微軟驅(qū)動性能稍微高一點點,在數(shù)據(jù)量增大時幾萬到上百萬時,微軟驅(qū)動有著明顯優(yōu)勢,所以若對性能比較敏感,建議使用微軟驅(qū)動,否則隨意
微軟驅(qū)動在Maven庫找不到,這點比較郁悶,若使用maven的話還得先安裝到本地,這點很不爽
JTDS使用比較方便Maven直接引用即可
相關(guān)jar maven引用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
< properties > < project.build.sourceEncoding >UTF-8</ project.build.sourceEncoding > < org.springframework.version >3.2.7.RELEASE</ org.springframework.version > </ properties > < dependencies > < dependency > < groupId >org.aspectj</ groupId > < artifactId >aspectjweaver</ artifactId > < version >1.7.2</ version > </ dependency > < dependency > < groupId >commons-dbcp</ groupId > < artifactId >commons-dbcp</ artifactId > < version >1.4</ version > </ dependency > < dependency > < groupId >commons-logging</ groupId > < artifactId >commons-logging</ artifactId > < version >1.1.3</ version > </ dependency > < dependency > < groupId >log4j</ groupId > < artifactId >log4j</ artifactId > < version >1.2.17</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-core</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-beans</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-aop</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-context</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-jdbc</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-context-support</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-web</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-webmvc</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.springframework</ groupId > < artifactId >spring-tx</ artifactId > < version >${org.springframework.version}</ version > </ dependency > < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis</ artifactId > < version >3.2.4</ version > </ dependency > < dependency > < groupId >org.mybatis</ groupId > < artifactId >mybatis-spring</ artifactId > < version >1.2.2</ version > </ dependency > < dependency > < groupId >org.slf4j</ groupId > < artifactId >slf4j-log4j12</ artifactId > < version >1.7.6</ version > </ dependency > < dependency > < groupId >net.sourceforge.jtds</ groupId > < artifactId >jtds</ artifactId > < version >1.2.8</ version > </ dependency > < dependency > < groupId >mysql</ groupId > < artifactId >mysql-connector-java</ artifactId > < version >5.1.29</ version > </ dependency > </ dependencies > |
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:http://www.cnblogs.com/lzrabbit/p/3750803.html