Spring Boot:如何使用多个模式并动态选择在运行时为每个请求使用哪个模式

时间:2016-06-02 21:17:46

标签: java database-design spring-boot

前提: 我选择这样做是因为我最终可能会有几千个模式,每个模式都有(其中包括)1个包含几百万个条目的表。另一种选择是(在其他情况下)一个表中有一个模式中有几十亿个条目。

详细阐述这个问题的最佳方法是提供一个简单的例子。请考虑以下事项:

User.java

@Entity(name = "user")
public class User {
    @Id
    @GeneratedValue
    @Column(name = "id")
    private Long id;

    @Column(name = "username")
    private String username;

    // getters and setters...
}

UserDao.java

@Repository
public interface UserDao extends CrudRepository<User, Long> {}

UserService.java

public interface UserService {
    User getUser(Long id);
}

UserServiceBean.java

@Transactional
@Service
public class UserServiceBean implements UserService {
    @Autowired
    private UserDao dao;

    @Override
    public User getUser(Long id) {
        return dao.findOne(id);
    }
}

UserController.java

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @RequestMapping(
            value = "/api/users/{id}",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<User> getUser(
            @PathVariable("id") Long id) {

        User user = userService.getUser(id);
        return new ResponseEntity<User>(user, HttpStatus.OK);
    }
}

我想扩展到以下功能:在URL中提供另一个ID,以便从不同的表返回用户数据。

UserController.java

...
@RequestMapping(
            value = "/api/users/{id}",
            method = RequestMethod.GET,
            produces = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<User> getUser(
            @PathVariable("id") Long id,
            @RequestParam(value = "tlbid") Long tblId) {

        User user = userService.getUser(id, tblId);
        return new ResponseEntity<User>(user, HttpStatus.OK);
    }

现在,UserService会将该ID解码为可能对spring有用的内容,以便从不同的表中获取数据。

UserServiceBean.java

    ...
    public User getUser(Long id, Long tblId) {
        Object o = doMagic(tblId);
        // What should 'o' be and how could I use this?
    }

所有表格具有相同的结构和名称,但条目不同。这些表必须位于不同的数据库中,或位于同一数据库中,但位于不同的模式上。

我想知道:

a)我如何拥有一个数据库连接并为每个请求指定不同的模式。

b)如何在必要时创建新的数据库连接(我会为进一步的请求维护它们),并指定每次请求应该在哪个连接上。

c)我的前提是错误的,在表中有数十亿条目,高并发性并不会显着降低查询速度。

2 个答案:

答案 0 :(得分:1)

如果您使用的是休眠实体类,那么只要数据源中映射的特定用户可以访问其他模式,就可以始终对同一数据源使用不同的模式。

您可以在实体类中使用schema批注的Table属性。使用以下语法来使用不同的模式

@Table(name="TABLE_NAME",schema="SCHEMA2")

答案 1 :(得分:0)

听起来您正在描述多租户解决方案。有关详细说明,请参见the Hibernate documentation,有关如何分区数据的一些选择。

注意:我们目前正在尝试实现基于架构的多租户方法:)