Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join

License

NotificationsYou must be signed in to change notification settings

dromara/easy-query

Repository files navigation

MavenApache 2jdk-8jdk-11jdk-17

Gitee starGithub starfork

📚 documentation

🐧 QQGroup:170029046

Five Implicit Features 🔥🔥🔥

  • Implicit Join - Automatically implements join queries for OneToOne and ManyToOne relationships, supporting filtering, sorting, and result fetching
  • Implicit Subquery - Automatically handles subqueries for OneToMany and ManyToMany relationships, supporting filtering, sorting, and aggregate function results
  • Implicit Grouping - Optimizes and merges multiple subqueries into grouped queries for OneToMany and ManyToMany relationships, supporting filtering, sorting, and aggregate functions
  • Implicit Partition Grouping - Enables first/Nth element operations for OneToMany and ManyToMany relationships, supporting filtering, sorting, and aggregate function results
  • Implicit CASE WHEN Expression - property.aggregate.filter() syntax, e.g., o.age().sum().filter(()->o.name().like("123"))

Company OneToManySysUser

Implicit Join

List<SysUser>userInXXCompany =entityQuery.queryable(SysUser.class)        .where(user -> {user.company().name().like("xx Company");        })        .orderBy(user -> {user.company().registerMoney().desc();user.birthday().asc();        }).toList();

Implicit Subquery

List<Company>companies =entityQuery.queryable(Company.class)        .where(company -> {company.users().any(u ->u.name().like("Xiao Ming"));company.users().where(u ->u.name().like("Xiao Ming"))                  .max(u ->u.birthday()).gt(LocalDateTime.now());        }).toList();

Implicit Grouping

List<Company>companies =entityQuery.queryable(Company.class)// Two subqueries in where will be merged        .manyJoin(company ->company.users())        .where(company -> {company.users().any(u ->u.name().like("Xiao Ming"));company.users().where(u ->u.name().like("Xiao Ming"))                  .max(u ->u.birthday()).gt(LocalDateTime.now());        }).toList();

Implicit Partition Grouping

List<Company>companies =entityQuery.queryable(Company.class)        .where(company -> {company.users().orderBy(u->u.birthday().desc()).first().name().eq("Xiao Ming");company.users().orderBy(u->u.birthday().desc()).element(0)                  .birthday().lt(LocalDateTime.now());        }).toList();

Implicit CASE WHEN Expression

List<Draft2<LocalDateTime,Long>>customVO =entityQuery.queryable(SysUser.class)        .where(user -> {user.birthday().lt(LocalDateTime.now());        }).groupBy(user ->GroupKeys.of(user.companyId()))        .select(group ->Select.DRAFT.of(group.groupTable().birthday().max().filter(() -> {group.groupTable().name().like("Xiao Ming");                }),group.groupTable().id().count().filter(() -> {group.groupTable().birthday().ge(LocalDateTime.of(2024,1,1,0,0));                })        )).toList();

Complete Single-Table Example

First, let's look at a complete single-table query example involving filtering, aggregation, aggregate filtering, projection, and sorting.

List<Draft3<String,Integer,LocalDateTime>>myBlog =easyEntityQuery.queryable(BlogEntity.class)        .where(b -> {b.content().like("my blog");        })        .groupBy(b ->GroupKeys.of(b.title()))        .having(group -> {group.groupTable().star().sum().lt(10);        })// The select statement will wrap previous expressions as an inline view (t1 table)// If no subsequent chained operations exist, it will expand directly        .select(group ->Select.DRAFT.of(group.key1(),// value1group.groupTable().star().sum().asAnyType(Integer.class),// value2group.groupTable().createTime().max()// value3        ))// If no orderBy is added, no inline view (t1 table) SQL will be generated// Because orderBy operates on the previous select results        .orderBy(group ->group.value3().desc())        .limit(2,2)// Apply result pagination        .toList();--第1条sql数据SELECTt1.`value1`AS `value1`,t1.`value2`AS `value2`,t1.`value3`AS `value3`FROM    (SELECTt.`title`AS `value1`,SUM(t.`star`)AS `value2`,MAX(t.`create_time`)AS `value3`FROM        `t_blog`tWHEREt.`deleted` =falseANDt.`content`LIKE'%my blog%'GROUPBYt.`title`HAVINGSUM(t.`star`) <10)t1ORDERBYt1.`value3`DESCLIMIT2,2

