日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

这应该是java最好用的orm之一了

發(fā)布時(shí)間:2024/1/18 windows 42 coder
生活随笔 收集整理的這篇文章主要介紹了 这应该是java最好用的orm之一了 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

這應(yīng)該是java最好用的orm之一了

說起orm大家肯定都不會(huì)陌生,作者是一個(gè).net菜鳥。并且是在.net繁榮的orm圈子下成長的,所以這次給大家?guī)淼氖擎敲纄fcore,freesql,sqlsugar的java的orm.如果你是一位.net轉(zhuǎn)java的開發(fā),或者是一名需要經(jīng)常和數(shù)據(jù)庫打交道的開發(fā)者和作者一樣是一名crud仔那么這個(gè)orm肯定是你不應(yīng)該錯(cuò)過的,我愿稱之為java最好用的orm之一。

介紹

easy-query

文檔地址 https://xuejm.gitee.io/easy-query-doc/

GITHUB地址 https://github.com/xuejmnet/easy-query

GITEE地址 https://gitee.com/xuejm/easy-query

復(fù)雜sql一

話不多說來一個(gè)復(fù)雜sql

        SELECT
        YEAR(日期) AS 年份,
        MONTH(日期) AS 月份
        SUM(收入) AS 月收入
        FROM
                your_table
        WHERE
        日期 >= CURDATE()- INTERVAL 3 MONTH
        GROUP BY
        年份,月份
        ORDER BY
        年份,月份;

用java的寫法寫sql,并且函數(shù)自適應(yīng)easy-query支持的所有數(shù)據(jù)庫,切庫0成本

List<Draft3<Integer, Integer, Integer>> list = easyEntityQuery.queryable(BlogEntity.class)
          .where(o -> o.createTime().gt(o._now().plusMonths(-3))) //WHERE 日期 >= CURDATE()- INTERVAL 3 MONTH
          .groupBy(o -> GroupKeys.TABLE1.of(o.createTime().year(), o.createTime().month()))//GROUP BY 年份,月份
          .orderBy(o -> {
              o.key1().asc();  // ORDER BY 年份,月份;
              o.key2().asc();
          }).selectDraft(o -> Select.draft( //采用草稿類型
                  o.key1(), //YEAR(日期) AS 年份,
                  o.key2(), //MONTH(日期) AS 月份
                  o.sum(o.group().star())  //SUM(收入) AS 月收入
          )).toList();


==> Preparing: SELECT YEAR(t.`create_time`) AS `value1`,MONTH(t.`create_time`) AS `value2`,SUM(t.`star`) AS `value3` FROM `t_blog` t WHERE t.`deleted` = ? AND  t.`create_time` > date_add(NOW(), interval (?) month) GROUP BY YEAR(t.`create_time`),MONTH(t.`create_time`) ORDER BY YEAR(t.`create_time`) ASC,MONTH(t.`create_time`) ASC
==> Parameters: false(Boolean),-3(Integer)
<== Time Elapsed: 4(ms)
<== Total: 0

復(fù)雜sql二


select a.id,a.name
from table a
where (select count(*) as num from table b where b.box_id=a.id ) = 0

//條件里面不直接使用列

        List<Draft2<String, String>> list = easyEntityQuery.queryable(BlogEntity.class)
                .where(o -> {

                    Query<Long> longQuery = easyEntityQuery.queryable(Topic.class)
                            .where(x -> x.id().eq(o.id())).selectCount();//創(chuàng)建子查詢的count然后和0常量進(jìn)行比較

                    o.SQLParameter().valueOf(0L)
                            .eq(longQuery);
                }).selectDraft(o -> Select.draft(
                        o.id(),
                        o.url()
                )).toList();

==> Preparing: SELECT t.`id` AS `value1`,t.`url` AS `value2` FROM `t_blog` t WHERE t.`deleted` = ? AND ? = (SELECT COUNT(*) FROM `t_topic` t1 WHERE t1.`id` = t.`id`)
==> Parameters: false(Boolean),0(Long)

