当一个表的某些字段过大,就需要将其拆成几个表,但是其拆出来的表最好在一个库中
也就是同一条完整的字段信息最好在一个库中(因为不能跨库操作)
image.pngimage.png
接下来对PositionDetail做的步骤:添加实体类、添加repository、添加配置信息、添加测试即可

1、开始编辑代码

a、追加实体类

  1. package com.slin.entity;
  2. import javax.persistence.*;
  3. import java.io.Serializable;
  4. @Entity
  5. @Table(name = "position_detail")
  6. public class PositionDetail implements Serializable {
  7. @Id
  8. @Column(name = "id")
  9. @GeneratedValue(strategy = GenerationType.IDENTITY)
  10. private long id;
  11. @Column(name = "pid")
  12. private long pid;
  13. @Column(name = "description")
  14. private String description;
  15. public long getId() {
  16. return id;
  17. }
  18. public void setId(long id) {
  19. this.id = id;
  20. }
  21. public long getPid() {
  22. return pid;
  23. }
  24. public void setPid(long pid) {
  25. this.pid = pid;
  26. }
  27. public String getDescription() {
  28. return description;
  29. }
  30. public void setDescription(String description) {
  31. this.description = description;
  32. }
  33. }

b、添加repository

package com.slin.repository;

import com.slin.entity.PositionDetail;
import org.springframework.data.jpa.repository.JpaRepository;

public interface PositionDetailRepository extends JpaRepository<PositionDetail,Long> {

}

c、添加配置信息

application-sharding-database.properties中添加分片的配置信息
image.png

######datasource(数据源,有两个库)#######
spring.shardingsphere.datasource.names=ds0,ds1

######配置第一个库#######
#使用连接池
spring.shardingsphere.datasource.ds0.type=com.zaxxer.hikari.HikariDataSource
#使用驱动
spring.shardingsphere.datasource.ds0.driver-class-name=com.mysql.jdbc.Driver
#数据库连接(如果是服务器的就只需要把localhost改为服务器的ip即可)
spring.shardingsphere.datasource.ds0.jdbc-url=jdbc:mysql://localhost:3306/lagou1
#数据库用户和密码
spring.shardingsphere.datasource.ds0.username=root
spring.shardingsphere.datasource.ds0.password=root

######配置第二个库#######
spring.shardingsphere.datasource.ds1.type=com.zaxxer.hikari.HikariDataSource
spring.shardingsphere.datasource.ds1.driver-class-name=com.mysql.jdbc.Driver
spring.shardingsphere.datasource.ds1.jdbc-url=jdbc:mysql://localhost:3306/lagou2
spring.shardingsphere.datasource.ds1.username=root
spring.shardingsphere.datasource.ds1.password=root



###########sharding-database(切分的策略)########
#position表按库分(database-strategy),分片键是id
spring.shardingsphere.sharding.tables.position.database-strategy.inline.sharding-column=id
#如何定位呢,是根据ds$->{id % 2}来定位
spring.shardingsphere.sharding.tables.position.database-strategy.inline.algorithm-expression=ds$->{id % 2}

#position_detail表按库分(database-strategy),分片键是pid(其实是上面的id)
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.sharding-column=pid
#如何定位呢,是根据ds$->{pid % 2}来定位
spring.shardingsphere.sharding.tables.position_detail.database-strategy.inline.algorithm-expression=ds$->{pid % 2}



########对position表的操作###########
#id的主键生成器(配置之后就会采用系统内置的雪花算法)
spring.shardingsphere.sharding.tables.position.key-generator.column=id
#spring.shardingsphere.sharding.tables.position.key-generator.type=SNOWFLAKE
#改为自定义的主键类型
spring.shardingsphere.sharding.tables.position.key-generator.type=LAGOUKEY

########对position_detail表的操作###########
#id的主键生成器(配置之后就会采用系统内置的雪花算法)
spring.shardingsphere.sharding.tables.position_detail.key-generator.column=id
spring.shardingsphere.sharding.tables.position_detail.key-generator.type=SNOWFLAKE

d、添加测试类

package com.slin.test;

import com.slin.RunBoot;
import com.slin.entity.Position;
import com.slin.entity.PositionDetail;
import com.slin.repository.PositionDetailRepository;
import com.slin.repository.PositionRepository;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;


//通过它来启动
@RunWith(SpringRunner.class)
//通过RunBoot来创建boot容器
@SpringBootTest(classes = RunBoot.class)
public class TestSharding {

    @Resource
    private PositionRepository positionRepository;

    @Resource
    private PositionDetailRepository positionDetailRepository;

    @Test
    public void testAdd2(){
        for(int i=1;i<=20;i++){
            Position position = new Position();
            // position.setId(i);
            position.setName("lagou"+i);
            position.setSalary("1000000");
            position.setCity("beijing");
            positionRepository.save(position);

            PositionDetail positionDetail = new PositionDetail();
            positionDetail.setPid(position.getId());
            positionDetail.setDescription("this is test"+i);
            positionDetailRepository.save(positionDetail);
        }
    }
}

e、效果图查看

一张大表成功拆到同一个库(lagou1库)的两张表
后面查询一条完整信息,就不用担心垮库的问题了

image.png image.png
总结:表的分片规则很重要,必须在同一个库中(查询时候就还是相当于在一个表中)

f、查询SQL样例

在repository中可以添加以下信息,进行查询展示
@Query(nativeQuery = true,value = “select p.id,p.name,p.salary,p.city,pd.description from position p join position_detail pd on(p.id=pd.pid) where p.id=:id”) public Object findPositionsById(@Param(“id”) long id);