- Notifications
You must be signed in to change notification settings - Fork56
java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join
License
dromara/easy-query
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
- 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
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();
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();
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();
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();
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();
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
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>
easy-query
🚀 is a high-performance, lightweight, and versatile Java/Kotlin object query ORM framework that supports database sharding and read-write separation.
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.
https://central.sonatype.com/ searchcom.easy-query
获取最新Installation包
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
Here is the usage guide for spring-boot environment and console mode.
<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>
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);
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;}
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
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
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
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`= ?
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
//实体更新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
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
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
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
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
easy-query
支持Table Sharding、Database Sharding、Table Sharding+Database 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
@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
个人QQ:326308290(欢迎技术支持提供您宝贵的意见)
个人邮箱:326308290@qq.com
About
java/kotlin high performance lightweight solution for jdbc query,support oltp and olap query,一款java下面支持强类型、轻量级、高性能的ORM,致力于解决jdbc查询,拥有对象模型筛选、隐式子查询、隐式join