復(fù)雜sql三

//select 查詢子表聯(lián)結(jié)
select a,b,c,(select count(*) from a t1 where t.id=b.id) as xx from b


List<Draft3<String, String, Long>> list = easyEntityQuery.queryable(BlogEntity.class)
                .where(o -> {
                    o.id().eq("123");
                }).selectDraft(o -> Select.draft(
                        o.id(),
                        o.url(),
                        o.subQuery(() -> easyEntityQuery.queryable(Topic.class).where(x -> x.id().eq(o.id())).selectCount())
                )).toList();

==> Preparing: SELECT t.`id` AS `value1`,t.`url` AS `value2`,(SELECT COUNT(*) FROM `t_topic` t1 WHERE t1.`id` = t.`id`) AS `value3` FROM `t_blog` t WHERE t.`deleted` = ? AND t.`id` = ?
==> Parameters: false(Boolean),123(String)

可能會(huì)有人說這不就是拼sql嗎,對(duì)的你沒有說錯(cuò)就是但是這是強(qiáng)類型的并且是支持所有庫的,還有一點(diǎn)jpa你說無法控制sql你不想用,我這個(gè)框架完全自主控制sql支持強(qiáng)類型我想你應(yīng)該沒有拒絕的理由。

單表

//根據(jù)條件查詢表中的第一條記錄
List<Topic> topics = easyEntityProxy
                .queryable(Topic.class)
                .limit(1)
                .toList();
==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t LIMIT 1
<== Total: 1

//根據(jù)條件查詢表中的第一條記錄
Topic topic = easyEntityProxy
                .queryable(Topic.class)
                .firstOrNull();
==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t LIMIT 1
<== Total: 1 

//根據(jù)條件查詢id為3的記錄
Topic topic = easyEntityProxy
        .queryable(Topic.class)
        .where(o->o.id().eq("3"))
        .firstOrNull();
==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t WHERE t.`id` = ? LIMIT 1
==> Parameters: 3(String)
<== Total: 1


Topic topic = easyEntityProxy
        .queryable(Topic.class)
        .where(o->{
                o.id().eq("3");
                o.title().like("3");
        })
        .firstOrNull();
==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t WHERE t.`id` = ? AND t.`title` like ? LIMIT 1
==> Parameters: 3(String),%3%(String)
<== Total: 1

多表


Topic topic = easyEntityQuery
        .queryable(Topic.class)
        .leftJoin(BlogEntity.class, (t,b) -> t.id().eq(b.id()))
        .where((t,b) -> t.id().eq("3"))
        .firstOrNull();

==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t LEFT JOIN t_blog t1 ON t.`id` = t1.`id` WHERE t.`id` = ? LIMIT 1
==> Parameters: 3(String)
<== Total: 1

List<BlogEntity> blogEntities = easyEntityQuery
        .queryable(Topic.class)
        //join 后面是多參數(shù)委托,第一個(gè)主表,第二個(gè)參數(shù)為join表
        .innerJoin(BlogEntity.class, (t,b) -> t.id().eq(b.id()))
        .where((t,b) -> {
                t.title().isNotNull();
                b.id().eq("3");
        })
        //select 參數(shù)個(gè)數(shù)和join表個(gè)數(shù)一樣,group后參數(shù)為一個(gè),返回一個(gè)對(duì)象代理
        //可以對(duì)其進(jìn)行自定義賦值比如id().set(t.title())將title賦值給id屬性
        .select((t,b)->new BlogEntityProxy().selectAll(t))
        .toList();

==> Preparing: SELECT t1.`id`,t1.`create_time`,t1.`update_time`,t1.`create_by`,t1.`update_by`,t1.`deleted`,t1.`title`,t1.`content`,t1.`url`,t1.`star`,t1.`publish_time`,t1.`score`,t1.`status`,t1.`order`,t1.`is_top`,t1.`top` FROM t_topic t INNER JOIN t_blog t1 ON t.`id` = t1.`id` WHERE t1.`title` IS NOT NULL AND t.`id` = ?
==> Parameters: 3(String)
<== Total: 1

