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

       上一篇文章,我们实现了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文件配置

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

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

	<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文件配置

        <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文件配置如下

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配置数据源:

读取配置内容。

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

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

    private MasterSlaveRuleConfiguration masterSlaveRule;
}

配置数据源:

@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属性。

<?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>

配置启动类

@SpringBootApplication
@MapperScan("com.vipcode.vts.dao")
public class Application {
	
	public static void main(String[] args) throws Exception {
		SpringApplication.run(Application.class, args);
	}

}

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

全注解配置

@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配置


@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内容如下,是通过工具映射生成的。

<?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>
      <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层,进行业务处理

/**
 * <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

@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,则读写分离配置成功。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值