sharding-jdbc讀寫分離(一)--Spring Boot集成實現

前言

  本文主要分享spring boot工程使用mybatis和sharding-jdbc實現mysql數據庫的讀寫分離。
  本文demo工程已上傳github:https://github.com/hubSKH/sharding-jdbc-demo
  關於mysql數據庫主從複製設置,可以參考我另外一篇文章:https://blog.csdn.net/u012786993/article/details/89201161
  sharding-jdbc更多介紹與用法,可以上官網查閱相關文檔:http://shardingsphere.apache.org/index_zh.html

工程版本


框架 版本
spring boot 2.0.3.RELEASE(或者1.5.18.RELEASE)
mybatis 1.3.2
sharding-jdbc 3.0.0.M3

  這裏,使用的sharding-jdbc是3.X版本,pom配置:

	<sharding-sphere.version>3.0.0.M3</sharding-sphere.version>

	<!-- for spring boot -->
	<dependency>
	    <groupId>io.shardingsphere</groupId>
	    <artifactId>sharding-jdbc-spring-boot-starter</artifactId>
	    <version>${sharding-sphere.version}</version>
	</dependency>
	
	<!-- for spring namespace -->
	<dependency>
	    <groupId>io.shardingsphere</groupId>
	    <artifactId>sharding-jdbc-spring-namespace</artifactId>
	    <version>${sharding-sphere.version}</version>
	</dependency>

  mybatis使用1.3.2版本,pom:

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

  spring boot的版本最好是1.5.x或以上,本次以1.5.18.RELEASE爲例,pom:

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.18.RELEASE</version>
        <!-- <version>2.0.3.RELEASE</version> -->
    </parent>

  本文使用的是spring boot集成sharding-jdbc,官網的數據源配置是寫在propertis文件中,而本文配置寫在yml文件中也是同樣效果,yml如下:

server:
  port: 9090

spring:
  application:
    name: sharding_jdbc

#sharding-jdbc的配置
sharding.jdbc:
  datasource:
    names: ds_master,ds_slave_0,ds_slave_1
    ds_master:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db1
      username: root
      password: root
    ds_slave_0:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db0
      username: root
      password: root
    ds_slave_1:
      type: com.alibaba.druid.pool.DruidDataSource
      driver-class-name: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/db2
      username: root
      password: root
  config:
    masterslave:
      name: ds_ms
      master-data-source-name: ds_master
      slave-data-source-names: ds_slave_0,ds_slave_1
      load-balance-algorithm-type: round_robin
  props:
    sql.show: true
#mybatis的配置
mybatis:
  config-location: classpath:mybatis/config.xml
  mapper-locations:
  - classpath:mybatis/mappers/*.xml

  這裏我配置的是一主兩從,目的是爲了驗證數據庫查詢的負載均衡算法round_robin,即輪詢。
  mybatis的config.xml配置。注意:這裏注意用了配置文件,就不能再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>

  然後配置spring boot啓動類


@SpringBootApplication
@MapperScan(basePackages = "com.skh.dao")
public class Application  extends WebMvcConfigurerAdapter {

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

}

  數據庫表對象映射類(po)

@Data
public class User implements Serializable {
    private  Integer id;

    private  String name;

    private  Integer age;
}

  dao層接口類

@Mapper
public interface UserMapper {
    int insert(User record);

    User selectByPrimaryKey(int id);
}

  對應UserMapper.xml配置,xml文件可通過mybatis generator工具生成。

<?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.skh.dao.UserMapper">
    <resultMap id="BaseResultMap" type="com.skh.po.User">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="name" jdbcType="INTEGER" property="name" />
        <result column="age" jdbcType="INTEGER" property="age" />
    </resultMap>
    <sql id="Base_Column_List">
        id, name, age
    </sql>
    <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List" />
        from user
        where id = #{id,jdbcType=INTEGER}
    </select>
    <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
        delete from user
        where id = #{id,jdbcType=INTEGER}
    </delete>
    <insert id="insert" parameterType="com.skh.po.User">
        insert into user (id, name, age)
        values (#{id,jdbcType=INTEGER}, #{name,jdbcType=INTEGER}, #{age,jdbcType=INTEGER}
        )
    </insert>
    <insert id="insertSelective" parameterType="com.skh.po.User">
        insert into user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id != null">
                id,
            </if>
            <if test="name != null">
                name,
            </if>
            <if test="age != null">
                age,
            </if>
        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="id != null">
                #{id,jdbcType=INTEGER},
            </if>
            <if test="name != null">
                #{name,jdbcType=INTEGER},
            </if>
            <if test="age != null">
                #{age,jdbcType=INTEGER},
            </if>
        </trim>
    </insert>
    <update id="updateByPrimaryKeySelective" parameterType="com.skh.po.User">
        update user
        <set>
            <if test="name != null">
                name = #{name,jdbcType=INTEGER},
            </if>
            <if test="age != null">
                age = #{age,jdbcType=INTEGER},
            </if>
        </set>
        where id = #{id,jdbcType=INTEGER}
    </update>
    <update id="updateByPrimaryKey" parameterType="com.skh.po.User">
        update user
        set name = #{name,jdbcType=INTEGER},
        age = #{age,jdbcType=INTEGER},
        where id = #{id,jdbcType=INTEGER}
    </update>
</mapper>

  接下來是service層接口類

public interface UserService {

    User getUser(int id);

    Integer saveUser(User user);
}

  service的實現類

@Service
public class UserServiceImpl implements UserService {
    /**
     * 注入數據接口
     */
    @Autowired
    private UserMapper vtsUserMapper;


    @Override
    public User getUser(int id) {
        User user = vtsUserMapper.selectByPrimaryKey(id);
        System.out.println(user);
        return user;
    }

    @Override
    public Integer saveUser(User user) {
        vtsUserMapper.insert(user);
        return user.getId ();
    }

}

  最後是controller類

@RestController
@RequestMapping("user")
public class UserController {

    @Resource
    private UserService userService;

    @RequestMapping("select")
    public User getuser(@RequestParam("id")int id){

        return userService.getUser (id);

    }
}

  運行application的main方法啓動工程後,即可通過接口測試工具,驗證讀寫分離配置。
在這裏插入圖片描述
  爲了更好體現出數據的讀寫分離,從庫中的數據改變數據值以做區分。從下圖多次調用可以看出,配置的讀寫分離已生效,讀取操作不會使用主數據庫數據源,而且數據讀取也按照輪詢的從庫訪問策略使用從庫數據源。
在這裏插入圖片描述

參考文獻

1、https://blog.csdn.net/zhuwei_clark/article/details/82898497

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章