數(shù)據(jù)庫函數(shù)支持

提供了常用的字符串trim,leftPad,subString,toLower,isBank,nullOrDefault等,時(shí)間類型的format,druation,plus,year,month等函數(shù)...


            List<Topic> list2 = easyEntityQuery.queryable(Topic.class)
                    .where(o -> {
                        o.createTime().le(o.createTime().nullOrDefault(LocalDateTime.of(2022, 1, 1, 1, 1)));
                        o.id().isNotBank();
                        o.id().nullOrDefault("" ).eq(o.title().nullOrDefault(c -> c.column(o.id())));
                        o.title().isEmpty();
                    })
                    .toList();

==> Preparing: SELECT `id`,`stars`,`title`,`create_time` FROM `t_topic` WHERE  `create_time` <= IFNULL(`create_time`,?) AND (`id` IS NOT NULL AND `id` <> '' AND LTRIM(`id`) <> '') AND IFNULL(`id`,?) = IFNULL(`title`,`id`) AND (`title` IS NULL OR `title` = '')
==> Parameters: 2022-01-01T01:01(LocalDateTime),(String)
<== Time Elapsed: 4(ms)
<== Total: 2

//pgsql
Draft7<Long, Long, Long, Long, Long, Long, Long> draft3 = entityQuery.queryable(BlogEntity.class)
                .whereById(id)
                .selectDraft(o -> Select.draft(
                        o.createTime().duration(o.updateTime(), DateTimeDurationEnum.Days).abs(),//計(jì)算createTime和updateTime相差的天數(shù)如果createTime小則返回負(fù)數(shù) 因?yàn)槭莂bs所以返回的是肯定是相差天數(shù)
                        o.createTime().duration(o.updateTime(), DateTimeDurationEnum.Hours),//同理返回的是小時(shí)數(shù)
                        o.createTime().duration(o.updateTime(), DateTimeDurationEnum.Minutes),//同理返回分鐘數(shù)
                        o.createTime().duration(o.updateTime(), DateTimeDurationEnum.Seconds),//同理返回秒數(shù)
                        o.createTime().duration(o.createTime().plus(1,TimeUnit.DAYS), DateTimeDurationEnum.Days),//計(jì)算createTime和createTime加上1天后的相差天數(shù)
                        o.createTime().duration(o.createTime().plus(2,TimeUnit.SECONDS),DateTimeDurationEnum.Seconds),
                        o.createTime().duration(o.createTime().plus(3,TimeUnit.MINUTES),DateTimeDurationEnum.Minutes)
                )).firstOrNull();

==> Preparing: SELECT ABS((extract(epoch from (t."create_time")::timestamp-(t."update_time")::timestamp)/86400)::int) AS "value1",(extract(epoch from (t."create_time")::timestamp-(t."update_time")::timestamp)/3600)::int AS "value2",(extract(epoch from (t."create_time")::timestamp-(t."update_time")::timestamp)/60)::int AS "value3",(extract(epoch from (t."create_time")::timestamp-(t."update_time")::timestamp))::int AS "value4",(extract(epoch from (t."create_time")::timestamp-((t."create_time" + INTERVAL '86400 second'))::timestamp)/86400)::int AS "value5",(extract(epoch from (t."create_time")::timestamp-((t."create_time" + INTERVAL '2 second'))::timestamp))::int AS "value6",(extract(epoch from (t."create_time")::timestamp-((t."create_time" + INTERVAL '180 second'))::timestamp)/60)::int AS "value7" FROM "t_blog" t WHERE t."deleted" = ? AND t."id" = ? LIMIT 1
==> Parameters: false(Boolean),123456zz9(String)
<== Time Elapsed: 3(ms)
<== Total: 1

匿名類型平替

