您的位置:首页 > 编程语言 > Java开发

Spring Boot2.0.3 Mybatis Sharding-jdbc3.X集成实现数据库的读写分离(二)-项目实现

2018-09-29 16:08 831 查看

       上一篇文章,我们实现了Mysql的主从配置。并且配置了2个库,进行主从同步db0,db1。如果对主从配置不清楚的可以查看上一篇博客https://blog.csdn.net/zhuwei_clark/article/details/82898093

       这篇文章,主要讲解的是怎么使用Sharding-jdbc3.x实现数据库的读写分离。

官网地址:http://shardingsphere.io/index_zh.html

       这里使用的3.X版本。POM文件配置

[code]  	<dependency>
<groupId>io.shardingsphere</groupId>
<artifactId>sharding-jdbc</artifactId>
<version>3.0.0.M3</version>
</dependency>

  使用的是Spring boo 2.0.3 POM文件配置

[code]	<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>

ORM采用的是Mybatis,POM文件配置

[code]        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis.spring.boot/mybatis-spring-boot-starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>

application.yml文件配置如下

[code]server:
port: 9090

spring:
application:
name: vts_sc_sharding_mybatis

#sharding-jdbc的配置
sharding.jdbc:
data-sources:
ds_master:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://XX:3306/db1
username: daxian
password: zhudaxian;.,68NB
ds_slave_0:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://XX2:3306/db0
username: daxian
password: zhudaxian;.,68NB
master-slave-rule:
name: ds_ms
master-data-source-name: ds_master
slave-data-source-names: ds_slave_0
load-balance-algorithm-type: round_robin
props:
sql.show: true
#mybatis的配置
mybatis:
config-location: classpath:mybatis/config.xml
mapper-locations:
- classpath:mybatis/mappers/*.xml

这里我为了验证数据确实读写分库,采用的不是对应的主从库,这里采用的主库是master机器的db1,从库是Slave机器的db0,也就是避免了mysql自身的主从机制复制数据。

使用Sharding配置数据源:

读取配置内容。

[code]@Data
@ConfigurationProperties(prefix = "sharding.jdbc")
public class ShardingMasterSlaveConfig {

private Map<String, DruidDataSource> dataSources = new HashMap<>();

private MasterSlaveRuleConfiguration masterSlaveRule;
}

配置数据源:

[code]@Slf4j
@Configuration
@EnableConfigurationProperties(ShardingMasterSlaveConfig.class)
@ConditionalOnProperty({"sharding.jdbc.data-sources.ds_master.url", "sharding.jdbc.master-slave-rule.master-data-source-name"})
public class ShardingDataSourceConfig {

@Autowired(required = false)
private ShardingMasterSlaveConfig shardingMasterSlaveConfig;

@Bean("dataSource")
public DataSource masterSlaveDataSource() throws SQLException {
shardingMasterSlaveConfig.getDataSources().forEach((k, v) -> configDataSource(v));
Map<String, DataSource> dataSourceMap = Maps.newHashMap();
dataSourceMap.putAll(shardingMasterSlaveConfig.getDataSources());
DataSource dataSource = MasterSlaveDataSourceFactory.createDataSource(dataSourceMap, shardingMasterSlaveConfig.getMasterSlaveRule(),  new HashMap<String, Object>(), new Properties());
log.info("masterSlaveDataSource config complete");
return dataSource;
}

private void configDataSource(DruidDataSource druidDataSource) {
druidDataSource.setMaxActive(20);
druidDataSource.setInitialSize(1);
druidDataSource.setMaxWait(60000);
druidDataSource.setMinIdle(1);
druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
druidDataSource.setMinEvictableIdleTimeMillis(300000);
druidDataSource.setValidationQuery("select 'x'");
druidDataSource.setTestWhileIdle(true);
druidDataSource.setTestOnBorrow(false);
druidDataSource.setTestOnReturn(false);
druidDataSource.setPoolPreparedStatements(true);
druidDataSource.setMaxOpenPreparedStatements(20);
druidDataSource.setUseGlobalDataSourceStat(true);
try {
druidDataSource.setFilters("stat,wall,slf4j");
} catch (SQLException e) {
log.error("druid configuration initialization filter", e);
}
}
}

Mybatis配置

resources文件下面新建mybatis文件,在mybatis文件下新建mappers文件夹。

在mybatis文件下配置mybatis的配置文件,这里注意用了配置文件,就不能再application里面配置configlcation属性。

[code]<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!--配置命名规则-->
<setting name="mapUnderscoreToCamelCase" value="true" />
</settings>
<typeAliases>
<typeAlias alias="Integer" type="java.lang.Integer" />
<typeAlias alias="Long" type="java.lang.Long" />
<typeAlias alias="HashMap" type="java.util.HashMap" />
<typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
<typeAlias alias="ArrayList" type="java.util.ArrayList" />
<typeAlias alias="LinkedList" type="java.util.LinkedList" />
</typeAliases>
</configuration>

配置启动类

[code]@SpringBootApplication
@MapperScan("com.vipcode.vts.dao")
public class Application {

public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}

}

mybatis支持全注解方式和XML配置

全注解配置

[code]@Mapper
public interface VTSUserAnnotation {

@Insert("INSERT INTO vts_user(pk_user,userName,user_password,user_code) VALUES (#{pkUser},#{username},#{userPassword},#{userCode})")
@Results({
@Result(column = "userName",property = "username"),
})

int insert(VTSUser record);

@Select("SELECT * FROM vts_user WHERE pk_user=#{pkUser}")
@Results({
@Result(column = "userName",property = "username"),
})
VTSUser selectByPrimaryKey(String pkUser);

}

使用注解方式配置的话,最好是设置驼峰命令规则。需要使用@Mapper

XML配置

[code]
@Repository("vtsUserMapper")
public interface VTSUserMapper {
int deleteByPrimaryKey(String pkUser);

int insert(VTSUser record);

int insertSelective(VTSUser record);

VTSUser selectByPrimaryKey(String pkUser);

int updateByPrimaryKeySelective(VTSUser record);

int updateByPrimaryKey(VTSUser record);
}

这里需要把接口托管给Spring,XML内容如下,是通过工具映射生成的。

[code]<?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.vipcode.vts.dao.VTSUserMapper">
<resultMap id="BaseResultMap" type="com.vipcode.vts.entity.VTSUser">
<id column="pk_user" jdbcType="CHAR" property="pkUser" />
<result column="dr" jdbcType="INTEGER" property="dr" />
<result column="use_status" jdbcType="INTEGER" property="useStatus" />
<result column="create_date" jdbcType="CHAR" property="createDate" />
<result column="user_code" jdbcType="VARCHAR" property="userCode" />
<result column="user_password" jdbcType="VARCHAR" property="userPassword" />
<result column="userName" jdbcType="VARCHAR" property="username" />
<result column="user_sex" jdbcType="INTEGER" property="userSex" />
<result column="pk_status" jdbcType="VARCHAR" property="pkStatus" />
<result column="user_picture" jdbcType="VARCHAR" property="userPicture" />
<result column="regist_date" jdbcType="CHAR" property="registDate" />
<result column="login_status" jdbcType="INTEGER" property="loginStatus" />
<result column="login_platform" jdbcType="INTEGER" property="loginPlatform" />
<result column="login_deivce_code" jdbcType="VARCHAR" property="loginDeivceCode" />
<result column="is_first" jdbcType="INTEGER" property="isFirst" />
<result column="openID" jdbcType="VARCHAR" property="openid" />
<result column="weixin_url" jdbcType="VARCHAR" property="weixinUrl" />
<result column="weixin_name" jdbcType="VARCHAR" property="weixinName" />
<result column="bind_tag" jdbcType="VARCHAR" property="bindTag" />
<result column="bind_date" jdbcType="CHAR" property="bindDate" />
<result column="mac_address" jdbcType="VARCHAR" property="macAddress" />
<result column="ip_address" jdbcType="VARCHAR" property="ipAddress" />
<result column="AccessKey" jdbcType="VARCHAR" property="accesskey" />
<result column="SecretKey" jdbcType="VARCHAR" property="secretkey" />
</resultMap>
<sql id="Base_Column_List">
pk_user, dr, use_status, create_date, user_code, user_password, userName, user_sex,
pk_status, user_picture, regist_date, login_status, login_platform, login_deivce_code,
is_first, openID, weixin_url, weixin_name, bind_tag, bind_date, mac_address, ip_address,
AccessKey, SecretKey
</sql>
<select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from vts_user
where pk_user = #{pkUser,jdbcType=CHAR}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.String">
delete from vts_user
where pk_user = #{pkUser,jdbcType=CHAR}
</delete>
<insert id="insert" parameterType="com.vipcode.vts.entity.VTSUser">
insert into vts_user (pk_user, dr, use_status,
create_date, user_code, user_password,
userName, user_sex, pk_status,
user_picture, regist_date, login_status,
login_platform, login_deivce_code, is_first,
openID, weixin_url, weixin_name,
bind_tag, bind_date, mac_address,
ip_address, AccessKey, SecretKey
)
values (#{pkUser,jdbcType=CHAR}, #{dr,jdbcType=INTEGER}, #{useStatus,jdbcType=INTEGER},
#{createDate,jdbcType=CHAR}, #{userCode,jdbcType=VARCHAR}, #{userPassword,jdbcType=VARCHAR},
#{username,jdbcType=VARCHAR}, #{userSex,jdbcType=INTEGER}, #{pkStatus,jdbcType=VARCHAR},
#{userPicture,jdbcType=VARCHAR}, #{registDate,jdbcType=CHAR}, #{loginStatus,jdbcType=INTEGER},
#{loginPlatform,jdbcType=INTEGER}, #{loginDeivceCode,jdbcType=VARCHAR}, #{isFirst,jdbcType=INTEGER},
#{openid,jdbcType=VARCHAR}, #{weixinUrl,jdbcType=VARCHAR}, #{weixinName,jdbcType=VARCHAR},
#{bindTag,jdbcType=VARCHAR}, #{bindDate,jdbcType=CHAR}, #{macAddress,jdbcType=VARCHAR},
#{ipAddress,jdbcType=VARCHAR}, #{accesskey,jdbcType=VARCHAR}, #{secretkey,jdbcType=VARCHAR}
)
</insert>
<insert id="insertSelective" parameterType="com.vipcode.vts.entity.VTSUser">
insert into vts_user
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="pkUser != null">
pk_user,
</if>
<if test="dr != null">
dr,
</if
1fff8
>
<if test="useStatus != null">
use_status,
</if>
<if test="createDate != null">
create_date,
</if>
<if test="userCode != null">
user_code,
</if>
<if test="userPassword != null">
user_password,
</if>
<if test="username != null">
userName,
</if>
<if test="userSex != null">
user_sex,
</if>
<if test="pkStatus != null">
pk_status,
</if>
<if test="userPicture != null">
user_picture,
</if>
<if test="registDate != null">
regist_date,
</if>
<if test="loginStatus != null">
login_status,
</if>
<if test="loginPlatform != null">
login_platform,
</if>
<if test="loginDeivceCode != null">
login_deivce_code,
</if>
<if test="isFirst != null">
is_first,
</if>
<if test="openid != null">
openID,
</if>
<if test="weixinUrl != null">
weixin_url,
</if>
<if test="weixinName != null">
weixin_name,
</if>
<if test="bindTag != null">
bind_tag,
</if>
<if test="bindDate != null">
bind_date,
</if>
<if test="macAddress != null">
mac_address,
</if>
<if test="ipAddress != null">
ip_address,
</if>
<if test="accesskey != null">
AccessKey,
</if>
<if test="secretkey != null">
SecretKey,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="pkUser != null">
#{pkUser,jdbcType=CHAR},
</if>
<if test="dr != null">
#{dr,jdbcType=INTEGER},
</if>
<if test="useStatus != null">
#{useStatus,jdbcType=INTEGER},
</if>
<if test="createDate != null">
#{createDate,jdbcType=CHAR},
</if>
<if test="userCode != null">
#{userCode,jdbcType=VARCHAR},
</if>
<if test="userPassword != null">
#{userPassword,jdbcType=VARCHAR},
</if>
<if test="username != null">
#{username,jdbcType=VARCHAR},
</if>
<if test="userSex != null">
#{userSex,jdbcType=INTEGER},
</if>
<if test="pkStatus != null">
#{pkStatus,jdbcType=VARCHAR},
</if>
<if test="userPicture != null">
#{userPicture,jdbcType=VARCHAR},
</if>
<if test="registDate != null">
#{registDate,jdbcType=CHAR},
</if>
<if test="loginStatus != null">
#{loginStatus,jdbcType=INTEGER},
</if>
<if test="loginPlatform != null">
#{loginPlatform,jdbcType=INTEGER},
</if>
<if test="loginDeivceCode != null">
#{loginDeivceCode,jdbcType=VARCHAR},
</if>
<if test="isFirst != null">
#{isFirst,jdbcType=INTEGER},
</if>
<if test="openid != null">
#{openid,jdbcType=VARCHAR},
</if>
<if test="weixinUrl != null">
#{weixinUrl,jdbcType=VARCHAR},
</if>
<if test="weixinName != null">
#{weixinName,jdbcType=VARCHAR},
</if>
<if test="bindTag != null">
#{bindTag,jdbcType=VARCHAR},
</if>
<if test="bindDate != null">
#{bindDate,jdbcType=CHAR},
</if>
<if test="macAddress != null">
#{macAddress,jdbcType=VARCHAR},
</if>
<if test="ipAddress != null">
#{ipAddress,jdbcType=VARCHAR},
</if>
<if test="accesskey != null">
#{accesskey,jdbcType=VARCHAR},
</if>
<if test="secretkey != null">
#{secretkey,jdbcType=VARCHAR},
</if>
</trim>
</insert>
<update id="updateByPrimaryKeySelective" parameterType="com.vipcode.vts.entity.VTSUser">
update vts_user
<set>
<if test="dr != null">
dr = #{dr,jdbcType=INTEGER},
</if>
<if test="useStatus != null">
use_status = #{useStatus,jdbcType=INTEGER},
</if>
<if test="createDate != null">
create_date = #{createDate,jdbcType=CHAR},
</if>
<if test="userCode != null">
user_code = #{userCode,jdbcType=VARCHAR},
</if>
<if test="userPassword != null">
user_password = #{userPassword,jdbcType=VARCHAR},
</if>
<if test="username != null">
userName = #{username,jdbcType=VARCHAR},
</if>
<if test="userSex != null">
user_sex = #{userSex,jdbcType=INTEGER},
</if>
<if test="pkStatus != null">
pk_status = #{pkStatus,jdbcType=VARCHAR},
</if>
<if test="userPicture != null">
user_picture = #{userPicture,jdbcType=VARCHAR},
</if>
<if test="registDate != null">
regist_date = #{registDate,jdbcType=CHAR},
</if>
<if test="loginStatus != null">
login_status = #{loginStatus,jdbcType=INTEGER},
</if>
<if test="loginPlatform != null">
login_platform = #{loginPlatform,jdbcType=INTEGER},
</if>
<if test="loginDeivceCode != null">
login_deivce_code = #{loginDeivceCode,jdbcType=VARCHAR},
</if>
<if test="isFirst != null">
is_first = #{isFirst,jdbcType=INTEGER},
</if>
<if test="openid != null">
openID = #{openid,jdbcType=VARCHAR},
</if>
<if test="weixinUrl != null">
weixin_url = #{weixinUrl,jdbcType=VARCHAR},
</if>
<if test="weixinName != null">
weixin_name = #{weixinName,jdbcType=VARCHAR},
</if>
<if test="bindTag != null">
bind_tag = #{bindTag,jdbcType=VARCHAR},
</if>
<if test="bindDate != null">
bind_date = #{bindDate,jdbcType=CHAR},
</if>
<if test="macAddress != null">
mac_address = #{macAddress,jdbcType=VARCHAR},
</if>
<if test="ipAddress != null">
ip_address = #{ipAddress,jdbcType=VARCHAR},
</if>
<if test="accesskey != null">
AccessKey = #{accesskey,jdbcType=VARCHAR},
</if>
<if test="secretkey != null">
SecretKey = #{secretkey,jdbcType=VARCHAR},
</if>
</set>
where pk_user = #{pkUser,jdbcType=CHAR}
</update>
<update id="updateByPrimaryKey" parameterType="com.vipcode.vts.entity.VTSUser">
update vts_user
set dr = #{dr,jdbcType=INTEGER},
use_status = #{useStatus,jdbcType=INTEGER},
create_date = #{createDate,jdbcType=CHAR},
user_code = #{userCode,jdbcType=VARCHAR},
user_password = #{userPassword,jdbcType=VARCHAR},
userName = #{username,jdbcType=VARCHAR},
user_sex = #{userSex,jdbcType=INTEGER},
pk_status = #{pkStatus,jdbcType=VARCHAR},
user_picture = #{userPicture,jdbcType=VARCHAR},
regist_date = #{registDate,jdbcType=CHAR},
login_status = #{loginStatus,jdbcType=INTEGER},
login_platform = #{loginPlatform,jdbcType=INTEGER},
login_deivce_code = #{loginDeivceCode,jdbcType=VARCHAR},
is_first = #{isFirst,jdbcType=INTEGER},
openID = #{openid,jdbcType=VARCHAR},
weixin_url = #{weixinUrl,jdbcType=VARCHAR},
weixin_name = #{weixinName,jdbcType=VARCHAR},
bind_tag = #{bindTag,jdbcType=VARCHAR},
bind_date = #{bindDate,jdbcType=CHAR},
mac_address = #{macAddress,jdbcType=VARCHAR},
ip_address = #{ipAddress,jdbcType=VARCHAR},
AccessKey = #{accesskey,jdbcType=VARCHAR},
SecretKey = #{secretkey,jdbcType=VARCHAR}
where pk_user = #{pkUser,jdbcType=CHAR}
</update>
</mapper>

新建Service层,进行业务处理

[code]/**
* <b>  </b>
* <p>
* 功能描述:
* </p>
* <p/>
* @author 朱维
* @date 2018年9月29日
* @time 上午11:18:36
* @Path: com.vipcode.vts.service.impl.UserServiceImpl
*/
@Service
public class UserServiceImpl implements UserService{
/**
* 注入数据接口
*/
@Autowired
private VTSUserMapper vtsUserMapper;

/**
* 注入数据接口
*/
@Autowired
private VTSUserAnnotation vtsUserAnnotation;

@Override
public VTSUser getUser(String pkUser) {
// TODO Auto-generated method stub
VTSUser vtsUser = vtsUserMapper.selectByPrimaryKey(pkUser);
System.out.println(vtsUser);
VTSUser vtsUser2 = vtsUserAnnotation.selectByPrimaryKey(pkUser);
System.out.println(vtsUser2);
return vtsUser2;
}

@Override
public String saveUser(VTSUser vtsUser) {
// TODO Auto-generated method stub
//		 vtsUserMapper.insert(vtsUser);
vtsUser.setPkUser(Pub_Tools.genUUID());
vtsUserAnnotation.insert(vtsUser);
return vtsUser.getPkUser();
}

}

编写Controller

[code]@RestController
public class UserController {
/**
* 注入用户Service
*/
@Autowired
private UserService userService;
/**
* 获取用户
* @param pkUser
* @return
*/
@GetMapping("/user")
public VTSUser getUser(@RequestParam("pkUser")String pkUser){
return userService.getUser(pkUser);
}
/**
* 保存用户
* @param vtsUser
* @return
*/
@PostMapping("/save")
public String saveUser(VTSUser vtsUser){
return userService.saveUser(vtsUser);
}
}

测试调用保存的方法,往数据库中插入一条数据,得到返回的主键。

此时去查询Slave的db0,无此条数据

查询Slave的db1,有此条数据,这是Mysql主从复制规则产生的。

使用该主键,调用查询方法,返回数据null。说明查询是从db0中进行查询。由此证明,项目中的读写是分库的。

更改yml配置,设置主库为Master机器的db0,则读写分离配置成功。

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: