利用SpEL 表达式实现简单的动态分表查询

这里的动态分表查询并不是动态构造sql语句,而是利用SpEL操作同一结构的不同张表。

也可以参考Spring Data Jpa中的章节http://docs.spring.io/spring-data/jpa/docs/1.11.3.RELEASE/reference/html/#jpa.query.spel-expressions

背景如下:

因为数据量较大,将数据按年份进行了分表,表结构都是一致的。例如现在有两张表分别表示2017/2018年数据

表中只有id和name两个字段

DROP TABLE IF EXISTS "public"."data_2017";
CREATE TABLE "public"."data_2017" (
"id" int4 NOT NULL,
"name" varchar(255) COLLATE "default"
)
WITH (OIDS=FALSE)

实际工作中们需要根据请求去选择查询17年的表还是18年的表。执行的sql语句除了表名不一致,其他均一致。

SELECT id,name FROM table

利用JPA实现

因为JPA中实体与表示一一对应的,而实际查询的语句又是一样的,那么如果按照传统JPA方法,就需要建立N个Entity,N个Repository,N个查询方法。

现在使用SpELl表达式可以简化Entity及Repository中的代码编写,相对提高效率。

1、建立一个抽象实体

/**
* Created by dingshuo on 2017/6/5.
*/
@MappedSuperclass
public class AbstractMappedType {
private int id;
private String name;
@Id
@Column(name = "id")
@JsonIgnore
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

2、建立17/18年表对应的实体,继承抽象实体

/**
* Created by dingshuo on 2017/6/5.
*/
@Entity
@Table(name = "DATA_2017", schema = "public", catalog = "powermanager")
public class Data2017 extends AbstractMappedType {
}
/**
* Created by dingshuo on 2017/6/5.
*/
@Entity
@Table(name = "DATA_2018", schema = "public", catalog = "powermanager")
public class Data2018 extends AbstractMappedType {
}

3、建立抽象Repository

/**
* Created by dingshuo on 2017/6/5.
*/
@NoRepositoryBean
public interface MappedTypeRepository<T extends AbstractMappedType>
extends Repository<T, Long> {
@Query("select t from #{#entityName} t where t.id = ?1")
List<T> findById(int id);
@Query("select t from #{#entityName} t ")
List<T> findALL();
}

4、建立17年实体的Repository,继承抽象Repository

/**
* Created by dingshuo on 2017/6/5.
*/
public interface Data2017Repository extends MappedTypeRepository<Data2017>{
}

5、测试

@RestController
public class TestController {
@Autowired
Data2017Repository repository;
@GetMapping(value = "/test")
public String test(){
List<Data2017> object=repository.findById(1);
List<Data2017> objec1t=repository.findALL();
return "OK";
}
}

如上就可以相对简化的使用JPA查询结构相同,表名不同的系列表数据了。

当然,还是得建立N个Entity和N个Repository,还是比较麻烦的。。

时间: 2024-11-05 14:40:19

利用SpEL 表达式实现简单的动态分表查询的相关文章

利用for循环制作简单的99乘法表

利用for循环制作简单的99乘法表 public class chengfabiao { public static void main(String[] args) { for(int a = 1;a <= 9;a++) { for(int b = 1; b <= a;b++) { int res = a * b; System.out.print("["+a+"x"+b+"="+res+"]"); } Syst

mysql如何查询多样同样的表/sql分表查询、java项目日志表分表的开发思路/按月分表

之前开发的一个监控系统,数据库的日志表是单表,虽然现在数据还不大并且做了查询sql优化,不过以后数据库的日志表数据肯定会越来越庞大,将会导致查询缓慢,所以把日志表改成分表,日志表可以按时间做水平分表,我是按月分的,每个月一张表,这时候的问题是 数据库有多张同样的分表如何根据条件查询? 在进行分页的时候如何计算总记录数?如何查询出所有分表? 每个月的新表是如何创建?系统如何自动创建? 不确定哪个分表的情况如何查询某一条详细记录? 分表查询分表查询可以用union或者union all进行查询uni

4:分表查询

4.1分表查询(等值连接) FROM employees,departments WHERE employees.department_id=departments.department_id; #案例3:查询员工名,工种号,工种名 #为表名起别名,简洁,一旦使用了别名,则不能使用原来的表名了. SELECT last_name,e.job_id,job_title FROM employees e,jobs j WHERE e.job_id = j.job_id; #4,可以加筛选吗? #案例

超简单理解分库分表

目录 一.为什么要做分库分表 二.如何进行数据分片 1.垂直切分 2.水平切分(重点) 三.数据切分后会出现的问题 数据源管理的问题 一.为什么要做分库分表 在数据爆炸的年代,单表数据达到千万级别,甚至过亿的量,都是很常见的情景.这时候再对数据库进行操作就是非常吃力的事情了,select个半天都出不来数据,这时候业务已经难以维系.不得已,分库分表提上日程,我们的目的很简单,减小数据库的压力,缩短表的操作时间. 二.如何进行数据分片 数据切分(Sharding),简单的来说,就是通过某种特定的条件

mysql分表+查询

垂直分表: 其实没啥好讲,就是 主键+常用列 放在原表中,再讲 主键+一些不常用列 放在另外的表中. 这样一个数据页就可以存放更多数据. 但是缺点也明显,可能会增加join 或 union之类的操作. 水平分表: 今天面试被问到水平分表,突然愣住了,分都知道,但分完如何有效查询就不好说了. 原则:具体情况具体分析. 常见几种分法: 1.按时间分 典型应用:新闻类.qq状态.朋友圈动态等关注实时或最近的,可以用时间划分,比如当月一张表,上个月一张表. 2.按区间分 通常每张表都会有个自增id,可以

mycat初次简单配置分库分表

先规划下数据库的基础架构,先来个最简单基础的. 三台虚机,各安装了mysql5.7 用mycat建立逻辑数据库,建立5个表格,其中一个表格分库,一个表格做全局表,剩余三个表格每个虚机的数据库各放一个. 统计信息: 三个虚机的IP分别为: 192.168.211.138 192.168.211.139 192.168.211.142 真实的dataNode就是这三个虚机啦. mysql的登录用户就用[email protected]%,密码都是:[email protected] mycat逻辑库

简单的动态顺序表实现

#pragma once #include <stdio.h> #include <assert.h> #include <malloc.h> #include <string.h> typedef int DateType; typedef struct SeqList {  DateType* _array;  size_t _size;  size_t _capacity; }SeqList; void InitSeqList(SeqList* pSe

简单的动态顺序表的实现

#pragma once #include <stdio.h> #include <assert.h> #include <malloc.h> #include <string.h> typedef int DateType; typedef struct SeqList {  DateType* _array;  size_t _size;  size_t _capacity; }SeqList; void InitSeqList(SeqList* pSe

简单的动态线性表

头文件 #ifndef __TEST_H__ #define __TEST_H__ #include<stdio.h> #include<string.h> #include<assert.h> #include<malloc.h> #define MAX 3   //方便测试给一个小空间 typedef int datatype; typedef struct Seqlist {  datatype *_Array;  size_t _size;  siz