List<Draft4<String, String, String, String>> list = easyEntityQuery.queryable(Topic.class)
                .where(o -> {
                    o.title().subString(1, 2).eq("123");
                    o.title().toLower().subString(1, 2).eq("123");
                    o.title().toLower().toUpper().toLower().subString(1, 2).eq("123");
                    o.createTime()
                            .format("yyyy-MM")//日期先格式化
                            .toLower()//然后轉(zhuǎn)成小寫
                            .subString(1, 10)//分割從第一位
                            .like("023-01");
                })
                .selectDraft(o -> Select.draft(
                        o.id(),
                        o.title().toLower().replace("123","456"),
                        o.title().toUpper(),
                        o.title().toLower().subString(1, 2)
                ))
                .toList();

==> Preparing: SELECT t.`id` AS `value1`,REPLACE(LOWER(t.`title`),?,?) AS `value2`,UPPER(t.`title`) AS `value3`,SUBSTR(LOWER(t.`title`),2,2) AS `value4` FROM `t_topic` t WHERE SUBSTR(t.`title`,2,2) = ? AND SUBSTR(LOWER(t.`title`),2,2) = ? AND SUBSTR(LOWER(UPPER(LOWER(t.`title`))),2,2) = ? AND SUBSTR(LOWER(DATE_FORMAT(t.`create_time`,'%Y-%m')),2,10) LIKE ?
==> Parameters: 123(String),456(String),123(String),123(String),123(String),%023-01%(String)
<== Time Elapsed: 2(ms)
<== Total: 0

強(qiáng)類型

因?yàn)閠opicType為枚舉類型所以后續(xù)的操作都用枚舉類型并且有智能提示如果使用其他類型ide會(huì)進(jìn)行報(bào)錯(cuò)無法編譯通過


@Data
@Table("t_topic_type")
@EntityFileProxy
@ToString
public class TopicTypeTest1 implements ProxyEntityAvailable<TopicTypeTest1 , TopicTypeTest1Proxy> {

    @Column(primaryKey = true)
    private String id;
    private Integer stars;
    private String title;
    @Column(value = "topic_type",conversion = EnumConverter.class)
    private TopicTypeEnum topicType;
    private LocalDateTime createTime;

    @Override
    public Class<TopicTypeTest1Proxy> proxyTableClass() {
        return TopicTypeTest1Proxy.class;
    }
}


public enum TopicTypeEnum implements IEnum<TopicTypeEnum> {
    STUDENT(1),

    TEACHER(3),

    CLASSER(9);
    @EnumValue
    private final Integer code;

    TopicTypeEnum(Integer code){

        this.code = code;
    }
    @Override
    public Integer getCode() {
        return code;
    }
//......省略
}
List<TopicTypeTest1> list1 = easyEntityQuery.queryable(TopicTypeTest1.class)
                .where(o -> {
                    o.topicType().nullOrDefault(TopicTypeEnum.CLASSER).eq(TopicTypeEnum.STUDENT);
                    o.topicType().eq(TopicTypeEnum.STUDENT);
                }).toList();

==> Preparing: SELECT `id`,`stars`,`title`,`topic_type`,`create_time` FROM `t_topic_type` WHERE IFNULL(`topic_type`,?) = ? AND `topic_type` = ?
==> Parameters: 9(Integer),1(Integer),1(Integer)
<== Time Elapsed: 2(ms)
<== Total: 0

開箱即用的api

第一條

Topic topic = easyEntityQuery.queryable(Topic.class)
                    .where(o -> o.id().eq("123"))
                    .firstOrNull();

==> Preparing: SELECT `id`,`stars`,`title`,`create_time` FROM `t_topic` WHERE `id` = ? LIMIT 1
==> Parameters: 123(String)

至多一條

Topic topic = easyEntityQuery.queryable(Topic.class)
                    .where(o -> o.id().eq("123"))
                    .singleOrNull();

==> Preparing: SELECT `id`,`stars`,`title`,`create_time` FROM `t_topic` WHERE `id` = ?
==> Parameters: 123(String)

