{"id":17299748,"url":"https://github.com/threefish/nutz-dao-enhance","last_synced_at":"2025-07-26T10:35:55.331Z","repository":{"id":93222622,"uuid":"368098246","full_name":"threefish/nutz-dao-enhance","owner":"threefish","description":"增强NutzDao,无需写dao实现类也能完成数据库基础crud、复杂sql查询、存储过程调用。可以在spring boot 和 nutz (boot) 两种框架中运行，使用体验保持一致","archived":false,"fork":false,"pushed_at":"2023-10-04T12:11:30.000Z","size":507,"stargazers_count":3,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-06T23:34:19.128Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/threefish.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2021-05-17T07:41:34.000Z","updated_at":"2023-11-30T06:23:10.000Z","dependencies_parsed_at":"2023-10-01T16:21:36.501Z","dependency_job_id":"d3b0b6eb-4a96-4c4b-8781-3aa5e86b3756","html_url":"https://github.com/threefish/nutz-dao-enhance","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/threefish/nutz-dao-enhance","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threefish%2Fnutz-dao-enhance","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threefish%2Fnutz-dao-enhance/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threefish%2Fnutz-dao-enhance/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threefish%2Fnutz-dao-enhance/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/threefish","download_url":"https://codeload.github.com/threefish/nutz-dao-enhance/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/threefish%2Fnutz-dao-enhance/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267150480,"owners_count":24043473,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-26T02:00:08.937Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-15T11:23:32.670Z","updated_at":"2025-07-26T10:35:55.287Z","avatar_url":"https://github.com/threefish.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# nutz-dao-enhance\n\n## 增强NutzDao,无需写dao实现类也能完成数据库基础crud、复杂sql查询、存储过程调用。\n\n1. @Entity(UserDO.class)可添加到Dao接口类上或放在方法上，该方法返回实体优先采用当前指定的class\n2. 在开启自动建表的情况下，将@IgnoreAutoDDL添加到实体类上将忽略当前实体自动创建表和更新功能\n3. 实现 AuditHandler 接口，可以在更新和插入数据时自动设置当前操作人(对应注解 @CreatedBy @LastModifiedBy)，同时也实现了@EntityListener 注解\n4. 实现 IdentifierGenerator 接口，可以在插入时对添加了 @AutoID 字段进行赋值。如果搭配 @Id 注解，需要在 @Id(auto=false)时才生效\n5. @CustomProvider 可以方便你扩展更多基础的功能 参考 org.nutz.dao.enhance.dao.BaseDao\n6. \\#[] 语法使用介绍 例子： \\#[ and u.realName=@name and u.gmtCreate=@gmtCreate ] name或gmtCreate 入参不存在，则当前#[]中的全部条件都不生效，且会忽略这段sql\n7. 查询预计中可以使用和java实体类名称如： UserDO as u ,会翻译为 user as u 而 u.realName 则会翻译为 u.real_name\n8. 自定义SQL下可按参数循环执行sql语句（batch操作）\n9. @FieldCalculation 字段计算注解可以方便的在查询结果下对查询对象进行计算（通过表达式赋值）\n10. lambda方式连表查询join\n    PS：3-4项的原理实际是采用NutzDao原生@PrevInsert @PrevUpdate搭配el表达式等方式来实现，原生功能更强大，请自由选择使用。\n\n### mavne坐标\n\n[nutz-dao-enhance-spring-starter](https://mvnrepository.com/artifact/org.nutz/nutz-dao-enhance-spring-starter)\n[nutz-dao-enhance-nutz-starter](https://mvnrepository.com/artifact/org.nutz/nutz-dao-enhance-nutz-starter)\n\n### lambda常用方法\n\n```java\n//lambda方式更新\nuserDao.lambdaUpdate().set(UserDO::getAge, 123).eq(UserDO::getAge, 15).update();\nuserDao.lambdaUpdate().eq(UserDO::getAge, 15).delete();\nuserDao.lambdaUpdate().set(UserDO::getAge, 250).insert();\n\n//lambda方式查询\nuserDao.lambdaQuery().isNotNull(UserDO::getRealName).in(UserDO::getAge,Arrays.asList(15,16)).list();\nuserDao.lambdaQuery().isNull(UserDO::getRealName).one();\nuserDao.lambdaQuery().gte(UserDO::getAge, 17).count();\nuserDao.lambdaQuery().gte(UserDO::getAge, 17)\n        .and(c -\u003e c.gte(UserDO::getAge, 15).lte(UserDO::getAge, 40), c -\u003e c.gte(UserDO::getId, 10))\n        .list();\n\n```\n\n### 更多用法请查看 org.nutz.dao.enhance.SpringDaoTest\n\n#### 自定义SQL操作 dao\n\n```java\n/**\n * 自动建表，通过泛型 找到 UserDO 再根据 UserDO 信息进行建表。如果不需要自动建表，需要再UserDO上添加 @IgnoreAutoDDL 主键\n * 如果没有定义泛型但是也需要自动建表功能 则需要添加 @Entity(UserDO.class) 注解\n */\n@Dao\npublic interface UserDao extends BaseDao\u003cUserDO\u003e {\n\n   /**\n    * gmtCreate 入参不存在，所以当前#[]中的全部条件不生效\n    * 输出SQL：select u.id,u.real_name,u.age,u.gmt_create,u.create_by from user as u where 1=1   and u.real_name='测试11'\n    *\n    * @param name\n    * @return\n    */\n   @Query(\"select u.* from UserDO as u where 1=1\"\n           + \"#[ and u.realName=#{name} and u.gmtCreate=#{gmtCreate} ] \"\n           + \"#[ and u.realName=#{name} ] \")\n   UserDO queryByCndHql(String name);\n\n   /**\n    * 查询2\n    * 输出SQL： select u.id,u.real_name,u.age,u.gmt_create,u.create_by from user as u where 1=1  and u.real_name='测试11'\n    *\n    * @param user\n    */\n   @Query(\"select u.* from UserDO as u where 1=1 \"\n           + \"#[ and u.realName=#{user.realName} ] \")\n   UserDO queryByVoHql(UserDO user);\n\n   /**\n    * 返回当前实体类\n    *\n    * @param id\n    * @return\n    */\n   @Query(\"select * from user where id=#{id}\")\n   UserDO queryUserById(int id);\n\n   /**\n    * 返回当前实体类\n    *\n    * @param id\n    * @return\n    */\n   @Query(\"select * from user where id=#{id}\")\n   Optional\u003cUserDO\u003e queryOptionalUserById(@Param(\"id\") int id);\n\n   /**\n    * 根据 condition 条件返回\n    *\n    * @param condition\n    * @return\n    */\n   @Query(\"select * from user $condition\")\n   @Entity(UserDO.class)\n   List\u003cUserDO\u003e listUser(Condition condition);\n\n   /**\n    * 根据 condition 条件返回\n    *\n    * @param condition\n    * @return\n    */\n   @Query(\"select * from user $condition\")\n   @Entity(UserDO.class)\n   Optional\u003cList\u003cUserDO\u003e\u003e listOptionalUser(Condition condition);\n\n   /**\n    * 查询返回一个map\n    *\n    * @param id\n    * @return\n    */\n   @Query(\"select * from user where id=#{id}\")\n   Map queryMapById(int id);\n\n   /**\n    * 查询返回一个map\n    *\n    * @return\n    */\n   @Query(\"select * from user\")\n   List\u003cMap\u003e listMap();\n\n   /**\n    * 查询返回一个 Record\n    *\n    * @param id\n    * @return\n    */\n   @Query(\"select * from user where id=#{id}\")\n   Record queryRecordById(int id);\n\n   /**\n    * 只会返回第一条记录，且不会像mybaits那样会提示too many result\n    *\n    * @return\n    */\n   @Query(\"select * from user\")\n   UserDO queryAllAndGetFirst();\n\n   /**\n    * 分页查询\n    *\n    * @param pager\n    * @return\n    */\n   @Query(\n           value = \"select * from user\"\n           , countSql = \"select count(1) from user\"\n   )\n   PageRecord listUserPage(Pager pager);\n\n   /**\n    * 插入获取自增ID\n    *\n    * @param name\n    * @param age\n    * @param create\n    * @return\n    */\n   @Insert(value = \"INSERT INTO user(`real_name`, `age`,`gmt_create`,`create_by`) VALUES (#{name},#{age}, now(),#{create})\", returnGeneratedKeys = true)\n   int insert(String name, int age, String create);\n\n\n   /**\n    * 插入\n    *\n    * @param name\n    * @param age\n    * @param create\n    */\n   @Insert(\"INSERT INTO user(`real_name`, `age`,`gmt_create`,`create_by`) VALUES (#{name},#{age}, now(),#{create})\")\n   void insertVoid(String name, int age, String create);\n\n   /**\n    * 更新数据\n    *\n    * @param age\n    * @param id\n    * @return\n    */\n   @Update(\"UPDATE user SET age = #{age} WHERE id = #{id}\")\n   int updateAgeById(int age, int id);\n\n   /**\n    * 删除数据\n    *\n    * @param id\n    * @return\n    */\n   @Delete(\"DELETE FROM user WHERE id=#{id}\")\n   int delectById(int id);\n\n\n   /**\n    * @return\n    */\n   @Query(\"select u.realName from UserDO as u\")\n   String[] queryRealNames();\n\n   /**\n    * @return\n    */\n   @Query(\"select u.realName from UserDO as u\")\n   Optional\u003cString[]\u003e queryOptionalRealNames();\n\n   /**\n    * @return\n    */\n   @Query(\"select u.id from UserDO as u\")\n   int[] queryIntIds();\n\n   /**\n    * @return\n    */\n   @Query(\"select u.id from UserDO as u\")\n   Integer[] queryIntegerIds();\n\n\n   /**\n    * 自定义提供类处理\n    * \u003cp\u003e\n    * 通过自定义扩展，实现插入并返回自增ID\n    *\n    * @param name\n    * @param age\n    * @param create\n    * @return\n    */\n   @Insert(\"INSERT INTO user(`real_name`, `age`,`gmt_create`,`create_by`) VALUES (#{name},#{age}, now(),#{create})\")\n   @CustomProvider(type = TestProvider.class, methodName = \"insertWithCustomprovider\")\n   int insertWithCustomprovider(String name, int age, String create);\n\n   /**\n    * 返回值是列表\n    * CREATE  PROCEDURE `callList`()\n    * BEGIN\n    * SELECT * FROM user;\n    * END\n    *\n    * @return\n    */\n   @CallStoredProcedure(\"call callList()\")\n   Optional\u003cList\u003cUserVO\u003e\u003e callList();\n\n   /**\n    * 通过出参返回单行数据\n    * CREATE PROCEDURE `callOut`(IN id INT,OUT realName VARCHAR(15),OUT age INT(15))\n    * BEGIN\n    * SELECT real_name,user.`age` INTO realName,age FROM `user`  WHERE `user`.id=id;\n    * END\n    */\n   @CallStoredProcedure(value = \"call callOut(#{id},#realName,#{age})\", out = {\n           @CallStoredProcedure.Out(name = \"realName\"),\n           @CallStoredProcedure.Out(name = \"age\", jdbcType = Types.INTEGER)\n   })\n   Optional\u003cUserVO\u003e callOut(@Param(\"id\") int id);\n\n\n   /**\n    * 返回值是列表\n    * CREATE  PROCEDURE `callList`()\n    * BEGIN\n    * SELECT * FROM user;\n    * END\n    *\n    * @return\n    */\n   @CallStoredProcedure(\"call callList()\")\n   void callList1();\n\n   /**\n    * 通过出参返回单行数据\n    * CREATE PROCEDURE `callOut`(IN id INT,OUT realName VARCHAR(15),OUT age INT(15))\n    * BEGIN\n    * SELECT real_name,user.`age` INTO realName,age FROM `user`  WHERE `user`.id=id;\n    * END\n    */\n   @CallStoredProcedure(value = \"call callOut(#{id},#realName,#{age})\", out = {\n           @CallStoredProcedure.Out(name = \"realName\"),\n           @CallStoredProcedure.Out(name = \"age\", jdbcType = Types.INTEGER)\n   })\n   void callOut1(@Param(\"id\") int id);\n\n\n   @CallStoredProcedure(\"call callList()\")\n   List callList2();\n\n   /**\n    * 通过出参返回单行数据\n    * CREATE PROCEDURE `callOut`(IN id INT,OUT realName VARCHAR(15),OUT age INT(15))\n    * BEGIN\n    * SELECT real_name,user.`age` INTO realName,age FROM `user`  WHERE `user`.id=id;\n    * END\n    */\n   @CallStoredProcedure(value = \"call callOut(#{id},#realName,#{age})\", out = {\n           @CallStoredProcedure.Out(name = \"realName\"),\n           @CallStoredProcedure.Out(name = \"age\", jdbcType = Types.INTEGER)\n   })\n   Map callOut2(@Param(\"id\") int id);\n\n\n   /**\n    * 插入\n    *\n    * @param name\n    * @param ages\n    * @param create\n    * @return\n    */\n   @Insert(value = \"INSERT INTO user(`real_name`, `age`,`gmt_create`,`create_by`) VALUES (#{name},#{age}, now(),#{create})\", loopFor = \"age\")\n   int insertLoopForAge(String name, String create, @Param(\"age\") List\u003cInteger\u003e ages);\n\n   /**\n    * 插入返回主键ID\n    *\n    * @param name\n    * @param ages\n    * @param create\n    * @return\n    */\n   @Insert(value = \"INSERT INTO user(`real_name`, `age`,`gmt_create`,`create_by`) VALUES (#{name},#{age}, now(),#{create})\", loopFor = \"age\", returnGeneratedKeys = true)\n   List\u003cInteger\u003e insertLoopForAgeAndReturnId(String name, String create, @Param(\"age\") List\u003cInteger\u003e ages);\n\n   @Delete(value = \"delete from user where age = #{object.test}\", loopFor = \"object\")\n   int deleteLoopForAge(@Param(\"object\") List\u003cNutMap\u003e ages);\n}\n\n\n\n\n\n```\n\n#### 测试类\n\n```java\n@SuppressWarnings(\"all\")\n@RunWith(SpringRunner.class)\n@SpringBootTest(classes = MainApplication.class)\n@TestMethodOrder(MethodOrderer.OrderAnnotation.class)\n@Transactional\npublic class SpringDaoTest {\n    /**\n     * 防止IDE报红可以在 UserDao 类上加 Spring 注册注解如  @Repository @Component 等\n     */\n    @Autowired\n    private UserDao userDao;\n\n    private UserDO u1 = null;\n    private UserDO u2 = null;\n    private UserDO u3 = null;\n\n    @Before\n    public void before() {\n        userDao.clear();\n        u1 = UserDO.builder().age(15).realName(\"测试1\").build();\n        u2 = UserDO.builder().age(16).realName(\"测试2\").build();\n        u3 = UserDO.builder().age(17).realName(\"测试3\").build();\n        List\u003cUserDO\u003e list = new ArrayList\u003c\u003e();\n        list.add(u1);\n        list.add(u2);\n        list.add(u3);\n        userDao.saveBatch(list);\n    }\n\n    @After\n    public void after() {\n        userDao.clear();\n    }\n\n    @Test\n    public void test_auditing() {\n        assert Objects.equals(u1.getCreateBy(), \"spring-test\");\n    }\n\n    @Test\n    public void test_condition() {\n        List\u003cUserDO\u003e list = userDao.listUser(Cnd.where(UserDO::getAge, \"=\", 15));\n        assert list.size() == 1;\n    }\n\n\n    @Test\n    public void list_optional_user_condition() {\n        Optional\u003cList\u003cUserDO\u003e\u003e optional = userDao.listOptionalUser(Cnd.where(UserDO::getAge, \"=\", 15));\n        assert optional.isPresent() \u0026\u0026 optional.get().size() == 1;\n    }\n\n\n    @Test\n    public void test_list_map() {\n        List\u003cMap\u003e maps = userDao.listMap();\n        assert maps.size() == 3;\n\n    }\n\n    @Test\n    public void test_list_pagedata() {\n        StopWatch stopWatch = new StopWatch();\n        stopWatch.start(\"A\");\n        PageRecord\u003cUserDO\u003e pageRecord = userDao.listUserPage(new Pager(1, 10));\n        assert pageRecord.getTotal() == 3;\n        assert pageRecord.getRecords().size() == 3;\n        stopWatch.stop();\n        System.out.println(stopWatch.getTotalTimeMillis());\n        stopWatch.start(\"B\");\n        PageRecord\u003cUserDO\u003e pageRecord2 = userDao.listUserPage(new Pager(1, 10));\n        assert pageRecord2.getTotal() == 3;\n        assert pageRecord2.getRecords().size() == 3;\n        stopWatch.stop();\n        System.out.println(stopWatch.getTotalTimeMillis());\n    }\n\n    @Test\n    public void test_query_user_by_id() {\n        UserDO uset = userDao.queryUserById(u1.getId());\n        assert uset != null;\n    }\n\n    @Test\n    public void test_query_optional_user_by_id() {\n        final Optional\u003cUserDO\u003e userDO = userDao.queryOptionalUserById(u1.getId());\n        assert userDO != null \u0026\u0026 userDO.isPresent();\n    }\n\n    @Test\n    public void test_query_map_by_id() {\n        Map map = userDao.queryMapById(u1.getId());\n        assert map != null;\n\n    }\n\n    @Test\n    public void test_query_record_by_id() {\n        Record record = userDao.queryRecordById(u1.getId());\n        assert record != null;\n    }\n\n    @Test\n    public void test_query_all_and_get_first() {\n        UserDO usetDO = userDao.queryAllAndGetFirst();\n        assert usetDO != null;\n    }\n\n    @Test\n    public void test_insert_void() {\n        userDao.insertVoid(\"王五\", 100, \"张三\");\n    }\n\n    @Test\n    public void test_insert_and_incr_pk_id() {\n        int insertId = userDao.insert(\"王五\", 100, \"张三\");\n        assert insertId \u003e 0;\n\n    }\n\n\n    @Test\n    public void test_update_age_by_id() {\n        int insertId = userDao.insert(\"王五\", 100, \"张三\");\n        int updateCount = userDao.updateAgeById(50, insertId);\n        assert updateCount == 1;\n    }\n\n    @Test\n    public void test_delect_by_id() {\n        int insertId = userDao.insert(\"王五\", 100, \"张三\");\n        List\u003cUserDO\u003e list = userDao.lambdaQuery().list();\n        int delectCount = userDao.delectById(insertId);\n        assert delectCount == 1;\n    }\n\n\n    @Test\n    public void test_insert_entity() {\n        UserDO insert = userDao.insert(UserDO.builder().age(15).realName(\"测试11\").build());\n        assert insert.getId() \u003e 0;\n    }\n\n    @Test\n    public void test_fetch_by_id() {\n        UserDO insert = userDao.insert(UserDO.builder().age(15).realName(\"测试11\").build());\n        UserDO fetch = userDao.fetch(insert.getId());\n        assert fetch.getId() \u003e 0;\n    }\n\n    @Test\n    public void test_delete_by_id() {\n        UserDO insert = userDao.insert(UserDO.builder().age(15).realName(\"测试11\").build());\n        int updateCount = userDao.delete(insert.getId());\n        assert updateCount == 1;\n    }\n\n\n    @Test\n    public void test_cnd_hql() {\n        final UserDO userDO = UserDO.builder().age(15).realName(\"测试11\").build();\n        userDao.insert(userDO);\n        UserDO fetch = userDao.queryByCndHql(\"测试11\");\n        assert fetch != null;\n    }\n\n    @Test\n    public void test_cnd_hql_vo() {\n        final UserDO userDO = UserDO.builder().age(15).realName(u1.getRealName()).build();\n        UserDO fetch2 = userDao.queryByVoHql(userDO);\n        assert fetch2 != null;\n    }\n\n\n    @Test\n    public void test_query_realnames() {\n        String[] strings = userDao.queryRealNames();\n        assert Arrays.equals(strings, new String[]{u1.getRealName(), u2.getRealName(), u3.getRealName()});\n    }\n\n    @Test\n    public void test_query_optional_realnames() {\n        final Optional\u003cString[]\u003e strings = userDao.queryOptionalRealNames();\n        assert strings.isPresent() \u0026\u0026 Arrays.equals(strings.get(), new String[]{u1.getRealName(), u2.getRealName(), u3.getRealName()});\n    }\n\n    @Test\n    public void test_query_int_ids() {\n        int[] ints = userDao.queryIntIds();\n        assert Arrays.equals(ints, new int[]{u1.getId(), u2.getId(), u3.getId()});\n    }\n\n    @Test\n    public void test_query_integer_ids() {\n        Integer[] ints = userDao.queryIntegerIds();\n        assert Arrays.equals(ints, new Integer[]{u1.getId(), u2.getId(), u3.getId()});\n    }\n\n    @Test\n    public void test_insert_with_customprovider() {\n        int insertId = userDao.insertWithCustomprovider(\"王五\", 100, null);\n        assert insertId \u003e 0;\n    }\n\n    @Test\n    public void test_call_list() {\n        Optional\u003cList\u003cUserVO\u003e\u003e maps = userDao.callList();\n        assert maps.get().size() == 3;\n    }\n\n    @Test\n    public void test_call_out() {\n        int maxId = userDao.getMaxId();\n        Optional\u003cUserVO\u003e data = userDao.callOut(maxId);\n        assert u3.getRealName().equals(data.get().getRealName());\n    }\n\n    @Test\n    public void test_call_lambdaQuery_fetch() {\n        UserDO userDO = userDao.lambdaQuery().where(UserDO::getAge, \"=\", 15).one();\n        assert userDO != null;\n    }\n\n    @Test\n    public void test_call_lambdaQuery_query() {\n        List\u003cUserDO\u003e query = userDao.lambdaQuery().list();\n        assert query.size() == 3;\n    }\n\n    @Test\n    public void test_call_lambdaQuery_queryPage() {\n        PageRecord\u003cUserDO\u003e userDOPageRecord = userDao.lambdaQuery().limit(1, 10).listPage();\n        assert userDOPageRecord.getTotal() == 3;\n        PageRecord\u003cUserDO\u003e userDOPageRecord1 = userDao.lambdaQuery().listPage(1, 10);\n        assert userDOPageRecord1.getTotal() == 3;\n        PageRecord\u003cUserDO\u003e userDOPageRecord2 = userDao.lambdaQuery().listPage(new Pager(1, 10));\n        assert userDOPageRecord2.getTotal() == 3;\n        PageRecord\u003cUserDO\u003e userDOPageRecord3 = userDao.lambdaQuery().eq(UserDO::getAge, 15).limit(1, 10).listPage();\n        assert userDOPageRecord3.getTotal() == 1;\n        List\u003cUserDO\u003e userDOPageRecord4 = userDao.lambdaQuery().limit(1, 10).groupBy(UserDO::getId).list();\n        assert userDOPageRecord4.size() == 3;\n        UserDO fetch = userDao.lambdaQuery().eq(UserDO::getAge, 15).one();\n        assert fetch.getAge() == 15;\n        List\u003cUserDO\u003e query = userDao.lambdaQuery().eq(UserDO::getAge, 15).list();\n        assert query.size() == 1;\n        List\u003cUserDO\u003e query1 = userDao.lambdaQuery().likeRight(UserDO::getRealName, \"测试\").list();\n        assert query1.size() == 3;\n        UserDO insert = userDao.insert(UserDO.builder().age(16).realName(null).build());\n        UserDO nullRealName = userDao.lambdaQuery().isNull(UserDO::getRealName).one();\n        assert insert.getId() == nullRealName.getId();\n        List\u003cUserDO\u003e query2 = userDao.lambdaQuery().isNotNull(UserDO::getRealName).list();\n        assert query2.size() == 3;\n        List\u003cUserDO\u003e query3 = userDao.lambdaQuery().isNull(UserDO::getRealName).list();\n        assert query3.size() == 1;\n        List\u003cUserDO\u003e query4 = userDao.lambdaQuery().isNotNull(UserDO::getRealName).in(UserDO::getAge, Arrays.asList(15, 16)).list();\n        assert query4.size() == 2;\n        int count = userDao.lambdaQuery().gte(UserDO::getAge, 17).count();\n        List\u003cUserDO\u003e query5 = userDao.lambdaQuery().gte(UserDO::getAge, 17).list();\n        assert query5.size() == count;\n        List\u003cUserDO\u003e list = userDao.lambdaQuery().gte(UserDO::getAge, 17)\n                .and(c -\u003e c.gte(UserDO::getAge, 15).lte(UserDO::getAge, 40), c -\u003e c.gte(UserDO::getId, 10))\n                .list();\n        assert list.size() == 1;\n    }\n\n    @Test\n    public void test_call_lambda_update() {\n        int updateCount = userDao.lambdaUpdate().set(UserDO::getAge, 123).eq(UserDO::getAge, 15).update();\n        int update = userDao.lambdaUpdate().set(UserDO::getAge, 15).eq(UserDO::getAge, 123).update();\n        assert updateCount == update;\n        userDao.lambdaUpdate().set(UserDO::getAge, 150).insert();\n        userDao.lambdaUpdate().set(UserDO::getAge, 250).insert();\n        int delCount = userDao.lambdaUpdate().gte(UserDO::getAge, 150).delete();\n        assert delCount == 2;\n\n    }\n\n    @Test\n    public void test_insert_loopfor_age() {\n        int count = userDao.insertLoopForAge(\"1\", \"张三\", Arrays.asList(15, 12, 13, 19));\n        assert count == 4;\n    }\n\n    @Test\n    public void test_insert_loopfor_age_and_returnid() {\n        List\u003cInteger\u003e list = userDao.insertLoopForAgeAndReturnId(\"1\", \"张三\", Arrays.asList(15, 12, 13, 19));\n        assert list.size() == 4;\n    }\n\n    @Test\n    public void test_delect_loopfor_age() {\n        int count = userDao.insertLoopForAge(\"1\", \"张三\", Arrays.asList(150, 120, 130, 190));\n        List\u003cNutMap\u003e nutMaps = Arrays.asList(\n                NutMap.NEW().setv(\"test\", 150),\n                NutMap.NEW().setv(\"test\", 120),\n                NutMap.NEW().setv(\"test\", 130),\n                NutMap.NEW().setv(\"test\", 190)\n        );\n        int deleteCount = userDao.deleteLoopForAge(nutMaps);\n        assert count == deleteCount;\n    }\n\n    @Test\n    public void test_call_lambda_query_fields() {\n        userDao.lambdaUpdate()\n                .set(UserDO::getAge, 123)\n                .set(UserDO::getRealName, null)\n                .set(UserDO::getCreateBy, \"张三\")\n                .ignoreNull()\n                .insert();\n        int maxId = userDao.getMaxId();\n        UserDO one = userDao.lambdaQuery().select(UserDO::getId).eq(UserDO::getId, maxId).one();\n        assert one.getRealName() == null;\n\n        UserDO one1 = userDao.lambdaQuery().excludes(UserDO::getCreateBy).eq(UserDO::getId, maxId).one();\n        assert one1.getCreateBy() == null;\n\n        userDao.lambdaUpdate()\n                .set(UserDO::getAge, 123)\n                .set(UserDO::getRealName, null)\n                .ignoreNull()\n                .eq(UserDO::getId, maxId)\n                .update();\n\n    }\n\n    @Test\n    public void test_field_calc() {\n        UserDO userDO = userDao.insert(UserDO.builder().age(17).realName(\"测试3\").build());\n\n        userDao.fieldCalculation(userDO, \"test\");\n        assert userDO.getUserDO() != null;\n        assert userDO.getUserDO1() != null;\n\n        userDao.fieldCalculation(userDO, \"test2\");\n        assert userDO.getTest() == userDO.getId() + userDO.getAge();\n\n        userDao.fieldCalculation(userDO);\n        assert userDO.getUserDO3() != null;\n\n\n    }\n\n\n    @Test\n    public void test_left_join_query() {\n        List\u003cUserDO\u003e list = userDao.lambdaQuery()\n                .selectAs(UserDO::getRealName, JobDO::getRealName)\n                .leftJoin(JobDO.class, UserDO::getId, JobDO::getUserId)\n                .like(UserDO.class, JobDO::getRealName, \"测试\")\n                .groupBy(UserDO::getRealName)\n                .list();\n        assert list.size() == 3;\n\n        PageRecord\u003cUserDO\u003e page = userDao.lambdaQuery()\n                .selectAs(UserDO::getRealName, JobDO::getUserId)\n                .leftJoin(JobDO.class, UserDO::getId, JobDO::getUserId)\n                .like(UserDO.class, JobDO::getRealName, \"测试\")\n                .limit(1, 10)\n                .listPage();\n        assert page.getTotal() == 3;\n    }\n\n}\n\n\n\n\n```\n\n#### 实体类 entity\n\n```java\n@Data\n@Builder\n@AllArgsConstructor\n@NoArgsConstructor\n@Table(\"user\")\n@IgnoreAutoDDL\npublic class UserDO extends BaseDO {\n\n   @Id(auto = false)\n   @AutoID\n   @ColDefine(width = 9, type = ColType.INT)\n   Integer id;\n   @Column\n   String realName;\n   @Column\n   Integer age;\n   /**\n    * 字段计算功能，可按分组进行计算\n    */\n   @FieldCalculation(groups = {\"test\"}, expression = \"$ioc:filedCalcTestService.query($this)\")\n   UserDO userDO;\n\n   @FieldCalculation(groups = {\"test\"}, order = 1, expression = \"$ioc:filedCalcTestService.query($this)\")\n   UserDO userDO1;\n\n   @FieldCalculation(groups = {\"test2\"}, order = 2, expression = \"$this.age + $this.id\")\n   int test;\n\n   @FieldCalculation(order = 1, expression = \"$ioc:filedCalcTestService.query($this)\")\n   UserDO userDO3;\n\n}\n```\n\n### 打包\n\n```\nmvn clean package -P releasse\nmvn clean install -P releasse\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreefish%2Fnutz-dao-enhance","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthreefish%2Fnutz-dao-enhance","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthreefish%2Fnutz-dao-enhance/lists"}