最近忙於項目已經很久幾天沒寫博客了,前2篇文章我給你們介紹了搭建基礎springMvc+mybatis的maven工程,這個簡單框架已經能夠對付通常的小型項目。可是咱們實際項目中會碰到不少複雜的場景,好比數據量很大的狀況下如何保證性能。今天我就給你們介紹數據庫分庫分表的優化,本文介紹mybatis結合噹噹網的sharding-jdbc分庫分表技術(原理這裏不作介紹)java
首先在pom文件中引入須要的依賴spring
<dependency> <groupId>com.dangdang</groupId> <artifactId>sharding-jdbc-core</artifactId> <version>1.4.2</version> </dependency> <dependency> <groupId>com.dangdang</groupId> <artifactId>sharding-jdbc-config-spring</artifactId> <version>1.4.0</version> </dependency>
2、新建一個sharding-jdbc.xml文件,實現分庫分表的配置sql
<?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:tx="http://www.springframework.org/schema/tx" xmlns:rdb="http://www.dangdang.com/schema/ddframe/rdb" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.dangdang.com/schema/ddframe/rdb http://www.dangdang.com/schema/ddframe/rdb/rdb.xsd"> <rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-class="com.meiren.member.common.sharding.MemberSingleKeyTableShardingAlgorithm"/> <rdb:data-source id="shardingDataSource"> <rdb:sharding-rule data-sources="dataSource"> <rdb:table-rules> <rdb:table-rule logic-table="member_index" actual-tables="member_index_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/> <rdb:table-rule logic-table="member_details" actual-tables="member_details_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/> </rdb:table-rules> </rdb:sharding-rule> </rdb:data-source> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="shardingDataSource" /> </bean> </beans>
這裏我簡單介紹下一些屬性的含義,數據庫
<rdb:strategy id="tableShardingStrategy" sharding-columns="user_id" algorithm-class="com.meiren.member.common.sharding.MemberSingleKeyTableShardingAlgorithm"/> 配置分表規則器 sharding-columns:分表規 則 mybatis
依賴的名(根據user_id取模分表),algorithm-class:分表規則的實現類 架構
<rdb:sharding-rule data-sources="dataSource"> 這裏填寫關聯數據源(多個數據源用逗號隔開),框架
<rdb:table-rule logic-table="member_index" actual-tables="member_index_tbl_${[0,1,2,3,4,5,6,7,8,9]}${0..9}" table-strategy="tableShardingStrategy"/> logic-table:邏輯表名(mybatis中代替的表名)actual-tables:maven
數據庫實際的表名,這裏支持inline表達式,好比:member_index_tbl_${0..2}會解析成member_index_tbl_0,member_index_tbl_1,member_index_tbl_2;member_index_tbl_${[a,b,c]}會被解析成分佈式
member_index_tbl_a,member_index_tbl_b和member_index_tbl_c,兩種表達式一塊兒使用的時候,會採起笛卡爾積的方式:member_index_tbl_${[a,b]}${0..2}解析爲member_index_tbl_a0,member_index_tbl_a1 member_index_tbl_a2,member_index_tbl_b0,member_index_tbl_b1,member_index_tbl_b2;table-strategy:前面定義的分表規則器;性能
3、配置好改文件後,須要修改以前咱們的spring-dataSource的幾個地方,把sqlSessionFactory和transactionManager原來關聯的dataSource統一修改成shardingDataSource(這一步做用就是把數據源所有託管給sharding去管理)
4、實現分表(分庫)邏輯,咱們的分表邏輯類須要實現SingleKeyTableShardingAlgorithm接口的三個方法doBetweenSharding、doEqualSharding、doInSharding
/** * 分表邏輯 * @author zhangwentao * */ public class MemberSingleKeyTableShardingAlgorithm implements SingleKeyTableShardingAlgorithm<Long> { /** * sql between 規則 */ public Collection<String> doBetweenSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<String>(tableNames.size()); Range<Long> range = (Range<Long>) shardingValue.getValueRange(); for (long i = range.lowerEndpoint(); i <= range.upperEndpoint(); i++) { Long modValue = i % 100; String modStr = modValue < 10 ? "0" + modValue : modValue.toString(); for (String each : tableNames) { if (each.endsWith(modStr)) { result.add(each); } } } return result; } /** * sql == 規則 */ public String doEqualSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) { Long modValue = shardingValue.getValue() % 100; String modStr = modValue < 10 ? "0" + modValue : modValue.toString(); for (String each : tableNames) { if (each.endsWith(modStr)) { return each; } } throw new IllegalArgumentException(); } /** * sql in 規則 */ public Collection<String> doInSharding(Collection<String> tableNames, ShardingValue<Long> shardingValue) { Collection<String> result = new LinkedHashSet<String>(tableNames.size()); for (long value : shardingValue.getValues()) { Long modValue = value % 100; String modStr = modValue < 10 ? "0" + modValue : modValue.toString(); for (String tableName : tableNames) { if (tableName.endsWith(modStr)) { result.add(tableName); } } } return result; } }
5、以上四步,咱們就完成了sharding-jdbc的搭建,咱們能夠寫一個測試demo來檢查咱們的成果
<select id="getDetailsById" resultType="com.meiren.member.dataobject.MemberDetailsDO" parameterType="java.lang.Long"> select user_id userId ,qq,email from member_details where user_id =#{userId} limit 1 </select>
private static final String SERVICE_PROVIDER_XML = "/spring/member-service.xml"; private static final String BEAN_NAME = "idcacheService"; private ClassPathXmlApplicationContext context = null; IdcacheServiceImpl bean = null; IdcacheDao idcacheDao; @Before public void before() { context= new ClassPathXmlApplicationContext( new String[] {SERVICE_PROVIDER_XML}); idcacheDao=context.getBean("IdcacheDao", IdcacheDao.class); } @Test public void getAllCreditActionTest() { // int id = bean.insertIdcache(); Long s=100l; MemberDetailsDO memberDetailsDO=idcacheDao.getDetailsById(s); System.out.println("QQ---------------------"+memberDetailsDO.getQq()); }
打印sql語句,輸出結果:QQ-------------------------------------100,證實成功!
注意點:此次搭建過程當中,我有碰到一個小坑,就是執行的時候會報錯:,官方文檔是有解決方案:引入 <context:property-placeholder location="classpath:/member_service.properties" ignore-unresolvable="true" /> ,引入這行代碼的時候,·必需要要把這邊管理配配置文件的bean刪除,換句話說,即Spring容器僅容許最多定義一個PropertyPlaceholderConfigurer(或<context:property-placeholder/>),其他的會被Spring忽略掉(當時搞了半天啊)
小結:此次給你們分享了sharding-jdbc的配置是爲了解決大數據量進行分庫分表的架構,下一張,我將介紹拆分業務所需的duboo+zookeeper的配置(分佈式),歡迎關注!