企业信用应用依赖的数据为模型团队计算所得,应用依赖多个数据库、表个数多、重叠字段多且必须一致,测试数据库中没有数据对开发测试工作带来很大困难。这里介绍一个简单的配置,如何快速搭建一个工程通过tddl+ibatis+spring构造数据。新建工程方法很多,大家可以根据习惯选择。
POM依赖
<!-- srping框架 -->
参考附件
<!-- TDDL -->
<dependency>
<groupId>com.taobao.tddl</groupId>
<artifactId>tddl-client</artifactId>
<version>5.1.11</version>
</dependency>
<!-- 保证主键的全局唯一性-->
<dependency>
<groupId>com.taobao.tddl</groupId>
<artifactId>tddl-sequence</artifactId>
<version>5.0.0</version>
</dependency>
<!-- ibatis -->
<dependency>
<groupId>org.apache.ibatis</groupId>
<artifactId>ibatis-sqlmap</artifactId>
<version>2.3.5</version>
<scope>test</scope>
</dependency>
<!-- Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.7</version>
<scope>test</scope>
</dependency>
如果和我一样只需要操作数据库,可以直接copy附件中pom.xml使用,多余的依赖已经排除,记得改artifactid和java版本,我用的是1.7。
目录结构
Spring bean配置
spring_tddl_dal.xml
:对应spring_bizcredit_pbserver_dal.xml, 配置数据库appName、groupKey,规则文件地址,sqlMapClient ,功能bean;
tddl_rule_xxxdb.xml
:对应tddl_rule_pbserver.xml规则文件,每个库一份;
注意引用时的文件名和路径,这里经常会笔误或遗漏。
配置数据源DataSource
appname:ABC_APP groupname:ABC_00_GROUP -- ABC_15_GROUP
表:users 分库分表 规则:根据ali_id取模划分16个库,根据ali_id取模划分128张表;
表:search_index 规则:根据ali_id取模划分16个库,不分表;
分库分表配置
<!-- 分库分表 -->
<bean id="xxxDataSource" class="com.taobao.tddl.client.jdbc.TDataSource" init-method="init" >
<property name="appName" value="ABC_APP" />
<property name="appRuleFile" value="classpath:spring/rule/tddl_rule_xxxdb.xml"/>
</bean>
tddl-rule-xxxdb.xml
:规则配置
<!-- TDDL规则总配置 -->
<bean id="vtabroot" class="com.taobao.tddl.rule.VirtualTableRoot" init-method="init">
<!-- 没有被配置在tableRules的逻辑表都将在这个group里,以单表形式执行-->
<property name="defaultDbIndex" value="ABC_00_GROUP"/>
<!-- 该map配置有分表的逻辑表,有几个表有分表就配置几个键值对-->
<property name="tableRules">
<map>
<!-- key是逻辑表名,value-ref指的是对应具体配置的id-->
<entry key="users" value-ref="users_bean" />
<entry key="search_index" value-ref="search_index_bean" />
</map>
</property>
</bean>
<!-- 分库分表 -->
<bean id="users" class="com.taobao.tddl.interact.rule.TableRule">
<!-- groupKey格式框架,{}中的数将会被dbRuleArray的值替代,并保持位数 -->
<property name="dbNamePattern" value="ABC_{00}_GROUP" />
<!-- 具体表名格式框架,{}中的数将会被tbRuleArray的值替代,并保持位数 -->
<property name="tbNamePattern" value="users_{0000}" />
<property name="dbRuleArray" value="((#ali_id,1,16#).longValue() % 16)" />
<property name="tbRuleArray" value="((#ali_id,1,128#).longValue() % 128)" />
<!-- 全表扫描开关,默认关闭,是否允许应用端在没有给定分表键值的情况下查询全表 -->
<property name="allowFullTableScan" value="true"/>
</bean>
<!-- 分库单表 -->
<bean id="search_index_bean" class="com.taobao.tddl.interact.rule.TableRule">
<property name="dbNamePattern" value="ABC_{00}_GROUP" />
<property name="tbNamePattern" value="search_index" />
<property name="dbRuleArray" value="((#ali_id,1,128#).longValue() % 128)" />
<property name="allowFullTableScan" value="true" />
</bean>
单库单表配置
<!-- 单库单表 -->
<bean id="xxxDataSource" class="com.taobao.tddl.jdbc.group.TGroupDataSource" init-method="init" >
<property name="appName" value="xxx_APP" />
<property name="dbGroupKey" value="yyy_GROUP"/>
</bean>
注意:
分库分表和单库单表class有区别。
分库分表需要指定规则,规则可以动态从diamond获取也可以在本地配置。
配置sql处理工具sqlMapClient
<bean id="xxxSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation" value="classpath:ibatis/xxxdb_sql_map.xml" />
<property name="dataSource" ref="xxxDataSource" />
</bean>
配置sql功能的bean(JAVA中介绍如何生成)
<bean id="dwiBcCompScoreDao" class="com.alibaba.qatest.dao.DwiBcCompScoreDAO">
<property name="sqlMapClient" ref="sqlMapClient"></property>
</bean>
ibatis配置
abc_db_sqlmap.xml
:ABC库SqlMapConfig配置,每张表对应一个sql文件。
dwi_bc_comp_score_d_sqlmap.xml
:dwi_bc_comp_score_d表sql文件
abc_db_sqlmap.xml
<sqlMapConfig>
<settings cacheModelsEnabled="false" enhancementEnabled="false" lazyLoadingEnabled="false" maxRequests="3000" maxSessions="3000" maxTransactions="3000" useStatementNamespaces="true" />
<sqlMap resource="ibatis/sqlmap/pbserver/dwi_bc_comp_score_d_sqlmap.xml" />
</sqlMapConfig>
dwi_bc_comp_score_d_sqlmap.xml
<typeAlias alias="dwiBcCompScoreDDO" type="com.alibaba.qatest.dao.dataobject.DwiBcCompScoreDDO"/>
<!-- select 基本语句 -->
<select id="dwiBcCompScoreD.select" parameterClass="dwiBcCompScoreDDO" resultClass="dwiBcCompScoreDDO">
...sql语句...
</dynamic>
</select>
<!-- insert into 基本语句 -->
<insert id="dwiBcCompScoreD.insert" parameterClass="dwiBcCompScoreDDO">
...sql语句...
</insert>
<!-- delete 基本语句 -->
<delete id="dwiBcCompScoreD.delete" parameterClass="dwiBcCompScoreDDO" >
delete from dwi_bc_comp_score_d
where id = #关键字#
</delete>
快速生成:
IDB选中表点击“代码生成器”,代码模板选择“ibatis”自动生成文件。需自行修改以下几处:
- typeAlias中
com.taobao.***.dataobject.dwiBcCompScoreDDO
替换; id = #关键字#
改为所需条件字段;后面会介绍如何替换。
JAVA代码
快速生成:
DwiBcCompScoreDDO:IDB代码生成器,“代码模板”选择JAVADO
DwiBcCompScoreDAO:IDB代码生成器,“代码模板”选择JAVADAO(ibatis)
规范的写法DAO应该为分为interface和实现类,我这里偷懒直接实现了,导入eclipse工程文件夹上会有x,会报安全提示可以忽略,如果有时间建议规范书写。
public class DwiBcCompScoreDAO extends SqlMapClientDaoSupport{
public List<DwiBcCompScoreDDO> getDwiBcCompScoreDList(DwiBcCompScoreDDO dwiBcCompScoreDDO) {
return getSqlMapClientTemplate().queryForList("dwiBcCompScoreD.select" , dwiBcCompScoreDDO);
}
public Integer deleteDwiBcCompScoreD(DwiBcCompScoreDDO dwiBcCompScoreDDO) {
return getSqlMapClientTemplate().update("dwiBcCompScoreD.delete" , dwiBcCompScoreDDO);
}
}
注意:方法中dwiBcCompScoreD.select
,dwiBcCompScoreD.delete
为ibatis-sql中执行语句的“id”;参数dwiBcCompScoreDDO
类型要与“parameterClass”一致。
测试代码构造数据
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:spring/spring_tddl_dal.xml"})
public class BaseTestCase extends TestCase{
@Autowired
protected DwiBcCompScoreDAO dwiBcCompScoreDao;
@Test
public void testInsert() {
DwiBcCompScoreDDO scoreDDO = new DwiBcCompScoreDDO()
scoreDDO.setStatDate(new Date());
scoreDDO.setDwInsTime(new Date());
scoreDDO.setAliId(1234567l);
scoreDDO.setBasicScore(100l);
scoreDDO.setIdNumber("1234567");
dwiBcCompScoreDao.insertDwiBcCompScoreD(scoreDDO);
}
}
如果遇到@Autowired、@ContextConfiguration导入不成功等问题,建议排查pom文件,一般都是依赖不全导致。如果从开发工程copy,需要注意子工程pom中的特殊依赖是否需要。
以上是我在阿里巴巴实习期间用到的一个中间件tddl,它继承了传统的jdbc的功能,使得我们在集团内部可以通过这个工具来访问、连接数据库。