1、公共表
公共表数据系统中数据量较小,变动少,而且属于高频联合查询的依赖表。参数表、数据字典表等属于此类型。可以将这类表在每个数据库都保存一份,所有更新操作都同时发送到所有分库执行。接下来看一下如何使用 Sharding-JDBC 实现公共表。
2、实现
2.1 创建数据库和表
分别在 user_db、order_db_1、order_db_2 中创建 t_dict 表(以上这些库是之前章节已经创建好的,若不知道请移步 Sharding-jdbc 快速入门)
CREATE TABLE `t_dict` (
`dict_id` bigint(20) NOT NULL COMMENT '字典 id,
`type` varchar(50) NOT NULL COMMENT '字典类型',
`code` varchar(50) NOT NULL COMMENT '字典编码',
`value` varchar(50) NOT NULL COMMENT '字典值',
PRIMARY KEY (`dict_id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='字典表'
2.2 修改 application.properties
# 配置公共表,指定 t_dict 为公共表
spring.shardingsphere.sharding.broadcast-tables=t_dict
2.3 新建 mapper 接口
新建 DictMapper 接口
package com.pky.shardingjdbc.mapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
@Repository
public interface DictMapper {
/**
* 插入字典表信息
* @param dictId 字典id
* @param type 字典类型
* @param code 字典编码
* @param value 字典值
* @return
*/
@Insert("Insert into t_dict(dict_id, type, code, value) values(#{dictId}, #{type}, #{code}, #{value})")
int insertDict(@Param("dictId") Long dictId, @Param("type") String type, @Param("code") String code, @Param("value") String value);
/**
* 删除字典信息
* @param dictId 字典id
* @return
*/
@Delete("Delete from t_dict where dict_id = #{dictId}")
int deleteDict(@Param("dictId") Long dictId);
}
2.4 测试
package com.pky.shardingjdbc;
import com.pky.shardingjdbc.mapper.DictMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ShardingJDBCApplication.class})
public class DictTest {
@Autowired
DictMapper dictMapper;
@Test
public void testInsert() {
dictMapper.insertDict(1L, "user_type", "0", "超级管理员");
dictMapper.insertDict(2L, "user_type", "1", "普通管理员");
}
@Test
public void testDelete() {
dictMapper.deleteDict(1L);
}
}
2.4.1 插入测试结果
从结果可以看出,已经向 m0,m1,m2 中各插入了两条数据。
2.4.2 删除测试结果
从结果可以看出,已经向 m0,m1,m2 中各删除了数据。
2.4.3 关联查询测试
因为在每个数据库中都有公共表 t_dict ,因此关联查询就不需要跨节点查询,接下来进行关联查询的测试
- 在 UserMapper 接口中新建查询
/**
* 根据id和字典信息查询用户
* @param userIds id集合
* @return
*/
@Select("<script>" +
"select * from t_user u, t_dict d " +
"where u.user_type = d.code and u.user_id in " +
"<foreach collection = 'userIds' open = '(' separator = ',' close = ')' item = 'id'> " +
"#{id}" +
"</foreach>" +
"</script>")
List<Map> selectUserByUserInfo(@Param("userIds") List<Long> userIds );
- 新建测试方法
@Test
public void testSelectByUserIds() {
List<Long> userIds = new ArrayList<>();
userIds.add(1L);
userIds.add(11L);
List<Map> users = userMapper.selectUserByUserInfo(userIds);
for (Map user: users) {
System.out.println(user.toString());
}
}
- 查询结果