多條

List<Topic> topics = easyEntityQuery.queryable(Topic.class)
                    .where(o -> o.id().eq("123"))
                    .toList();

==> Preparing: SELECT `id`,`stars`,`title`,`create_time` FROM `t_topic` WHERE `id` = ?
==> Parameters: 123(String)

分頁

EasyPageResult<Topic> topicPageResult = easyEntityQuery
                .queryable(Topic.class)
                .where(o -> o.id().isNotNull())
                .toPageResult(1, 20);

==> Preparing: SELECT  COUNT(*)  FROM t_topic t WHERE t.`id` IS NOT NULL
<== Total: 1
==> Preparing: SELECT t.`id`,t.`stars`,t.`title`,t.`create_time` FROM t_topic t WHERE t.`id` IS NOT NULL LIMIT 20
<== Total: 20

streamApi配合


        Optional<Topic> traceId1 = easyProxyQuery.queryable(TopicProxy.createTable())
                .filterConfigure(NotNullOrEmptyValueFilter.DEFAULT)
                .where(o -> o.eq(o.t().id(), "1"))
                .fetch(o -> {//o為Stream<Topic>類型
                    return o.findFirst();
                },1);

==> Preparing: SELECT `id`,`stars`,`title`,`create_time` FROM `t_topic` WHERE `id` = ?
==> Parameters: 1(String)
<== Time Elapsed: 2(ms)

所見所得的sql


@Data
@EntityFileProxy
public class  QueryVO {
    private String id;
    private String field1;
    private String field2;
}

List<QueryVO> list = easyEntityQuery.queryable(Topic.class)
                    //第一個(gè)join采用雙參數(shù),參數(shù)1表示第一張表Topic 參數(shù)2表示第二張表 BlogEntity
                    .leftJoin(BlogEntity.class, (t, t1) -> t.id().eq(t1.id()))
                    //第二個(gè)join采用三參數(shù),參數(shù)1表示第一張表Topic 參數(shù)2表示第二張表 BlogEntity 第三個(gè)參數(shù)表示第三張表 SysUser
                    .leftJoin(SysUser.class, (t, t1, t2) -> t.id().eq(t2.id()))
                    .where(o -> o.id().eq("123"))//單個(gè)條件where參數(shù)為主表Topic
                    //支持單個(gè)參數(shù)或者全參數(shù),全參數(shù)個(gè)數(shù)為主表+join表個(gè)數(shù) 鏈?zhǔn)綄懛ㄆ陂g可以通過then來切換操作表
                    .where((t, t1, t2) -> {
                        t.id().eq("123");
                        t1.title().like("456");
                        t2.createTime().eq(LocalDateTime.of(2021, 1, 1, 1, 1));
                    })
                    .select((t, t1, t2) -> new QueryVOProxy().adapter(r->{
                        r.selectAll(t);//因?yàn)榻Y(jié)果只有并沒有其他屬性所以能夠映射上的只有t.id所以只會(huì)查詢t.id
                        r.selectIgnores(t.title());//可寫可不寫因?yàn)閂O沒有title所以不會(huì)映射查詢
                        r.field1().set(t1.title());//別名映射
                        r.field2().set(t2.id());//別名映射
                    })).toList();

==> Preparing: SELECT t.`id`,t1.`title` AS `field1`,t2.`id` AS `field2` FROM `t_topic` t LEFT JOIN `t_blog` t1 ON t1.`deleted` = ? AND t.`id` = t1.`id` LEFT JOIN `easy-query-test`.`t_sys_user` t2 ON t.`id` = t2.`id` WHERE t.`id` = ? AND t.`id` = ? AND t1.`title` LIKE ? AND t2.`create_time` = ?
==> Parameters: false(Boolean),123(String),123(String),%456%(String),2021-01-01T01:01(LocalDateTime)
<== Time Elapsed: 2(ms)
<== Total: 0

group感知

