前言
本文主要分享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