Dependency

entity use@EntityProxy or@EntityFileProxy annotation then build project apt will auto generate java code for proxy

<properties>  <easy-query.version>last-version</easy-query.version></properties><dependency><groupId>com.easy-query</groupId><artifactId>sql-api-proxy</artifactId><version>${easy-query.version}</version></dependency><dependency><groupId>com.easy-query</groupId><artifactId>sql-mysql</artifactId><version>${easy-query.version}</version></dependency>

🚀 Introduction

Usage-Guide

easy-query 🚀 is a high-performance, lightweight, and versatile Java/Kotlin object query ORM framework that supports database sharding and read-write separation.

Overview

easy-query is a dependency-free JAVA/Kotlin ORM framework, extremely lightweight, with high performance. It supports single table queries, multi-table queries, union, subqueries, pagination, dynamic table names, VO object query returns, logical deletion, global interception, database column encryption (supporting high-performance LIKE queries), data tracking for differential updates, optimistic locking, multi-tenancy, automatic database sharding, automatic table sharding, read-write separation, and supports full-featured external extension customization of the framework, with strong-typed expressions.

Get-Latest-Version

https://central.sonatype.com/ searchcom.easy-query获取最新Installation包

single table preview

List<Draft3<String,Integer,LocalDateTime>>myBlog =easyEntityQuery.queryable(BlogEntity.class)        .where(b -> {b.content().like("my blog");//other conditions//b.id().eq("123");        })        .groupBy(b ->GroupKeys.of(b.title()))        .having(group -> {group.groupTable().star().sum().lt(10);        })// The select clause will wrap the select and previous expressions into a nested view (t1 table).// If there are no subsequent chained operations, it will expand directly; otherwise, it will be represented as a nested view (t1 table).        .select(group ->Select.DRAFT.of(group.key1(),//value1group.groupTable().star().sum().asAnyType(Integer.class),//value2group.groupTable().createTime().max()//value3        ))// If orderBy is not added, no nested view (t1 table) SQL will be generated// because orderBy operates on the results of the preceding select        .orderBy(group ->group.value3().desc())// Apply result limit restrictionslimit(2,2)        .toList();SELECTt1.`value1`AS `value1`,t1.`value2`AS `value2`,t1.`value3`AS `value3`FROM    (SELECTt.`title`AS `value1`,SUM(t.`star`)AS `value2`,MAX(t.`create_time`)AS `value3`FROM        `t_blog`tWHEREt.`deleted` =falseANDt.`content`LIKE'%my blog%'GROUPBYt.`title`HAVINGSUM(t.`star`) <10)t1ORDERBYt1.`value3`DESCLIMIT2,2

Installation

Here is the usage guide for spring-boot environment and console mode.

spring-boot

<properties>  <easy-query.version>last-version</easy-query.version></properties><dependency>    <groupId>com.easy-query</groupId>    <artifactId>sql-springboot-starter</artifactId>    <version>${easy-query.version}</version></dependency>

console

for mysql

<properties>  <easy-query.version>last-version</easy-query.version></properties><dependency><groupId>com.easy-query</groupId><artifactId>sql-api-proxy</artifactId><version>${easy-query.version}</version></dependency><!-- required data base dialect--><dependency><groupId>com.easy-query</groupId><artifactId>sql-mysql</artifactId><version>${easy-query.version}</version></dependency>
//init DataSourceHikariDataSourcedataSource=newHikariDataSource();dataSource.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/easy-query-test?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true");dataSource.setUsername("root");dataSource.setPassword("root");dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setMaximumPoolSize(20);//property api clientEasyQueryClienteasyQueryClient=EasyQueryBootstrapper.defaultBuilderConfiguration()         .setDataSource(dataSource)         .useDatabaseConfigure(newMySQLDatabaseConfiguration())         .build();//entity query apiEasyEntityQueryeasyEntityQuery=newDefaultEasyEntityQuery(easyQueryClient);

Getting-Started

sql script

createtablet_topic(  idvarchar(32)not null comment'主键ID'primary key,  starsintnot null comment'点赞数',  titlevarchar(50)null comment'标题',  create_time datetimenot null comment'创建时间')comment'主题表';createtablet_blog(  idvarchar(32)not null comment'主键ID'primary key,  deletedtinyint(1) default0not null comment'是否Delete',  create_byvarchar(32)not null comment'创建人',  create_time datetimenot null comment'创建时间',  update_byvarchar(32)not null comment'更新人',  update_time datetimenot null comment'更新时间',  titlevarchar(50)not null comment'标题',  contentvarchar(256)null comment'内容',  urlvarchar(128)null comment'博客链接',  starintnot null comment'点赞数',  publish_time datetimenull comment'发布时间',  scoredecimal(18,2)not null comment'评分',  statusintnot null comment'状态',`order`decimal(18,2)not null comment'排序',  is_toptinyint(1)not null comment'是否置顶',  toptinyint(1)not null comment'是否置顶')comment'博客表';

query entity

@DatapublicclassBaseEntityimplementsSerializable {privatestaticfinallongserialVersionUID = -4834048418175625051L;@Column(primaryKey =true)privateStringid;/**   * 创建时间;创建时间   */privateLocalDateTimecreateTime;/**   * Update时间;Update时间   */privateLocalDateTimeupdateTime;/**   * 创建人;创建人   */privateStringcreateBy;/**   * Update人;Update人   */privateStringupdateBy;/**   * 是否Delete;是否Delete   */@LogicDelete(strategy =LogicDeleteStrategyEnum.BOOLEAN)privateBooleandeleted;}@Data@Table("t_topic")@EntityProxy//or @EntityFileProxy@ToStringpublicclassTopicimplementsProxyEntityAvailable<Topic ,TopicProxy> {@Column(primaryKey =true)privateStringid;privateIntegerstars;privateStringtitle;privateLocalDateTimecreateTime;}//The ProxyEntityAvailable interface can be quickly generated using the IDEA plugin EasyQueryAssistant.@Data@Table("t_blog")@EntityProxy//or @EntityFileProxypublicclassBlogEntityextendsBaseEntityimplementsProxyEntityAvailable<BlogEntity ,BlogEntityProxy>{/**   * 标题   */privateStringtitle;/**   * 内容   */privateStringcontent;/**   * 博客链接   */privateStringurl;/**   * 点赞数   */privateIntegerstar;/**   * 发布时间   */privateLocalDateTimepublishTime;/**   * 评分   */privateBigDecimalscore;/**   * 状态   */privateIntegerstatus;/**   * 排序   */privateBigDecimalorder;/**   * 是否置顶   */privateBooleanisTop;/**   * 是否置顶   */privateBooleantop;}

Single-Table-Query

Topictopic =easyEntityQuery                .queryable(Topic.class)                .where(o ->o.id().eq("3"))                .firstOrNull();
==> Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tWHERE t.`id`= ?LIMIT1==> Parameters:3(String)<==Time Elapsed:15(ms)<== Total:1

Multi-Table-Query

Topictopic =entityQuery               .queryable(Topic.class)               .leftJoin(BlogEntity.class, (t,t1) ->t.id().eq(t1.id()))               .where(o -> {o.id().eq("3");o.title().eq("4");                })               .firstOrNull();
==> Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tLEFT JOIN`t_blog` t1ON t1.`deleted`= ?AND t.`id`= t1.`id`WHERE t.`id`= ?AND t.`title`= ?LIMIT1==> Parameters: false(Boolean),3(String),4(String)<==Time Elapsed:2(ms)<== Total:1

Complex-Query

join + group +page

EasyPageResult<BlogEntity>page =easyEntityQuery        .queryable(Topic.class)        .innerJoin(BlogEntity.class,(t1,t2)->t1.id().eq(t2.id()))        .where((t1,t2)->t2.title().isNotNull())        .groupBy((t1,t2)->GroupKeys.TABLE2.of(t2.id()))        .select(g->{BlogEntityProxyr =newBlogEntityProxy();r.id().set(g.key1());r.score().set(g.sum(g.group().t2.score()));returnr;        })        .toPageResult(1,20);
==> Preparing:SELECTCOUNT(*)FROM (SELECT t1.`id`AS`id`,SUM(t1.`score`)AS`score`FROM`t_topic` tINNER JOIN`t_blog` t1ON t1.`deleted`= ?AND t.`id`= t1.`id`WHERE t1.`title`IS NOT NULLGROUP BY t1.`id`) t2==> Parameters: false(Boolean)<==Time Elapsed:4(ms)<== Total:1==> Preparing:SELECT t1.`id`AS`id`,SUM(t1.`score`)AS`score`FROM`t_topic` tINNER JOIN`t_blog` t1ON t1.`deleted`= ?AND t.`id`= t1.`id`WHERE t1.`title`IS NOT NULLGROUP BY t1.`id`LIMIT20==> Parameters: false(Boolean)<==Time Elapsed:2(ms)<== Total:20

Dynamic-Table-Names

easyEntityQuery.queryable(BlogEntity.class)        .asTable(a->"aa_bb_cc")        .where(o ->o.id().eq("123"))        .toList();
SELECT t.`id`,t.`create_time`,t.`update_time`,t.`create_by`,t.`update_by`,t.`deleted`,t.`title`,t.`content`,t.`url`,t.`star`,t.`publish_time`,t.`score`,t.`status`,t.`order`,t.`is_top`,t.`top`FROM`aa_bb_cc` tWHERE t.`deleted`= ?AND t.`id`= ?

Insert

Topictopic =newTopic();topic.setId(String.valueOf(0));topic.setStars(100);topic.setTitle("标题0");topic.setCreateTime(LocalDateTime.now().plusDays(i));longrows =easyEntityQuery.insertable(topic).executeRows();
//返回结果rows为1==> Preparing:INSERT INTO`t_topic` (`id`,`stars`,`title`,`create_time`)VALUES (?,?,?,?)==> Parameters:0(String),100(Integer),标题0(String),2023-03-16T21:34:13.287(LocalDateTime)<== Total:1

Update

//实体更新Topictopic =easyEntityQuery.queryable(Topic.class)        .where(o ->o.id().eq("7")).firstNotNull("未找到对应的数据");StringnewTitle ="test123" +newRandom().nextInt(100);topic.setTitle(newTitle);longrows=easyEntityQuery.updatable(topic).executeRows();
==> Preparing:UPDATE t_topicSET`stars`= ?,`title`= ?,`create_time`= ?WHERE`id`= ?==> Parameters:107(Integer),test12364(String),2023-03-27T22:05:23(LocalDateTime),7(String)<== Total:1
//表达式更新longrows =easyEntityQuery.updatable(Topic.class)                    .setColumns(o->{o.stars().set(12);                    })                    .where(o->o.id().eq("2"))                    .executeRows();//rows为1easyEntityQuery.updatable(Topic.class)        .setColumns(o->{o.stars().set(12);        })        .where(o->o.id().eq("2"))                    .executeRows(1,"更新失败");//判断受影响行数并且进行报错,如果当前操作不在事务内执行那么会自动开启事务!!!会自动开启事务!!!会自动开启事务!!!来实现并发更新控制,异常为:EasyQueryConcurrentException//抛错后数据将不会被更新
==> Preparing:UPDATE t_topicSET`stars`= ?WHERE`id`= ?==> Parameters:12(Integer),2(String)<== Total:1

Delete

longl =easyQuery.deletable(Topic.class)                    .where(o->o.title().eq("title998"))                    .executeRows();
==> Preparing:DELETEFROM t_topicWHERE`title`= ?==> Parameters: title998(String)<== Total:1
Topictopic =easyQuery.queryable(Topic.class).whereId("997").firstNotNull("未找到当前主题数据");longl =easyQuery.deletable(topic).executeRows();
==> Preparing:DELETEFROM t_topicWHERE`id`= ?==> Parameters:997(String)<== Total:1

Union-ALL-Query

Queryable<Topic>q1 =easyQuery                .queryable(Topic.class);Queryable<Topic>q2 =easyQuery        .queryable(Topic.class);Queryable<Topic>q3 =easyQuery        .queryable(Topic.class);List<Topic>list =q1.union(q2,q3).where(o ->o.eq(Topic::getId,"123321")).toList();
==> Preparing:SELECT t1.`id`,t1.`stars`,t1.`title`,t1.`create_time`FROM (SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tUNIONSELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tUNIONSELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` t) t1WHERE t1.`id`= ?==> Parameters:123321(String)<==Time Elapsed:19(ms)<== Total:0

Subquery

inSubquery

EntityQueryable<StringProxy,String>idQuery =easyEntityQuery.queryable(BlogEntity.class)        .where(o ->o.id().eq("1" ))        .select(o ->newStringProxy(o.id()));List<Topic>list1 =easyEntityQuery.queryable(Topic.class)        .where(o ->o.id().in(idQuery))        .toList();
==> Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tWHERE t.`id`IN (SELECT t1.`id`FROM`t_blog` t1WHERE t1.`deleted`= ?AND t1.`id`= ?)==> Parameters: false(Boolean),1(String)<==Time Elapsed:6(ms)<== Total:1

existsSubquery

EntityQueryable<BlogEntityProxy,BlogEntity>where =easyEntityQuery.queryable(BlogEntity.class)        .where(o ->o.id().eq("1" ));List<Topic>list2 =easyEntityQuery.queryable(Topic.class)        .where(o -> {o.exists(() ->where.where(q ->q.id().eq(o.id())));        }).toList();
==> Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic` tWHERE EXISTS (SELECT1FROM`t_blog` t1WHERE t1.`deleted`= ?AND t1.`id`= ?AND t1.`id`= t.`id`)==> Parameters: false(Boolean),1(String)<==Time Elapsed:2(ms)<== Total:1

Sharding

easy-query支持Table Sharding、Database Sharding、Table Sharding+Database Sharding

Table-Sharding

//创建Sharding对象@Data@Table(value ="t_topic_sharding_time",shardingInitializer =TopicShardingTimeShardingInitializer.class)@ToStringpublicclassTopicShardingTime {@Column(primaryKey =true)privateStringid;privateIntegerstars;privateStringtitle;@ShardingTableKeyprivateLocalDateTimecreateTime;}//Sharding初始化器很简单 假设我们是2020年1月到2023年5月也就是当前时间进行Sharding那么要生成对应的Sharding表每月一张publicclassTopicShardingTimeShardingInitializerextendsAbstractShardingMonthInitializer<TopicShardingTime> {@OverrideprotectedLocalDateTimegetBeginTime() {returnLocalDateTime.of(2020,1,1,1,1);    }@OverrideprotectedLocalDateTimegetEndTime() {returnLocalDateTime.of(2023,5,1,0,0);    }@Overridepublicvoidconfigure0(ShardingEntityBuilder<TopicShardingTime>builder) {////以下条件可以选择配置也可以不配置用于优化Sharding性能//        builder.paginationReverse(0.5,100)//                .ascSequenceConfigure(new TableNameStringComparator())//                .addPropertyDefaultUseDesc(TopicShardingTime::getCreateTime)//                .defaultAffectedMethod(false, ExecuteMethodEnum.LIST,ExecuteMethodEnum.ANY,ExecuteMethodEnum.COUNT,ExecuteMethodEnum.FIRST)//                .useMaxShardingQueryLimit(2,ExecuteMethodEnum.LIST,ExecuteMethodEnum.ANY,ExecuteMethodEnum.FIRST);    }}//Sharding时间路由规则按月然后beanSharding属性就是LocalDateTime也可以自定义实现publicclassTopicShardingTimeTableRouteextendsAbstractMonthTableRoute<TopicShardingTime> {@OverrideprotectedLocalDateTimeconvertLocalDateTime(ObjectshardingValue) {return (LocalDateTime)shardingValue;    }}

数据库脚本参考源码

其中shardingInitializer为Sharding初始化器用来初始化告诉框架有多少Sharding的表名(支持动态添加)

ShardingTableKey表示哪个字段作为Sharding键(Sharding键不等于主键)

执行sql

LocalDateTimebeginTime =LocalDateTime.of(2021,1,1,1,1);LocalDateTimeendTime =LocalDateTime.of(2021,5,2,1,1);Durationbetween =Duration.between(beginTime,endTime);longdays =between.toDays();List<TopicShardingTime>list =easyQuery.queryable(TopicShardingTime.class)        .where(o->o.rangeClosed(TopicShardingTime::getCreateTime,beginTime,endTime))        .orderByAsc(o ->o.column(TopicShardingTime::getCreateTime))        .toList();
==> SHARDING_EXECUTOR_2, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_time_202101` tWHERE t.`create_time`>= ?AND t.`create_time`<= ?ORDER BY t.`create_time`ASC==> SHARDING_EXECUTOR_3, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_time_202102` tWHERE t.`create_time`>= ?AND t.`create_time`<= ?ORDER BY t.`create_time`ASC==> SHARDING_EXECUTOR_2, name:ds2020, Parameters:2021-01-01T01:01(LocalDateTime),2021-05-02T01:01(LocalDateTime)==> SHARDING_EXECUTOR_3, name:ds2020, Parameters:2021-01-01T01:01(LocalDateTime),2021-05-02T01:01(LocalDateTime)<== SHARDING_EXECUTOR_3, name:ds2020,Time Elapsed:3(ms)<== SHARDING_EXECUTOR_2, name:ds2020,Time Elapsed:3(ms)==> SHARDING_EXECUTOR_2, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_time_202103` tWHERE t.`create_time`>= ?AND t.`create_time`<= ?ORDER BY t.`create_time`ASC==> SHARDING_EXECUTOR_3, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_time_202104` tWHERE t.`create_time`>= ?AND t.`create_time`<= ?ORDER BY t.`create_time`ASC==> SHARDING_EXECUTOR_2, name:ds2020, Parameters:2021-01-01T01:01(LocalDateTime),2021-05-02T01:01(LocalDateTime)==> SHARDING_EXECUTOR_3, name:ds2020, Parameters:2021-01-01T01:01(LocalDateTime),2021-05-02T01:01(LocalDateTime)<== SHARDING_EXECUTOR_3, name:ds2020,Time Elapsed:2(ms)<== SHARDING_EXECUTOR_2, name:ds2020,Time Elapsed:2(ms)==> main, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_time_202105` tWHERE t.`create_time`>= ?AND t.`create_time`<= ?ORDER BY t.`create_time`ASC==> main, name:ds2020, Parameters:2021-01-01T01:01(LocalDateTime),2021-05-02T01:01(LocalDateTime)<== main, name:ds2020,Time Elapsed:2(ms)<== Total:122

Database-Sharding

@Data@Table(value ="t_topic_sharding_ds",shardingInitializer =DataSourceAndTableShardingInitializer.class)@ToStringpublicclassTopicShardingDataSource {@Column(primaryKey =true)privateStringid;privateIntegerstars;privateStringtitle;@ShardingDataSourceKeyprivateLocalDateTimecreateTime;}publicclassDataSourceShardingInitializerimplementsEntityShardingInitializer<TopicShardingDataSource> {@Overridepublicvoidconfigure(ShardingEntityBuilder<TopicShardingDataSource>builder) {EntityMetadataentityMetadata =builder.getEntityMetadata();StringtableName =entityMetadata.getTableName();List<String>tables =Collections.singletonList(tableName);LinkedHashMap<String,Collection<String>>initTables =newLinkedHashMap<String,Collection<String>>() {{put("ds2020",tables);put("ds2021",tables);put("ds2022",tables);put("ds2023",tables);        }};builder.actualTableNameInit(initTables);    }}//Database Sharding数据源路由规则publicclassTopicShardingDataSourceRouteextendsAbstractDataSourceRoute<TopicShardingDataSource> {@OverrideprotectedRouteFunction<String>getRouteFilter(TableAvailabletable,ObjectshardingValue,ShardingOperatorEnumshardingOperator,booleanwithEntity) {LocalDateTimecreateTime = (LocalDateTime)shardingValue;StringdataSource ="ds" +createTime.getYear();switch (shardingOperator){caseGREATER_THAN:caseGREATER_THAN_OR_EQUAL:returnds->dataSource.compareToIgnoreCase(ds)<=0;caseLESS_THAN:            {//如果小于月初那么月初的表是不需要被查询的LocalDateTimetimeYearFirstDay =LocalDateTime.of(createTime.getYear(),1,1,0,0,0);if(createTime.isEqual(timeYearFirstDay)){returnds->dataSource.compareToIgnoreCase(ds)>0;                }returnds->dataSource.compareToIgnoreCase(ds)>=0;            }caseLESS_THAN_OR_EQUAL:returnds->dataSource.compareToIgnoreCase(ds)>=0;caseEQUAL:returnds->dataSource.compareToIgnoreCase(ds)==0;default:returnt->true;        }    }}
LocalDateTimebeginTime =LocalDateTime.of(2020,1,1,1,1);LocalDateTimeendTime =LocalDateTime.of(2023,5,1,1,1);Durationbetween =Duration.between(beginTime,endTime);longdays =between.toDays();EasyPageResult<TopicShardingDataSource>pageResult =easyQuery.queryable(TopicShardingDataSource.class)        .orderByAsc(o ->o.column(TopicShardingDataSource::getCreateTime))        .toPageResult(1,33);
==> SHARDING_EXECUTOR_23, name:ds2022, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_ds` tORDER BY t.`create_time`ASCLIMIT33==> SHARDING_EXECUTOR_11, name:ds2021, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_ds` tORDER BY t.`create_time`ASCLIMIT33==> SHARDING_EXECUTOR_2, name:ds2020, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_ds` tORDER BY t.`create_time`ASCLIMIT33==> SHARDING_EXECUTOR_4, name:ds2023, Preparing:SELECT t.`id`,t.`stars`,t.`title`,t.`create_time`FROM`t_topic_sharding_ds` tORDER BY t.`create_time`ASCLIMIT33<== SHARDING_EXECUTOR_4, name:ds2023,Time Elapsed:4(ms)<== SHARDING_EXECUTOR_23, name:ds2022,Time Elapsed:4(ms)<== SHARDING_EXECUTOR_2, name:ds2020,Time Elapsed:4(ms)<== SHARDING_EXECUTOR_11, name:ds2021,Time Elapsed:6(ms)<== Total:33

support

[博客](https://www.cnblogs.com/xuejiaming)

个人QQ:326308290(欢迎技术支持提供您宝贵的意见)

个人邮箱:326308290@qq.com

About

java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages


[8]ページ先頭

©2009-2025 Movatter.jp