因?yàn)間roup后無法對(duì)結(jié)果進(jìn)行展開所以需要有g(shù)roup感知

 List<BlogEntity> page = easyEntityQuery
                .queryable(Topic.class)
                .innerJoin(BlogEntity.class, (t, t1) -> t.id().eq(t1.id()))
                .where((t, t1) -> t1.title().isNotNull())
                .groupBy((t, t1) -> GroupKeys.TABLE2.of(t1.id()))
                .select((g) -> new BlogEntityProxy().adapter(r->{
                    r.selectExpression(g.key1());//group只對(duì)t1.id進(jìn)行了分組所以這邊只有key1可以選擇
                    r.score().set(g.sum(g.group().t2.score()));//因?yàn)槭莏oin了一張表所以g.group里面其實(shí)是tuple2里面有t1和t2兩張表
                }))
                .toList();

==> Preparing: SELECT t1.`id`,SUM(t1.`score`) AS `score` FROM `t_topic` t INNER JOIN `t_blog` t1 ON t1.`deleted` = ? AND t.`id` = t1.`id` WHERE t1.`title` IS NOT NULL GROUP BY t1.`id`
==> Parameters: false(Boolean)
<== Time Elapsed: 5(ms)
<== Total: 100

匿名類型平替

無需定義別名可以直接返回并且擁有強(qiáng)類型,可以作為匿名表繼續(xù)查詢無需定義中間表


        List<Draft2<String, String>> list = easyEntityQuery.queryable(Topic.class)
                .where(o -> {
                    o.title().trimEnd().trimStart().eq(o.id().trimStart());
                    o.createTime().format("yyyy-MM-dd").subString(0, 4).eq("2021");
                })
                .selectDraft(o -> Select.draft(
                        o.id(),
                        o.title().toLower()
                ))
                .toList();

==> Preparing: SELECT t.`id` AS `value1`,LOWER(t.`title`) AS `value2` FROM `t_topic` t WHERE LTRIM(RTRIM(t.`title`)) = LTRIM(t.`id`) AND SUBSTR(DATE_FORMAT(t.`create_time`,'%Y-%m-%d'),1,4) = ?
==> Parameters: 2021(String)
<== Time Elapsed: 2(ms)
<== Total: 0

之前看到有人發(fā)過.net的orm語法實(shí)現(xiàn),這次我們通過模擬那個(gè)作者的orm語法來看看easy-query和其相差多少

var query = rep.GetLambdaQuery().Take(100);
var join = query.Select(b => new { a1 = b.Id, a2 = b.F_String }).Join<TestEntityItem>((a, b) => a.a1 == b.TestEntityId);//第一次關(guān)聯(lián)
varjoin2 = join.Select((a, b) => new { a3 = a.a1, a4 = b.Name })
      .Join<TestEntity>((a, b) => a.a3 == b.Id);//第二次關(guān)聯(lián)
  join2.Select((a, b) => new
  {
      a.a4,
      b.Id
  });

這個(gè)SQL是一個(gè)很明顯的匿名sql之間的join處理,一眼看過去基本就大致猜到具體的sql含義所以在表達(dá)式這方面其實(shí)還是很容易只曉得

select 
  t4.[a4], 
  t1.[Id] 
from 
  (
    select 
      t2.[a1] as a3, 
      t3.[Name] as a4 
    from 
      (
        select 
          t1.[Id] as a1, 
          t1.[F_String] as a2 
        from 
          [TestEntity] t1 
        LIMIT 0, 100
      ) t2 
      Inner join [TestEntityItem] t3 on t2.a1 = t3.[TestEntityId]
  ) t4 
  Inner join [TestEntity] t1 on t4.a3 = t1.[Id]
//selectDraft簡單理解為.net的匿名類型但是在java這邊沒有匿名類型所以通過一種草稿類型來對(duì)應(yīng)可以防止簡單功能需要重新定義類本質(zhì)是元祖tuple1-10
    EntityQueryable<TopicProxy, Topic> query = easyEntityQuery.queryable(Topic.class).limit(100);

    EntityQueryable2<Draft2Proxy<String, Integer>, Draft2<String, Integer>, BlogEntityProxy, BlogEntity> join = query.selectDraft(o -> Select.draft(o.id(), o.stars()))
            .leftJoin(BlogEntity.class, (t, t1) -> t.value1().eq(t1.id()));
    EntityQueryable2<Draft2Proxy<String, String>, Draft2<String, String>, BlogEntityProxy, BlogEntity> join2 = join.selectDraft((a, b) -> Select.draft(a.value1(), b.url()))
            .innerJoin(BlogEntity.class, (t, t1) -> t.value2().eq(t1.id()));

    List<Draft2<String, String>> list = join2.selectDraft((a, b) -> Select.draft(a.value1(), b.url())).toList();

//我們把局部變量去掉

            List<Draft2<String, String>> list = easyEntityQuery.queryable(Topic.class).limit(100)
                    .selectDraft(o -> Select.draft(o.id(), o.stars()))
                    .leftJoin(BlogEntity.class, (t, t1) -> t.value1().eq(t1.id()))
                    .selectDraft((a, b) -> Select.draft(a.value1(), b.url()))
                    .innerJoin(BlogEntity.class, (t, t1) -> t.value2().eq(t1.id()))
                    .selectDraft((a, b) -> Select.draft(a.value1(), b.url())).toList();

SELECT
    t3.`value1` AS `value1`,
    t4.`url` AS `value2` 
FROM
    (SELECT
        t1.`value1` AS `value1`,
        t2.`url` AS `value2` 
    FROM
        (SELECT
            t.`id` AS `value1`,
            t.`stars` AS `value2` 
        FROM
            `t_topic` t LIMIT 100) t1 
    LEFT JOIN
        `t_blog` t2 
            ON t2.`deleted` = false 
            AND t1.`value1` = t2.`id`
        ) t3 
INNER JOIN
    `t_blog` t4 
        ON t4.`deleted` = false 
        AND t3.`value2` = t4.`id`

或許你是一位java原住民,或許你是一位c#開發(fā),在java語言貧瘠的時(shí)候我相信一款優(yōu)雅的orm能夠讓你在編寫crud的時(shí)候放松神經(jīng)不需要去考慮mybatis這種sql模版帶來的心智負(fù)擔(dān),因?yàn)閙ybatis把所有問題都拋給了用戶所以你們一直覺得mybatis好,其實(shí)是你們被mybatis調(diào)教的好,因?yàn)橐粋€(gè)框架只要提供的功能足夠少那么他需要維護(hù)的就足夠少,出問題也會(huì)足夠少,所以你拿諾基亞半個(gè)月不需要充電和2024年的智能機(jī)一天一沖比較哪個(gè)優(yōu)秀我覺得你應(yīng)該是贏了

最后

可能有很多小伙伴會(huì)推薦我jpa或者jooq我想說如果我沒能力那么我可能會(huì)選擇他們,如果他們支持國產(chǎn)數(shù)據(jù)庫我可能會(huì)選擇他們,但是你我更愿意推薦easy-query因?yàn)槲視?huì)聆聽開發(fā)者的聲音起碼你叫的動(dòng)我,我是一個(gè)在crud混的菜鳥開發(fā),crud的困難,orm的困難必須是一個(gè)混跡在業(yè)務(wù)開發(fā)的程序員才能開發(fā)出來的好框架,在沒開發(fā)出這個(gè)api的時(shí)候已經(jīng)有很多小伙伴使用lambda的api進(jìn)行了開發(fā)反向非常不錯(cuò),期待您的使用。

easy-query

文檔地址 https://xuejm.gitee.io/easy-query-doc/

GITHUB地址 https://github.com/xuejmnet/easy-query

GITEE地址 https://gitee.com/xuejm/easy-query

總結(jié)

以上是生活随笔為你收集整理的这应该是java最好用的orm之一了的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。