From 366d556bad624ac1fbe9b542718c97b4e63c3c5a Mon Sep 17 00:00:00 2001 From: kfyty725 Date: Thu, 20 Mar 2025 16:17:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E6=B7=BB=E5=8A=A0loveqq-framework?= =?UTF-8?q?=E5=90=AF=E5=8A=A8=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mybatis-flex-loveqq-starter/pom.xml | 46 ++ .../autoconfig/FlexSqlSessionFactoryBean.java | 98 ++++ .../MybatisFlexAdminAutoConfiguration.java | 60 +++ .../MybatisFlexAutoConfiguration.java | 262 ++++++++++ .../autoconfig/MybatisFlexProperties.java | 472 ++++++++++++++++++ .../ConditionalOnMybatisFlexDatasource.java | 52 ++ .../customize/ConfigurationCustomizer.java | 33 ++ .../customize/MyBatisFlexCustomizer.java | 46 ++ .../datasource/DataSourceInterceptor.java | 93 ++++ .../boot/autoconfig/package-info.java | 19 + .../boot/autoconfig/service/ServiceImpl.java | 40 ++ .../transaction/FlexTransaction.java | 87 ++++ .../transaction/FlexTransactionFactory.java | 45 ++ .../transaction/FlexTransactionManager.java | 119 +++++ .../autoconfig/transaction/TimeoutHolder.java | 85 ++++ .../src/main/resources/META-INF/k.factories | 4 + .../mybatis-flex-loveqq-test/pom.xml | 63 +++ .../loveqq/test/DataSourceInitListener.java | 34 ++ .../test/MyConfigurationCustomizer.java | 59 +++ .../loveqq/test/SampleApplication.java | 64 +++ .../loveqq/test/alias/BaseEntity.java | 77 +++ .../mybatisflex/loveqq/test/alias/DeptVO.java | 57 +++ .../mybatisflex/loveqq/test/alias/RoleVO.java | 67 +++ .../loveqq/test/alias/SysDept.java | 59 +++ .../loveqq/test/alias/SysRole.java | 70 +++ .../loveqq/test/alias/SysUser.java | 106 ++++ .../mybatisflex/loveqq/test/alias/UserVO.java | 103 ++++ .../mybatisflex/loveqq/test/entity/Inner.java | 55 ++ .../mybatisflex/loveqq/test/entity/Outer.java | 64 +++ .../loveqq/test/entity/TestEntity.java | 28 ++ .../AccountAgeInsertListener.java | 13 + .../AccountAgeInsertListenerFlag.java | 5 + .../AccountTableAnnoInsertListener.java | 13 + .../missingListenerFix/BaseLogicDelete.java | 18 + .../LogicDeleteInsertListener.java | 12 + .../LogicDeleteInsertListenerFlag.java | 5 + .../loveqq/test/mapper/AccountMapper.java | 28 ++ ...AccountMissingListenerTestModelMapper.java | 10 + .../loveqq/test/mapper/ArticleMapper.java | 10 + .../test/mapper/FieldMappingInnerMapper.java | 10 + .../test/mapper/FieldMappingMapper.java | 10 + .../loveqq/test/mapper/GoodMapper.java | 10 + .../loveqq/test/mapper/InnerMapper.java | 10 + .../loveqq/test/mapper/MyAccountMapper.java | 40 ++ .../loveqq/test/mapper/OuterMapper.java | 10 + .../loveqq/test/mapper/PatientMapper.java | 10 + .../loveqq/test/mapper/SysUserMapper.java | 10 + .../loveqq/test/mapper/TbClassMapper.java | 7 + .../test/mapper/UnmappedUserMapper.java | 10 + .../loveqq/test/mapper/UserMapper.java | 10 + .../loveqq/test/model/Account.java | 122 +++++ .../loveqq/test/model/AccountDto.java | 37 ++ .../AccountMissingListenerTestModel.java | 89 ++++ .../test/model/AccountOnSetListener.java | 29 ++ .../loveqq/test/model/AccountVO.java | 70 +++ .../loveqq/test/model/AccountVO2.java | 76 +++ .../loveqq/test/model/AccountView.java | 54 ++ .../loveqq/test/model/Article.java | 71 +++ .../loveqq/test/model/BaseEntity.java | 57 +++ .../loveqq/test/model/Disease.java | 45 ++ .../loveqq/test/model/FieldMapping.java | 66 +++ .../loveqq/test/model/FieldMappingInner.java | 71 +++ .../mybatisflex/loveqq/test/model/Gender.java | 41 ++ .../mybatisflex/loveqq/test/model/Good.java | 108 ++++ .../loveqq/test/model/GoodOnSetListener.java | 33 ++ .../mybatisflex/loveqq/test/model/IdCard.java | 55 ++ .../loveqq/test/model/IdEntity.java | 44 ++ .../mybatisflex/loveqq/test/model/Order.java | 61 +++ .../loveqq/test/model/OrderGood.java | 49 ++ .../loveqq/test/model/OrderInfo.java | 106 ++++ .../loveqq/test/model/Patient.java | 72 +++ .../loveqq/test/model/PatientVO1.java | 121 +++++ .../mybatisflex/loveqq/test/model/Role.java | 121 +++++ .../loveqq/test/model/RoleKey.java | 40 ++ .../loveqq/test/model/RoleVO1.java | 74 +++ .../loveqq/test/model/RoleVO2.java | 52 ++ .../loveqq/test/model/RoleVO3.java | 62 +++ .../mybatisflex/loveqq/test/model/Tag.java | 44 ++ .../loveqq/test/model/TbClass.java | 47 ++ .../loveqq/test/model/UnmappedBaseEntity.java | 35 ++ .../loveqq/test/model/UnmappedUser.java | 53 ++ .../mybatisflex/loveqq/test/model/User.java | 96 ++++ .../loveqq/test/model/UserInfo.java | 115 +++++ .../loveqq/test/model/UserOrder.java | 49 ++ .../loveqq/test/model/UserRole.java | 49 ++ .../mybatisflex/loveqq/test/model/UserVO.java | 70 +++ .../loveqq/test/model/UserVO1.java | 62 +++ .../loveqq/test/model/UserVO2.java | 75 +++ .../loveqq/test/model/UserVO3.java | 68 +++ .../loveqq/test/model/UserVO4.java | 56 +++ .../loveqq/test/model/UserVO5.java | 108 ++++ .../loveqq/test/service/AccountService.java | 54 ++ .../loveqq/test/service/ArticleService.java | 30 ++ .../test/service/impl/ArticleServiceImpl.java | 52 ++ .../unmapped/MyUnMappedColumnHandler.java | 46 ++ .../src/main/resources/application.yml | 48 ++ .../main/resources/mapper/accountMapper.xml | 44 ++ .../loveqq/test/LoveqqExtension.java | 28 ++ .../loveqq/test/common/CloneTest.java | 134 +++++ .../loveqq/test/common/FieldTest.java | 67 +++ .../loveqq/test/common/ListenerTest.java | 89 ++++ .../loveqq/test/common/MapperUtilTest.java | 125 +++++ .../loveqq/test/common/QueryWrapperTest.java | 202 ++++++++ .../loveqq/test/common/ReflectTest.java | 44 ++ .../loveqq/test/common/SerialUtil.java | 105 ++++ .../loveqq/test/mapper/AccountMapperTest.java | 232 +++++++++ .../loveqq/test/mapper/ActiveRecordTest.java | 208 ++++++++ .../loveqq/test/mapper/AliasTest.java | 180 +++++++ .../test/mapper/CombinedMapperTest.java | 53 ++ .../test/mapper/MyAccountMapperTest.java | 73 +++ .../loveqq/test/mapper/OuterMapperTest.java | 71 +++ .../loveqq/test/mapper/PatientMapperTest.java | 30 ++ .../loveqq/test/mapper/QueryChainTest.java | 101 ++++ .../test/mapper/UnmappedUserMapperTest.java | 98 ++++ .../loveqq/test/mapper/UserMapperTest.java | 315 ++++++++++++ .../test/service/ArticleServiceTest.java | 91 ++++ .../loveqq/test/service/FieldMappingTest.java | 35 ++ mybatis-flex-test/pom.xml | 1 + pom.xml | 3 + 119 files changed, 8030 insertions(+) create mode 100644 mybatis-flex-loveqq-starter/pom.xml create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/FlexSqlSessionFactoryBean.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAdminAutoConfiguration.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAutoConfiguration.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexProperties.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/annotation/ConditionalOnMybatisFlexDatasource.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/ConfigurationCustomizer.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/MyBatisFlexCustomizer.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/datasource/DataSourceInterceptor.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/package-info.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/service/ServiceImpl.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransaction.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionFactory.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionManager.java create mode 100644 mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/TimeoutHolder.java create mode 100644 mybatis-flex-loveqq-starter/src/main/resources/META-INF/k.factories create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/pom.xml create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/DataSourceInitListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/MyConfigurationCustomizer.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/SampleApplication.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/BaseEntity.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/DeptVO.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/RoleVO.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysDept.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysRole.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysUser.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/UserVO.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Inner.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Outer.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/TestEntity.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListenerFlag.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountTableAnnoInsertListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/BaseLogicDelete.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListenerFlag.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMissingListenerTestModelMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/ArticleMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingInnerMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/GoodMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/InnerMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/OuterMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/PatientMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/SysUserMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/TbClassMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UserMapper.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Account.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountDto.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountMissingListenerTestModel.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountOnSetListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO2.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountView.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Article.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/BaseEntity.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Disease.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMapping.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMappingInner.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Gender.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Good.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/GoodOnSetListener.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdCard.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdEntity.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Order.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderGood.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderInfo.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Patient.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/PatientVO1.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Role.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleKey.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO1.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO2.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO3.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Tag.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/TbClass.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedBaseEntity.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedUser.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/User.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserInfo.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserOrder.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserRole.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO1.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO2.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO3.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO4.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO5.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/AccountService.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/ArticleService.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/impl/ArticleServiceImpl.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/unmapped/MyUnMappedColumnHandler.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/application.yml create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/mapper/accountMapper.xml create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/LoveqqExtension.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/CloneTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/FieldTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ListenerTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/MapperUtilTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/QueryWrapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ReflectTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/SerialUtil.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AccountMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/ActiveRecordTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AliasTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/CombinedMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/OuterMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/PatientMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/QueryChainTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UserMapperTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/ArticleServiceTest.java create mode 100644 mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/FieldMappingTest.java diff --git a/mybatis-flex-loveqq-starter/pom.xml b/mybatis-flex-loveqq-starter/pom.xml new file mode 100644 index 00000000..962104e8 --- /dev/null +++ b/mybatis-flex-loveqq-starter/pom.xml @@ -0,0 +1,46 @@ + + + 4.0.0 + + com.mybatis-flex + parent + 1.10.8 + + + mybatis-flex-loveqq-starter + jar + + + 8 + 8 + + + + + com.kfyty + loveqq-boot-starter-mybatis + ${loveqq.version} + + + org.mybatis + mybatis + + + + + + com.mybatis-flex + mybatis-flex-core + ${mybatis-flex.version} + + + + org.projectlombok + lombok + ${lombok.version} + provided + + + diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/FlexSqlSessionFactoryBean.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/FlexSqlSessionFactoryBean.java new file mode 100644 index 00000000..765368f2 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/FlexSqlSessionFactoryBean.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig; + +import com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.SqlSessionFactoryBean; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.event.ContextRefreshedEvent; +import com.kfyty.loveqq.framework.core.support.Pair; +import com.mybatisflex.core.FlexConsts; +import com.mybatisflex.core.datasource.FlexDataSource; +import com.mybatisflex.core.mybatis.FlexConfiguration; +import com.mybatisflex.core.mybatis.FlexSqlSessionFactoryBuilder; +import com.mybatisflex.loveqq.framework.boot.autoconfig.transaction.FlexTransactionFactory; +import org.apache.ibatis.builder.xml.XMLConfigBuilder; +import org.apache.ibatis.mapping.Environment; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.SqlSessionFactory; + +/** + *

源于 {@link SqlSessionFactoryBean},主要是用于构建 {@link com.mybatisflex.core.mybatis.FlexConfiguration },而不是使用原生的 {@link Configuration}。 + * + * @author kfyty725 + */ +public class FlexSqlSessionFactoryBean extends SqlSessionFactoryBean { + @Autowired + private MybatisFlexProperties mybatisFlexProperties; + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + // nothing + } + + @Override + protected Class obtainConfigurationClass() { + return FlexConfiguration.class; + } + + @Override + protected Pair buildConfiguration() { + Pair configPair = super.buildConfiguration(); + + MybatisFlexProperties.CoreConfiguration coreConfiguration = this.mybatisFlexProperties.getConfiguration(); + if (coreConfiguration != null && coreConfiguration.getDefaultEnumTypeHandler() != null) { + configPair.getKey().setDefaultEnumTypeHandler(coreConfiguration.getDefaultEnumTypeHandler()); + } + + return configPair; + } + + @Override + protected void buildEnvironment(Configuration configuration) { + FlexDataSource flexDataSource; + + if (this.getDataSource() instanceof FlexDataSource) { + flexDataSource = (FlexDataSource) this.getDataSource(); + } else { + flexDataSource = new FlexDataSource(FlexConsts.NAME, this.getDataSource()); + } + + configuration.setEnvironment( + new Environment( + FlexConsts.NAME, + this.getTransactionFactory() == null ? new FlexTransactionFactory() : this.getTransactionFactory(), + flexDataSource + ) + ); + } + + @Override + protected void buildMapperLocations() { + // mybatis-flex 要延迟加载 + } + + /** + * 需先构建 sqlSessionFactory,再去初始化 mapperLocations + * 因为 xmlMapperBuilder.parse() 用到 FlexGlobalConfig, FlexGlobalConfig 的初始化是在 sqlSessionFactory 的构建方法里进行的 + * fixed https://gitee.com/mybatis-flex/mybatis-flex/issues/I6X59V + */ + @Override + protected SqlSessionFactory build(Configuration configuration) { + SqlSessionFactory sqlSessionFactory = new FlexSqlSessionFactoryBuilder().build(configuration); + super.buildMapperLocations(); + return sqlSessionFactory; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAdminAutoConfiguration.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAdminAutoConfiguration.java new file mode 100644 index 00000000..21b4a488 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAdminAutoConfiguration.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig; + +import com.kfyty.loveqq.framework.core.autoconfig.InitializingBean; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.kfyty.loveqq.framework.core.autoconfig.condition.annotation.ConditionalOnProperty; +import com.mybatisflex.core.audit.AuditManager; +import com.mybatisflex.core.audit.MessageFactory; +import com.mybatisflex.core.audit.MessageReporter; +import com.mybatisflex.core.audit.http.HttpMessageReporter; + +/** + * MyBatis-Flex-Admin 自动配置。 + * + * @author 王帅 + * @author kfyty725 + * @since 2023-07-01 + */ +@Component +@ConditionalOnProperty(prefix = "mybatis-flex.adminConfig", value = "enable", havingValue = "true") +public class MybatisFlexAdminAutoConfiguration implements InitializingBean { + @Autowired(required = false) + private MessageFactory messageFactory; + + @Autowired(required = false) + private MybatisFlexProperties properties; + + @Autowired(required = false) + private HttpMessageReporter.JSONFormatter jsonFormatter; + + @Override + public void afterPropertiesSet() { + AuditManager.setAuditEnable(true); + if (messageFactory != null) { + AuditManager.setMessageFactory(messageFactory); + } + MybatisFlexProperties.AdminConfig adminConfig = properties.getAdminConfig(); + MessageReporter messageReporter = new HttpMessageReporter( + adminConfig.getEndpoint(), + adminConfig.getSecretKey(), + jsonFormatter + ); + AuditManager.setMessageReporter(messageReporter); + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAutoConfiguration.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAutoConfiguration.java new file mode 100644 index 00000000..e465ee34 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexAutoConfiguration.java @@ -0,0 +1,262 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig; + +import com.kfyty.loveqq.framework.aop.Advisor; +import com.kfyty.loveqq.framework.aop.support.annotated.AnnotationPointcutAdvisor; +import com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.MybatisProperties; +import com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.SqlSessionFactoryBean; +import com.kfyty.loveqq.framework.core.autoconfig.InitializingBean; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Bean; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Configuration; +import com.kfyty.loveqq.framework.core.autoconfig.condition.annotation.ConditionalOnMissingBean; +import com.kfyty.loveqq.framework.core.exception.ResolvableException; +import com.kfyty.loveqq.framework.core.utils.IOUtil; +import com.mybatisflex.annotation.UseDataSource; +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.datasource.DataSourceBuilder; +import com.mybatisflex.core.datasource.DataSourceDecipher; +import com.mybatisflex.core.datasource.DataSourceManager; +import com.mybatisflex.core.datasource.FlexDataSource; +import com.mybatisflex.core.exception.FlexExceptions; +import com.mybatisflex.core.logicdelete.LogicDeleteManager; +import com.mybatisflex.core.logicdelete.LogicDeleteProcessor; +import com.mybatisflex.core.mybatis.FlexConfiguration; +import com.mybatisflex.core.table.DynamicSchemaProcessor; +import com.mybatisflex.core.table.DynamicTableProcessor; +import com.mybatisflex.core.table.TableManager; +import com.mybatisflex.core.tenant.TenantFactory; +import com.mybatisflex.core.tenant.TenantManager; +import com.mybatisflex.core.util.MapUtil; +import com.mybatisflex.loveqq.framework.boot.autoconfig.annotation.ConditionalOnMybatisFlexDatasource; +import com.mybatisflex.loveqq.framework.boot.autoconfig.customize.ConfigurationCustomizer; +import com.mybatisflex.loveqq.framework.boot.autoconfig.customize.MyBatisFlexCustomizer; +import com.mybatisflex.loveqq.framework.boot.autoconfig.datasource.DataSourceInterceptor; +import com.mybatisflex.loveqq.framework.boot.autoconfig.transaction.FlexTransactionFactory; +import com.mybatisflex.loveqq.framework.boot.autoconfig.transaction.FlexTransactionManager; +import org.apache.ibatis.transaction.TransactionFactory; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.util.Assert; +import org.springframework.util.CollectionUtils; +import org.springframework.util.StringUtils; + +import javax.sql.DataSource; +import java.io.IOException; +import java.io.InputStream; +import java.util.List; +import java.util.Map; + +/** + * Mybatis-Flex 的核心配置。 + * + * @author kfyty725 + */ +@Configuration +public class MybatisFlexAutoConfiguration implements InitializingBean { + @Autowired + protected MybatisProperties mybatisProperties; + + @Autowired + protected MybatisFlexProperties mybatisFlexProperties; + + /** + * 数据源解密器 + */ + @Autowired(required = false) + protected DataSourceDecipher dataSourceDecipher; + + /** + * 动态表名 + */ + @Autowired(required = false) + protected DynamicTableProcessor dynamicTableProcessor; + + /** + * 动态 schema 处理器 + */ + @Autowired(required = false) + protected DynamicSchemaProcessor dynamicSchemaProcessor; + + /** + * 多租户 + */ + @Autowired(required = false) + protected TenantFactory tenantFactory; + + /** + * 自定义逻辑删除处理器 + */ + @Autowired(required = false) + protected LogicDeleteProcessor logicDeleteProcessor; + + /** + * 配置监听 + */ + @Autowired(required = false) + protected List configurationCustomizers; + + /** + * 初始化监听 + */ + @Autowired(required = false) + protected List mybatisFlexCustomizers; + + @Override + public void afterPropertiesSet() { + // 检测 MyBatis 原生配置文件是否存在 + this.checkConfigFileExists(); + + // 添加 MyBatis-Flex 全局配置 + if (mybatisFlexProperties.getGlobalConfig() != null) { + mybatisFlexProperties.getGlobalConfig().applyTo(FlexGlobalConfig.getDefaultConfig()); + } + + //数据源解密器 + if (dataSourceDecipher != null) { + DataSourceManager.setDecipher(dataSourceDecipher); + } + + // 动态表名配置 + if (dynamicTableProcessor != null) { + TableManager.setDynamicTableProcessor(dynamicTableProcessor); + } + + // 动态 schema 处理器配置 + if (dynamicSchemaProcessor != null) { + TableManager.setDynamicSchemaProcessor(dynamicSchemaProcessor); + } + + //多租户 + if (tenantFactory != null) { + TenantManager.setTenantFactory(tenantFactory); + } + + //逻辑删除处理器 + if (logicDeleteProcessor != null) { + LogicDeleteManager.setProcessor(logicDeleteProcessor); + } + + //初始化监听器 + if (mybatisFlexCustomizers != null) { + mybatisFlexCustomizers.forEach(myBatisFlexCustomizer -> myBatisFlexCustomizer.customize(FlexGlobalConfig.getDefaultConfig())); + } + } + + @ConditionalOnMybatisFlexDatasource + @Bean(resolveNested = false, independent = true) + public DataSource flexDataSource() { + FlexDataSource flexDataSource = null; + + Map> dataSourceProperties = this.mybatisFlexProperties.getDatasource(); + + if (dataSourceDecipher != null) { + DataSourceManager.setDecipher(dataSourceDecipher); + } + + if (this.mybatisFlexProperties.getDefaultDatasourceKey() != null) { + Map map = dataSourceProperties.remove(this.mybatisFlexProperties.getDefaultDatasourceKey()); + if (map != null) { + flexDataSource = this.addDataSource(MapUtil.entry(this.mybatisFlexProperties.getDefaultDatasourceKey(), map), flexDataSource); + } else { + throw FlexExceptions.wrap("没有找到默认数据源 \"%s\" 对应的配置,请检查您的多数据源配置。", this.mybatisFlexProperties.getDefaultDatasourceKey()); + } + } + + for (Map.Entry> entry : dataSourceProperties.entrySet()) { + flexDataSource = this.addDataSource(entry, flexDataSource); + } + + return flexDataSource; + } + + /** + * 事务管理器 + * + * @param dataSource 数据源 + * @return 事务管理器 + */ + @Bean(resolveNested = false, independent = true) + public PlatformTransactionManager flexDataSourceTransactionManager(DataSource dataSource) { + return new FlexTransactionManager(); + } + + /** + * {@link com.mybatisflex.annotation.UseDataSource} 注解切换数据源切面。 + */ + @Bean(resolveNested = false, independent = true) + @ConditionalOnMissingBean(name = "flexDataSourceAdvisor") + public Advisor flexDataSourceAdvisor() { + return new AnnotationPointcutAdvisor(UseDataSource.class, new DataSourceInterceptor()); + } + + @ConditionalOnMissingBean + @Bean(resolveNested = false, independent = true) + public TransactionFactory flexTransactionFactory() { + return new FlexTransactionFactory(); + } + + @Bean + public SqlSessionFactoryBean flexSqlSessionFactoryBean() { + SqlSessionFactoryBean factory = new FlexSqlSessionFactoryBean(); + + this.mybatisFlexProperties.applyTo(this.mybatisProperties); + + this.applyConfiguration(factory); + + return factory; + } + + protected void applyConfiguration(SqlSessionFactoryBean factory) { + FlexConfiguration configuration = null; + MybatisFlexProperties.CoreConfiguration coreConfiguration = this.mybatisFlexProperties.getConfiguration(); + if (coreConfiguration != null || !StringUtils.hasText(this.mybatisFlexProperties.getConfigLocation())) { + configuration = new FlexConfiguration(); + } + if (configuration != null && coreConfiguration != null) { + coreConfiguration.applyTo(configuration); + } + if (!CollectionUtils.isEmpty(this.configurationCustomizers)) { + for (ConfigurationCustomizer customizer : this.configurationCustomizers) { + customizer.customize(configuration); + } + } + factory.setConfiguration(configuration); + } + + private void checkConfigFileExists() { + if (this.mybatisFlexProperties.isCheckConfigLocation() && StringUtils.hasText(this.mybatisFlexProperties.getConfigLocation())) { + try (InputStream loaded = IOUtil.load(this.mybatisProperties.getConfigLocation())) { + Assert.state(loaded != null, "Cannot find config location: " + this.mybatisProperties.getConfigLocation() + " (please add config file or check your Mybatis configuration)"); + } catch (IOException e) { + throw new ResolvableException(e); + } + } + } + + private FlexDataSource addDataSource(Map.Entry> entry, FlexDataSource flexDataSource) { + DataSource dataSource = new DataSourceBuilder(entry.getValue()).build(); + + DataSourceManager.decryptDataSource(dataSource); + + if (flexDataSource == null) { + flexDataSource = new FlexDataSource(entry.getKey(), dataSource, false); + } else { + flexDataSource.addDataSource(entry.getKey(), dataSource, false); + } + return flexDataSource; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexProperties.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexProperties.java new file mode 100644 index 00000000..56c0a2a9 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/MybatisFlexProperties.java @@ -0,0 +1,472 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig; + +import com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.MybatisProperties; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.ConfigurationProperties; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.NestedConfigurationProperty; +import com.kfyty.loveqq.framework.core.lang.util.Mapping; +import com.mybatisflex.core.FlexConsts; +import com.mybatisflex.core.FlexGlobalConfig; +import lombok.Data; +import org.apache.ibatis.io.VFS; +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.mapping.ResultSetType; +import org.apache.ibatis.scripting.LanguageDriver; +import org.apache.ibatis.session.AutoMappingBehavior; +import org.apache.ibatis.session.AutoMappingUnknownColumnBehavior; +import org.apache.ibatis.session.Configuration; +import org.apache.ibatis.session.ExecutorType; +import org.apache.ibatis.session.LocalCacheScope; +import org.apache.ibatis.type.JdbcType; +import org.apache.ibatis.type.TypeHandler; + +import java.util.Map; +import java.util.Properties; +import java.util.Set; + +/** + * Mybatis-Flex 的配置属性。 + * 参考自 mybatis-flex-spring-boot-starter + * + * @author kfyty725 + */ +@Data +@Component +@ConfigurationProperties("mybatis-flex") +public class MybatisFlexProperties { + /** + * 默认数据源 key + */ + private String defaultDatasourceKey; + + /** + *

多数据源的配置。 + * + *

+ * mybatis-flex.datasource.ds1.url=***
+ * mybatis-flex.datasource.ds2.url=*** + */ + private Map> datasource; + + /** + * 全局配置。 + */ + private GlobalConfig globalConfig; + + /** + * MyBatis-Flex-Admin 配置。 + */ + private AdminConfig adminConfig; + + /** + * Location of MyBatis xml config file. + */ + private String configLocation; + + /** + * Locations of MyBatis mapper files. + */ + private String[] mapperLocations = new String[]{"mapper/**/*.xml"}; + + /** + * Packages to search type aliases. (Package delimiters are ",; \t\n") + */ + private String typeAliasesPackage; + + /** + * The super class for filtering type alias. If this not specifies, the MyBatis deal as type alias all classes that + * searched from typeAliasesPackage. + */ + private Class typeAliasesSuperType; + + /** + * Packages to search for type handlers. (Package delimiters are ",; \t\n") + */ + private String typeHandlersPackage; + + /** + * Indicates whether perform presence check of the MyBatis xml config file. + */ + private boolean checkConfigLocation = false; + + /** + * Execution mode for {@link com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.support.ConcurrentSqlSession}. + */ + private ExecutorType executorType; + + /** + * The default scripting language driver class. (Available when use together with mybatis-spring 2.0.2+) + */ + private Class defaultScriptingLanguageDriver; + + /** + * Externalized properties for MyBatis configuration. + */ + private Properties configurationProperties; + + /** + * A Configuration object for customize default settings. If {@link #configLocation} is specified, this property is + * not used. + */ + private CoreConfiguration configuration; + + /** + * 合并到 {@link MybatisProperties} 配置 + * + * @param properties 配置 + */ + void applyTo(MybatisProperties properties) { + Mapping.from(getConfigLocation()).whenNotNull(properties::setConfigLocation); + Mapping.from(getExecutorType()).whenNotNull(properties::setExecutorType); + Mapping.from(getTypeAliasesPackage()).whenNotNull(properties::setTypeAliasesPackage); + Mapping.from(getTypeHandlersPackage()).whenNotNull(properties::setTypeHandlersPackage); + Mapping.from(getMapperLocations()).whenNotNull(properties::setMapperLocations); + Mapping.from(getDefaultScriptingLanguageDriver()).whenNotNull(properties::setDefaultScriptingLanguageDriver); + Mapping.from(getConfigurationProperties()).whenNotNull(properties::setConfigurationProperties); + Mapping.from(getConfiguration()).notNullMap(CoreConfiguration::getVfsImpl).whenNotNull(properties::setVfs); + } + + /** + * The configuration properties for mybatis core module. + * + * @since 3.0.0 + */ + @Data + @NestedConfigurationProperty + public static class CoreConfiguration { + /** + * Allows using RowBounds on nested statements. If allow, set the false. Default is false. + */ + private Boolean safeRowBoundsEnabled; + + /** + * Allows using ResultHandler on nested statements. If allow, set the false. Default is true. + */ + private Boolean safeResultHandlerEnabled; + + /** + * Enables automatic mapping from classic database column names A_COLUMN to camel case classic Java property names + * aColumn. Default is true. + */ + private Boolean mapUnderscoreToCamelCase = true; + + /** + * When enabled, any method call will load all the lazy properties of the object. Otherwise, each property is loaded + * on demand (see also lazyLoadTriggerMethods). Default is false. + */ + private Boolean aggressiveLazyLoading; + + /** + * Allows or disallows multiple ResultSets to be returned from a single statement (compatible driver required). + * Default is true. + */ + private Boolean multipleResultSetsEnabled; + + /** + * Allows JDBC support for generated keys. A compatible driver is required. This setting forces generated keys to be + * used if set to true, as some drivers deny compatibility but still work (e.g. Derby). Default is false. + */ + private Boolean useGeneratedKeys; + + /** + * Uses the column label instead of the column name. Different drivers behave differently in this respect. Refer to + * the driver documentation, or test out both modes to determine how your driver behaves. Default is true. + */ + private Boolean useColumnLabel; + + /** + * Globally enables or disables any caches configured in any mapper under this configuration. Default is true. + */ + private Boolean cacheEnabled; + + /** + * Specifies if setters or map's put method will be called when a retrieved value is null. It is useful when you + * rely on Map.keySet() or null value initialization. Note primitives such as (int,boolean,etc.) will not be set to + * null. Default is false. + */ + private Boolean callSettersOnNulls; + + /** + * Allow referencing statement parameters by their actual names declared in the method signature. To use this + * feature, your project must be compiled in Java 8 with -parameters option. Default is true. + */ + private Boolean useActualParamName; + + /** + * MyBatis, by default, returns null when all the columns of a returned row are NULL. When this setting is enabled, + * MyBatis returns an empty instance instead. Note that it is also applied to nested results (i.e. collectioin and + * association). Default is false. + */ + private Boolean returnInstanceForEmptyRow; + + /** + * Removes extra whitespace characters from the SQL. Note that this also affects literal strings in SQL. Default is + * false. + */ + private Boolean shrinkWhitespacesInSql; + + /** + * Specifies the default value of 'nullable' attribute on 'foreach' tag. Default is false. + */ + private Boolean nullableOnForEach; + + /** + * When applying constructor auto-mapping, argument name is used to search the column to map instead of relying on + * the column order. Default is false. + */ + private Boolean argNameBasedConstructorAutoMapping; + + /** + * Globally enables or disables lazy loading. When enabled, all relations will be lazily loaded. This value can be + * superseded for a specific relation by using the fetchType attribute on it. Default is False. + */ + private Boolean lazyLoadingEnabled; + + /** + * Sets the number of seconds the driver will wait for a response from the database. + */ + private Integer defaultStatementTimeout; + + /** + * Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a + * query setting. + */ + private Integer defaultFetchSize; + + /** + * MyBatis uses local cache to prevent circular references and speed up repeated nested queries. By default + * (SESSION) all queries executed during a session are cached. If localCacheScope=STATEMENT local session will be + * used just for statement execution, no data will be shared between two different calls to the same SqlSession. + * Default is SESSION. + */ + private LocalCacheScope localCacheScope; + + /** + * Specifies the JDBC type for null values when no specific JDBC type was provided for the parameter. Some drivers + * require specifying the column JDBC type but others work with generic values like NULL, VARCHAR or OTHER. Default + * is OTHER. + */ + private JdbcType jdbcTypeForNull; + + /** + * Specifies a scroll strategy when omit it per statement settings. + */ + private ResultSetType defaultResultSetType; + + /** + * Configures the default executor. SIMPLE executor does nothing special. REUSE executor reuses prepared statements. + * BATCH executor reuses statements and batches updates. Default is SIMPLE. + */ + private ExecutorType defaultExecutorType; + + /** + * Specifies if and how MyBatis should automatically map columns to fields/properties. NONE disables auto-mapping. + * PARTIAL will only auto-map results with no nested result mappings defined inside. FULL will auto-map result + * mappings of any complexity (containing nested or otherwise). Default is PARTIAL. + */ + private AutoMappingBehavior autoMappingBehavior; + + /** + * Specify the behavior when detects an unknown column (or unknown property type) of automatic mapping target. + * Default is NONE. + */ + private AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior; + + /** + * Specifies the prefix string that MyBatis will add to the logger names. + */ + private String logPrefix; + + /** + * Specifies which Object's methods trigger a lazy load. Default is [equals,clone,hashCode,toString]. + */ + private Set lazyLoadTriggerMethods; + + /** + * Specifies which logging implementation MyBatis should use. If this setting is not present logging implementation + * will be autodiscovered. + */ + private Class logImpl; + + /** + * Specifies VFS implementations. + */ + private Class vfsImpl; + + /** + * Specifies an sql provider class that holds provider method. This class apply to the type(or value) attribute on + * sql provider annotation(e.g. @SelectProvider), when these attribute was omitted. + */ + private Class defaultSqlProviderType; + + /** + * Specifies the TypeHandler used by default for Enum. + */ + Class defaultEnumTypeHandler; + + /** + * Specifies the class that provides an instance of Configuration. The returned Configuration instance is used to + * load lazy properties of deserialized objects. This class must have a method with a signature static Configuration + * getConfiguration(). + */ + private Class configurationFactory; + + /** + * Specify any configuration variables. + */ + private Properties variables; + + void applyTo(Configuration target) { + Mapping.from(getSafeRowBoundsEnabled()).whenNotNull(target::setSafeRowBoundsEnabled); + Mapping.from(getSafeResultHandlerEnabled()).whenNotNull(target::setSafeResultHandlerEnabled); + Mapping.from(getMapUnderscoreToCamelCase()).whenNotNull(target::setMapUnderscoreToCamelCase); + Mapping.from(getAggressiveLazyLoading()).whenNotNull(target::setAggressiveLazyLoading); + Mapping.from(getMultipleResultSetsEnabled()).whenNotNull(target::setMultipleResultSetsEnabled); + Mapping.from(getUseGeneratedKeys()).whenNotNull(target::setUseGeneratedKeys); + Mapping.from(getUseColumnLabel()).whenNotNull(target::setUseColumnLabel); + Mapping.from(getCacheEnabled()).whenNotNull(target::setCacheEnabled); + Mapping.from(getCallSettersOnNulls()).whenNotNull(target::setCallSettersOnNulls); + Mapping.from(getUseActualParamName()).whenNotNull(target::setUseActualParamName); + Mapping.from(getReturnInstanceForEmptyRow()).whenNotNull(target::setReturnInstanceForEmptyRow); + Mapping.from(getShrinkWhitespacesInSql()).whenNotNull(target::setShrinkWhitespacesInSql); + Mapping.from(getNullableOnForEach()).whenNotNull(target::setNullableOnForEach); + Mapping.from(getArgNameBasedConstructorAutoMapping()).whenNotNull(target::setArgNameBasedConstructorAutoMapping); + Mapping.from(getLazyLoadingEnabled()).whenNotNull(target::setLazyLoadingEnabled); + Mapping.from(getLogPrefix()).whenNotNull(target::setLogPrefix); + Mapping.from(getLazyLoadTriggerMethods()).whenNotNull(target::setLazyLoadTriggerMethods); + Mapping.from(getDefaultStatementTimeout()).whenNotNull(target::setDefaultStatementTimeout); + Mapping.from(getDefaultFetchSize()).whenNotNull(target::setDefaultFetchSize); + Mapping.from(getLocalCacheScope()).whenNotNull(target::setLocalCacheScope); + Mapping.from(getJdbcTypeForNull()).whenNotNull(target::setJdbcTypeForNull); + Mapping.from(getDefaultResultSetType()).whenNotNull(target::setDefaultResultSetType); + Mapping.from(getDefaultExecutorType()).whenNotNull(target::setDefaultExecutorType); + Mapping.from(getAutoMappingBehavior()).whenNotNull(target::setAutoMappingBehavior); + Mapping.from(getAutoMappingUnknownColumnBehavior()).whenNotNull(target::setAutoMappingUnknownColumnBehavior); + Mapping.from(getVariables()).whenNotNull(target::setVariables); + Mapping.from(getLogImpl()).whenNotNull(target::setLogImpl); + Mapping.from(getVfsImpl()).whenNotNull(target::setVfsImpl); + Mapping.from(getDefaultSqlProviderType()).whenNotNull(target::setDefaultSqlProviderType); + Mapping.from(getConfigurationFactory()).whenNotNull(target::setConfigurationFactory); + Mapping.from(getDefaultEnumTypeHandler()).whenNotNull(target::setDefaultEnumTypeHandler); + } + } + + /** + * {@link FlexGlobalConfig} 配置。 + * + * @author 王帅 + * @author kfyty725 + * @since 2023-06-21 + */ + @Data + @NestedConfigurationProperty + public static class GlobalConfig { + /** + * 启动是否打印 banner 和 版本号。 + */ + private boolean printBanner = true; + + /** + * 全局的 ID 生成策略配置,当 @Id 未配置 或者 配置 KeyType 为 None 时 + * 使用当前全局配置。 + */ + @NestedConfigurationProperty + private FlexGlobalConfig.KeyConfig keyConfig; + + /** + * 逻辑删除数据存在标记值。 + */ + private Object normalValueOfLogicDelete = FlexConsts.LOGIC_DELETE_NORMAL; + + /** + * 逻辑删除数据删除标记值。 + */ + private Object deletedValueOfLogicDelete = FlexConsts.LOGIC_DELETE_DELETED; + + + /** + * 默认的分页查询时的每页数据量。 + */ + private int defaultPageSize = 10; + + + /** + * 默认的 Relation 注解查询深度。 + */ + private int defaultRelationQueryDepth = 2; + + /** + * 默认的逻辑删除字段。 + */ + private String logicDeleteColumn; + + /** + * 默认的多租户字段。 + */ + private String tenantColumn; + + /** + * 默认的乐观锁字段。 + */ + private String versionColumn; + + /** + * 全局忽略 @Table 中配置的 schema + */ + private boolean ignoreSchema = false; + + void applyTo(FlexGlobalConfig target) { + Mapping.from(isPrintBanner()).whenNotNull(target::setPrintBanner); + Mapping.from(getKeyConfig()).whenNotNull(target::setKeyConfig); + Mapping.from(getNormalValueOfLogicDelete()).whenNotNull(target::setNormalValueOfLogicDelete); + Mapping.from(getDeletedValueOfLogicDelete()).whenNotNull(target::setDeletedValueOfLogicDelete); + Mapping.from(getDefaultPageSize()).whenNotNull(target::setDefaultPageSize); + Mapping.from(getDefaultRelationQueryDepth()).whenNotNull(target::setDefaultRelationQueryDepth); + Mapping.from(getLogicDeleteColumn()).whenNotNull(target::setLogicDeleteColumn); + Mapping.from(getVersionColumn()).whenNotNull(target::setVersionColumn); + Mapping.from(getTenantColumn()).whenNotNull(target::setTenantColumn); + Mapping.from(isIgnoreSchema()).whenNotNull(target::setIgnoreSchema); + } + } + + /** + * MyBatis Flex Admin 配置。 + * + * @author 王帅 + * @author kfyty725 + * @since 2023-07-02 + */ + @Data + @NestedConfigurationProperty + public static class AdminConfig { + /** + * 启用服务。 + */ + private boolean enable; + + /** + * 连接端点。 + */ + private String endpoint; + + /** + * 秘密密钥。 + */ + private String secretKey; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/annotation/ConditionalOnMybatisFlexDatasource.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/annotation/ConditionalOnMybatisFlexDatasource.java new file mode 100644 index 00000000..e3c85a7e --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/annotation/ConditionalOnMybatisFlexDatasource.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.annotation; + +import com.kfyty.loveqq.framework.core.autoconfig.condition.Condition; +import com.kfyty.loveqq.framework.core.autoconfig.condition.ConditionContext; +import com.kfyty.loveqq.framework.core.autoconfig.condition.annotation.Conditional; +import com.kfyty.loveqq.framework.core.autoconfig.env.PropertyContext; +import com.kfyty.loveqq.framework.core.support.AnnotationMetadata; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Map; + +/** + *

判断是否有 MyBatis-Flex 的多数据源配置。 + *

如果配置文件中有 MyBatis-Flex 的多数据源配置,就加载 MyBatis-Flex 多数据源自动配置类。 + * + * @author michael + */ +@Documented +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.METHOD}) +@Conditional(ConditionalOnMybatisFlexDatasource.OnMybatisFlexDataSourceCondition.class) +public @interface ConditionalOnMybatisFlexDatasource { + + class OnMybatisFlexDataSourceCondition implements Condition { + + @Override + public boolean isMatch(ConditionContext context, AnnotationMetadata metadata) { + PropertyContext propertyContext = context.getBeanFactory().getBean(PropertyContext.class); + Map properties = propertyContext.searchMapProperties("mybatis-flex.datasource"); + return properties != null && !properties.isEmpty(); + } + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/ConfigurationCustomizer.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/ConfigurationCustomizer.java new file mode 100644 index 00000000..b4ccf45c --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/ConfigurationCustomizer.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.customize; + +import com.mybatisflex.core.mybatis.FlexConfiguration; + +/** + * 为 {@link FlexConfiguration} 做自定义的配置支持。 + * + * @author michael + */ +@FunctionalInterface +public interface ConfigurationCustomizer { + /** + * 自定义配置 {@link FlexConfiguration}。 + * + * @param configuration MyBatis Flex Configuration + */ + void customize(FlexConfiguration configuration); +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/MyBatisFlexCustomizer.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/MyBatisFlexCustomizer.java new file mode 100644 index 00000000..0f7c313f --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/customize/MyBatisFlexCustomizer.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.customize; + +import com.mybatisflex.core.FlexGlobalConfig; + +/** + *

MyBatis-Flex 配置。 + * + *

一般可以用于去初始化: + * + *

+ */ +public interface MyBatisFlexCustomizer { + /** + * 自定义 MyBatis-Flex 配置。 + * + * @param globalConfig 全局配置 + */ + void customize(FlexGlobalConfig globalConfig); +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/datasource/DataSourceInterceptor.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/datasource/DataSourceInterceptor.java new file mode 100644 index 00000000..67fbb8ec --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/datasource/DataSourceInterceptor.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.datasource; + +import com.kfyty.loveqq.framework.core.support.Pair; +import com.mybatisflex.annotation.UseDataSource; +import com.mybatisflex.core.datasource.DataSourceKey; +import com.mybatisflex.core.util.StringUtil; +import org.aopalliance.intercept.MethodInterceptor; +import org.aopalliance.intercept.MethodInvocation; + +import java.lang.reflect.Method; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +/** + * 多数据源切换拦截器。 + * + * @author 王帅 + * @author barql + * @author michael + * @since 2023-06-25 + */ +public class DataSourceInterceptor implements MethodInterceptor { + /** + * 缓存方法对应的数据源。 + */ + private final Map dsCache = new ConcurrentHashMap<>(); + + @Override + public Object invoke(MethodInvocation invocation) throws Throwable { + String dsKey = getDataSourceKey(invocation.getThis(), invocation.getMethod(), invocation.getArguments()); + if (StringUtil.noText(dsKey)) { + return invocation.proceed(); + } + try { + DataSourceKey.use(dsKey); + return invocation.proceed(); + } finally { + DataSourceKey.clear(); + } + } + + private String getDataSourceKey(Object target, Method method, Object[] arguments) { + Object cacheKey = new Pair<>(method, target.getClass()); + String dsKey = this.dsCache.get(cacheKey); + if (dsKey == null) { + dsKey = determineDataSourceKey(method, target.getClass()); + // 对数据源取值进行动态取值处理 + if (StringUtil.hasText(dsKey)) { + dsKey = DataSourceKey.processDataSourceKey(dsKey, target, method, arguments); + } + this.dsCache.put(cacheKey, dsKey); + } + return dsKey; + } + + private String determineDataSourceKey(Method method, Class targetClass) { + // 方法上定义有 UseDataSource 注解 + UseDataSource annotation = method.getAnnotation(UseDataSource.class); + if (annotation != null) { + return annotation.value(); + } + // 类上定义有 UseDataSource 注解 + annotation = targetClass.getAnnotation(UseDataSource.class); + if (annotation != null) { + return annotation.value(); + } + // 接口上定义有 UseDataSource 注解 + Class[] interfaces = targetClass.getInterfaces(); + for (Class anInterface : interfaces) { + annotation = anInterface.getAnnotation(UseDataSource.class); + if (annotation != null) { + return annotation.value(); + } + } + // 哪里都没有 UseDataSource 注解 + return ""; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/package-info.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/package-info.java new file mode 100644 index 00000000..ea911cd7 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/package-info.java @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * MyBatis-Flex loveqq-framework 支持。 + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig; diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/service/ServiceImpl.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/service/ServiceImpl.java new file mode 100644 index 00000000..1fc1990d --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/service/ServiceImpl.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.service; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.core.service.IService; + +/** + * 由 Mybatis-Flex 提供的顶级增强 Service 接口的默认实现类。 + * + * @param 实体类(Entity)类型 + * @param 映射类(Mapper)类型 + * @author 王帅 + * @since 2023-05-01 + */ +@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection") +public class ServiceImpl, T> implements IService { + + @Autowired + protected M mapper; + + @Override + public M getMapper() { + return mapper; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransaction.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransaction.java new file mode 100644 index 00000000..4cccea83 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransaction.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.transaction; + +import com.mybatisflex.core.transaction.TransactionContext; +import com.mybatisflex.core.util.StringUtil; +import org.apache.ibatis.transaction.Transaction; + +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +/** + * spring 事务支持,解决 issues: https://gitee.com/mybatis-flex/mybatis-flex/issues/I7HJ4J + * + * @author life + * @author michael + */ +public class FlexTransaction implements Transaction { + + private final DataSource dataSource; + private Boolean isConnectionTransactional; + private Boolean autoCommit; + private Connection connection; + + public FlexTransaction(DataSource dataSource) { + this.dataSource = dataSource; + } + + @Override + public Connection getConnection() throws SQLException { + if (isConnectionTransactional == null) { + connection = dataSource.getConnection(); + isConnectionTransactional = StringUtil.hasText(TransactionContext.getXID()); + autoCommit = connection.getAutoCommit(); + return connection; + } + // 在事务中,通过 FlexDataSource 去获取 + // FlexDataSource 内部会进行 connection 缓存以及多数据源下的 key 判断 + else if (isConnectionTransactional) { + return dataSource.getConnection(); + } + // 非事务,返回当前链接 + else { + return connection; + } + } + + @Override + public void commit() throws SQLException { + if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) { + this.connection.commit(); + } + } + + @Override + public void rollback() throws SQLException { + if (this.connection != null && !this.isConnectionTransactional && !this.autoCommit) { + this.connection.rollback(); + } + } + + @Override + public void close() throws SQLException { + if (this.connection != null && !this.isConnectionTransactional) { + connection.close(); + } + } + + @Override + public Integer getTimeout() throws SQLException { + return TimeoutHolder.getTimeToLiveInSeconds(); + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionFactory.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionFactory.java new file mode 100644 index 00000000..065e91cf --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionFactory.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.transaction; + +import org.apache.ibatis.session.TransactionIsolationLevel; +import org.apache.ibatis.transaction.Transaction; +import org.apache.ibatis.transaction.TransactionFactory; + +import javax.sql.DataSource; +import java.sql.Connection; + +/** + * @author life + * @author michael + */ +public class FlexTransactionFactory implements TransactionFactory { + /** + * {@inheritDoc} + */ + @Override + public Transaction newTransaction(DataSource dataSource, TransactionIsolationLevel level, boolean autoCommit) { + return new FlexTransaction(dataSource); + } + + /** + * {@inheritDoc} + */ + @Override + public Transaction newTransaction(Connection conn) { + throw new UnsupportedOperationException("New Flex transactions require a DataSource"); + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionManager.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionManager.java new file mode 100644 index 00000000..8bf8d0da --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/FlexTransactionManager.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.transaction; + +import com.mybatisflex.core.transaction.TransactionContext; +import com.mybatisflex.core.transaction.TransactionalManager; +import com.mybatisflex.core.util.StringUtil; +import org.springframework.jdbc.datasource.JdbcTransactionObjectSupport; +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionException; +import org.springframework.transaction.support.AbstractPlatformTransactionManager; +import org.springframework.transaction.support.DefaultTransactionStatus; + +/** + * MyBatis-Flex 事务支持。 + * + * @author michael + */ +public class FlexTransactionManager extends AbstractPlatformTransactionManager { + + @Override + protected Object doGetTransaction() throws TransactionException { + return new TransactionObject(TransactionContext.getXID()); + } + + @Override + protected boolean isExistingTransaction(Object transaction) throws TransactionException { + TransactionObject transactionObject = (TransactionObject) transaction; + return StringUtil.hasText(transactionObject.prevXid); + } + + @Override + protected Object doSuspend(Object transaction) throws TransactionException { + TransactionContext.release(); + TransactionObject transactionObject = (TransactionObject) transaction; + return transactionObject.prevXid; + } + + @Override + protected void doResume(Object transaction, Object suspendedResources) throws TransactionException { + String xid = (String) suspendedResources; + TransactionContext.holdXID(xid); + } + + @Override + protected void doBegin(Object transaction, TransactionDefinition definition) throws TransactionException { + TransactionObject transactionObject = (TransactionObject) transaction; + transactionObject.currentXid = TransactionalManager.startTransactional(); + + TimeoutHolder.hold(definition); + } + + @Override + protected void doCommit(DefaultTransactionStatus status) throws TransactionException { + TransactionObject transactionObject = (TransactionObject) status.getTransaction(); + TransactionalManager.commit(transactionObject.currentXid); + transactionObject.clear(); + } + + @Override + protected void doRollback(DefaultTransactionStatus status) throws TransactionException { + TransactionObject transactionObject = (TransactionObject) status.getTransaction(); + TransactionalManager.rollback(transactionObject.currentXid); + transactionObject.clear(); + } + + @Override + protected void doSetRollbackOnly(DefaultTransactionStatus status) throws TransactionException { + // 在多个事务嵌套时,子事务的传递方式为 REQUIRED(加入当前事务) + // 那么,当子事务抛出异常时,会调当前方法,而不是直接调用 doRollback + // 此时,需要标识 prevXid 进行 Rollback + TransactionObject transactionObject = (TransactionObject) status.getTransaction(); + transactionObject.setRollbackOnly(); + } + + @Override + protected void doCleanupAfterCompletion(Object transaction) { + TimeoutHolder.clear(); + } + + static class TransactionObject extends JdbcTransactionObjectSupport { + + private static final ThreadLocal ROLLBACK_ONLY_XIDS = new ThreadLocal<>(); + + private final String prevXid; + private String currentXid; + + public TransactionObject(String prevXid) { + this.prevXid = prevXid; + } + + public void setRollbackOnly() { + ROLLBACK_ONLY_XIDS.set(prevXid); + } + + public void clear() { + ROLLBACK_ONLY_XIDS.remove(); + } + + @Override + public boolean isRollbackOnly() { + return currentXid != null && currentXid.equals(ROLLBACK_ONLY_XIDS.get()); + } + } + +} diff --git a/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/TimeoutHolder.java b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/TimeoutHolder.java new file mode 100644 index 00000000..94854dce --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/java/com/mybatisflex/loveqq/framework/boot/autoconfig/transaction/TimeoutHolder.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.framework.boot.autoconfig.transaction; + +import org.springframework.transaction.TransactionDefinition; +import org.springframework.transaction.TransactionTimedOutException; + +import java.util.Date; + +/** + * 事务定义管理器 用于更完整的实现Spring事务 + * 仅支持传统事务不支持R2DBC事务 + * + * @author Aliothmoon + * @author Michael + * @since 2024/10/25 + */ +public final class TimeoutHolder { + private static final ThreadLocal TRANSACTION_DEADLINE = new ThreadLocal<>(); + + public static void hold(TransactionDefinition definition) { + if (definition == null) { + return; + } + int timeout = definition.getTimeout(); + if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) { + Long deadline = System.currentTimeMillis() + timeout * 1000L; + TRANSACTION_DEADLINE.set(deadline); + } + } + + + /** + * 清除事务上下文 + */ + public static void clear() { + TRANSACTION_DEADLINE.remove(); + } + + /** + * 获取当前事务可用TTL + * + * @return int + */ + public static Integer getTimeToLiveInSeconds() { + Long deadline = TRANSACTION_DEADLINE.get(); + if (deadline == null) { + return null; + } + double diff = ((double) getTimeToLiveInMillis(deadline)) / 1000; + int secs = (int) Math.ceil(diff); + checkTransactionTimeout(secs <= 0, deadline); + return secs; + } + + + private static void checkTransactionTimeout(boolean deadlineReached, Long deadline) throws TransactionTimedOutException { + if (deadlineReached) { + throw new TransactionTimedOutException("Transaction timed out: deadline was " + new Date(deadline)); + } + } + + + private static long getTimeToLiveInMillis(Long deadline) throws TransactionTimedOutException { + if (deadline == null) { + throw new IllegalStateException("No timeout specified for this resource holder"); + } + long timeToLive = deadline - System.currentTimeMillis(); + checkTransactionTimeout(timeToLive <= 0, deadline); + return timeToLive; + } +} diff --git a/mybatis-flex-loveqq-starter/src/main/resources/META-INF/k.factories b/mybatis-flex-loveqq-starter/src/main/resources/META-INF/k.factories new file mode 100644 index 00000000..653abe35 --- /dev/null +++ b/mybatis-flex-loveqq-starter/src/main/resources/META-INF/k.factories @@ -0,0 +1,4 @@ +com.kfyty.loveqq.framework.core.autoconfig.annotation.EnableAutoConfiguration=\ + com.mybatisflex.loveqq.framework.boot.autoconfig.MybatisFlexProperties,\ + com.mybatisflex.loveqq.framework.boot.autoconfig.MybatisFlexAutoConfiguration,\ + com.mybatisflex.loveqq.framework.boot.autoconfig.MybatisFlexAdminAutoConfiguration diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/pom.xml b/mybatis-flex-test/mybatis-flex-loveqq-test/pom.xml new file mode 100644 index 00000000..35cde995 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/pom.xml @@ -0,0 +1,63 @@ + + + 4.0.0 + + mybatis-flex-test + com.mybatis-flex + 1.10.8 + + + mybatis-flex-loveqq-test + jar + + + 8 + 8 + + + + + com.kfyty + loveqq-boot + ${loveqq.version} + + + + com.mybatis-flex + mybatis-flex-loveqq-starter + ${mybatis-flex.version} + + + + com.kfyty + loveqq-boot-starter-logback + ${loveqq.version} + + + + org.yaml + snakeyaml + 2.2 + + + + com.alibaba.fastjson2 + fastjson2 + 2.0.32 + + + + com.mysql + mysql-connector-j + + + + org.junit.jupiter + junit-jupiter + 5.5.2 + test + + + diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/DataSourceInitListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/DataSourceInitListener.java new file mode 100644 index 00000000..ce1575b9 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/DataSourceInitListener.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.kfyty.loveqq.framework.core.event.ApplicationListener; +import com.kfyty.loveqq.framework.core.event.ContextRefreshedEvent; +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.datasource.FlexDataSource; + +@Component +public class DataSourceInitListener implements ApplicationListener { + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + FlexDataSource dataSource = FlexGlobalConfig.getDefaultConfig().getDataSource(); + System.out.println("onApplicationEvent>>>> datasource:" + dataSource); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/MyConfigurationCustomizer.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/MyConfigurationCustomizer.java new file mode 100644 index 00000000..b54c1157 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/MyConfigurationCustomizer.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Configuration; +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.datasource.DataSourceDecipher; +import com.mybatisflex.core.datasource.DataSourceManager; +import com.mybatisflex.core.mybatis.FlexConfiguration; +import com.mybatisflex.loveqq.framework.boot.autoconfig.customize.ConfigurationCustomizer; +import com.mybatisflex.loveqq.framework.boot.autoconfig.customize.MyBatisFlexCustomizer; +import com.mybatisflex.loveqq.test.unmapped.MyUnMappedColumnHandler; +import org.apache.ibatis.logging.stdout.StdOutImpl; + +@Configuration +public class MyConfigurationCustomizer implements ConfigurationCustomizer, MyBatisFlexCustomizer { + + @Override + public void customize(FlexConfiguration configuration) { + System.out.println(">>>>>>> MyConfigurationCustomizer.customize() invoked"); + configuration.setLogImpl(StdOutImpl.class); + } + +// @Bean +// public DataSourceDecipher decipher() { +// DataSourceDecipher decipher = new DataSourceDecipher() { +// @Override +// public String decrypt(DataSourceProperty property, String value) { +// System.out.println(">>>>>> decipher.decrypt"); +// return value; +// } +// }; +// return decipher; +// } + + @Override + public void customize(FlexGlobalConfig globalConfig) { + DataSourceDecipher decipher = (property, value) -> { + System.out.println(">>>>>> decipher.decrypt"); + return value; + }; + DataSourceManager.setDecipher(decipher); + globalConfig.setUnMappedColumnHandler(new MyUnMappedColumnHandler()); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/SampleApplication.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/SampleApplication.java new file mode 100644 index 00000000..c8294a92 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/SampleApplication.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.kfyty.loveqq.framework.boot.K; +import com.kfyty.loveqq.framework.boot.data.orm.mybatis.autoconfig.annotation.MapperScan; +import com.kfyty.loveqq.framework.core.autoconfig.CommandLineRunner; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Bean; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.BootApplication; +import com.kfyty.loveqq.framework.core.autoconfig.condition.annotation.ConditionalOnMissingBean; +import com.kfyty.loveqq.framework.core.event.ApplicationListener; +import com.kfyty.loveqq.framework.core.event.ContextRefreshedEvent; +import com.kfyty.loveqq.framework.core.utils.JsonUtil; +import com.mybatisflex.core.audit.AuditManager; +import com.mybatisflex.core.audit.ConsoleMessageCollector; +import com.mybatisflex.core.audit.MessageCollector; +import com.mybatisflex.loveqq.test.mapper.AccountMapper; + +@BootApplication +@MapperScan("com.mybatisflex.loveqq.test.mapper.**.*") +public class SampleApplication implements CommandLineRunner, ApplicationListener { + @Autowired + private AccountMapper accountMapper; + + @Override + public void run(String... args) throws Exception { + System.out.println(this.accountMapper.selectOneById(1)); + } + + public static void main(String[] args) { + K.start(SampleApplication.class, args); + } + + @Override + public void onApplicationEvent(ContextRefreshedEvent event) { + System.out.println("onApplicationEvent"); + // 开启审计功能 + AuditManager.setAuditEnable(true); + // 设置 SQL 审计收集器 + MessageCollector collector = new ConsoleMessageCollector((sql, tookTimeMillis) -> System.out.println(sql)); + AuditManager.setMessageCollector(collector); + } + + @ConditionalOnMissingBean + @Bean(resolveNested = false, independent = true) + public ObjectMapper objectMapper() { + return JsonUtil.configure(); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/BaseEntity.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/BaseEntity.java new file mode 100644 index 00000000..a94de327 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/BaseEntity.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import java.io.Serializable; +import java.util.Date; + +/** + * 父类。 + * + * @author 王帅 + * @since 2023-11-16 + */ +public abstract class BaseEntity implements Serializable { + + private Date createTime; + private String createBy; + private Date updateTime; + private String updateBy; + + public Date getCreateTime() { + return createTime; + } + + public void setCreateTime(Date createTime) { + this.createTime = createTime; + } + + public String getCreateBy() { + return createBy; + } + + public void setCreateBy(String createBy) { + this.createBy = createBy; + } + + public Date getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(Date updateTime) { + this.updateTime = updateTime; + } + + public String getUpdateBy() { + return updateBy; + } + + public void setUpdateBy(String updateBy) { + this.updateBy = updateBy; + } + + @Override + public String toString() { + return "BaseEntity{" + + "createTime=" + createTime + + ", createBy='" + createBy + '\'' + + ", updateTime=" + updateTime + + ", updateBy='" + updateBy + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/DeptVO.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/DeptVO.java new file mode 100644 index 00000000..edc4bd74 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/DeptVO.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.TableRef; + +/** + * 部门。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@TableRef(SysDept.class) +public class DeptVO extends BaseEntity { + + private Integer id; + private String deptName; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + @Override + public String toString() { + return "SysDept{" + + "id=" + id + + ", deptName='" + deptName + '\'' + + '}' + super.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/RoleVO.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/RoleVO.java new file mode 100644 index 00000000..3db6f4fa --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/RoleVO.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.TableRef; + +/** + * 角色。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@TableRef(SysRole.class) +public class RoleVO extends BaseEntity { + + private Integer id; + private String roleKey; + private String roleName; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getRoleKey() { + return roleKey; + } + + public void setRoleKey(String roleKey) { + this.roleKey = roleKey; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + @Override + public String toString() { + return "SysRole{" + + "id=" + id + + ", roleKey='" + roleKey + '\'' + + ", roleName='" + roleName + '\'' + + '}' + super.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysDept.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysDept.java new file mode 100644 index 00000000..88f0052e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysDept.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; + +/** + * 部门。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@Table("sys_dept") +public class SysDept extends BaseEntity { + + @Id(keyType = KeyType.Auto) + private Integer id; + private String deptName; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getDeptName() { + return deptName; + } + + public void setDeptName(String deptName) { + this.deptName = deptName; + } + + @Override + public String toString() { + return "SysDept{" + + "id=" + id + + ", deptName='" + deptName + '\'' + + '}' + super.toString(); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysRole.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysRole.java new file mode 100644 index 00000000..186cde81 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysRole.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; + +/** + * 角色。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@Table("sys_role") +public class SysRole extends BaseEntity { + + @Id(keyType = KeyType.Auto) + private Integer id; + private String roleKey; + private String roleName; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getRoleKey() { + return roleKey; + } + + public void setRoleKey(String roleKey) { + this.roleKey = roleKey; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + @Override + public String toString() { + return "SysRole{" + + "id=" + id + + ", roleKey='" + roleKey + '\'' + + ", roleName='" + roleName + '\'' + + '}' + super.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysUser.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysUser.java new file mode 100644 index 00000000..84df58ee --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/SysUser.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.ColumnAlias; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; + +import java.util.Date; +import java.util.List; + +/** + * 用户。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@Table("sys_user") +public class SysUser extends BaseEntity { + + @Id(keyType = KeyType.Auto) + private Integer id; + private String userName; + @ColumnAlias("user_age") + private Integer age; + private Date birthday; + + private List roleList; + private List deptList; + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getDeptList() { + return deptList; + } + + public void setDeptList(List deptList) { + this.deptList = deptList; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + @Override + public String toString() { + return "SysUser{" + + "id=" + id + + ", userName='" + userName + '\'' + + ", age=" + age + + ", birthday=" + birthday + + ", roleList=" + roleList + + ", deptList=" + deptList + + '}' + super.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/UserVO.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/UserVO.java new file mode 100644 index 00000000..07e01471 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/alias/UserVO.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.alias; + +import com.mybatisflex.annotation.ColumnAlias; +import com.mybatisflex.annotation.TableRef; + +import java.util.Date; +import java.util.List; + +/** + * 用户。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@TableRef(SysUser.class) +public class UserVO extends BaseEntity { + + private Integer id; + private String userName; + @ColumnAlias("user_age") + private Integer age; + private Date birthday; + + private List roleList; + private List deptList; + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getDeptList() { + return deptList; + } + + public void setDeptList(List deptList) { + this.deptList = deptList; + } + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + @Override + public String toString() { + return "SysUser{" + + "id=" + id + + ", userName='" + userName + '\'' + + ", age=" + age + + ", birthday=" + birthday + + ", roleList=" + roleList + + ", deptList=" + deptList + + '}' + super.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Inner.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Inner.java new file mode 100644 index 00000000..9fbb5b46 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Inner.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.entity; + +import com.mybatisflex.annotation.Table; + +/** + * @author 王帅 + * @since 2023-07-01 + */ +@Table("tb_inner") +public class Inner { + + private Integer id; + private String type; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @Override + public String toString() { + return "Inner{" + + "id=" + id + + ", type='" + type + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Outer.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Outer.java new file mode 100644 index 00000000..2cf4ab3c --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/Outer.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.entity; + +import com.mybatisflex.annotation.ColumnAlias; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.loveqq.test.model.IdEntity; + +/** + * @author 王帅 + * @since 2023-06-16 + */ +@Table("tb_outer") +public class Outer extends IdEntity { + + private String name; + private Inner inner; + + @Override + @ColumnAlias("outer_id") + public Integer getId() { + return super.getId(); + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Inner getInner() { + return inner; + } + + public void setInner(Inner inner) { + this.inner = inner; + } + + @Override + public String toString() { + return "Outer{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", inner=" + inner + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/TestEntity.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/TestEntity.java new file mode 100644 index 00000000..ab2824f3 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/entity/TestEntity.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.entity; + +import com.mybatisflex.annotation.Table; + +/** + * @author 王帅 + * @since 2023-06-16 + */ +@Table("test") +public class TestEntity { + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListener.java new file mode 100644 index 00000000..6ac30042 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListener.java @@ -0,0 +1,13 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +import com.mybatisflex.annotation.InsertListener; +import com.mybatisflex.loveqq.test.model.AccountMissingListenerTestModel; + +public class AccountAgeInsertListener implements InsertListener { + + @Override + public void onInsert(Object entity) { + AccountMissingListenerTestModel model = (AccountMissingListenerTestModel) entity; + model.setAge(18); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListenerFlag.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListenerFlag.java new file mode 100644 index 00000000..a03f05eb --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountAgeInsertListenerFlag.java @@ -0,0 +1,5 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +public interface AccountAgeInsertListenerFlag { + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountTableAnnoInsertListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountTableAnnoInsertListener.java new file mode 100644 index 00000000..fbbc136f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/AccountTableAnnoInsertListener.java @@ -0,0 +1,13 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +import com.mybatisflex.annotation.InsertListener; +import com.mybatisflex.loveqq.test.model.AccountMissingListenerTestModel; + +public class AccountTableAnnoInsertListener implements InsertListener { + + @Override + public void onInsert(Object entity) { + AccountMissingListenerTestModel model = (AccountMissingListenerTestModel) entity; + model.setUserName("测试缺失的监听器-userName"); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/BaseLogicDelete.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/BaseLogicDelete.java new file mode 100644 index 00000000..7c581bad --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/BaseLogicDelete.java @@ -0,0 +1,18 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +import com.mybatisflex.annotation.Column; + +public class BaseLogicDelete implements LogicDeleteInsertListenerFlag { + + @Column(isLogicDelete = true) + private Boolean isDelete; + + public Boolean getDelete() { + return isDelete; + } + + public void setDelete(Boolean delete) { + isDelete = delete; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListener.java new file mode 100644 index 00000000..edb00098 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListener.java @@ -0,0 +1,12 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +import com.mybatisflex.annotation.InsertListener; + +public class LogicDeleteInsertListener implements InsertListener { + + @Override + public void onInsert(Object entity) { + BaseLogicDelete logicDeleteEntity = (BaseLogicDelete) entity; + logicDeleteEntity.setDelete(false); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListenerFlag.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListenerFlag.java new file mode 100644 index 00000000..acd52c60 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/listener/missingListenerFix/LogicDeleteInsertListenerFlag.java @@ -0,0 +1,5 @@ +package com.mybatisflex.loveqq.test.listener.missingListenerFix; + +public interface LogicDeleteInsertListenerFlag { + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMapper.java new file mode 100644 index 00000000..6981033b --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMapper.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.Account; + +/** + * @author 王帅 + * @since 2023-06-23 + */ +public interface AccountMapper extends BaseMapper { + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMissingListenerTestModelMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMissingListenerTestModelMapper.java new file mode 100644 index 00000000..1499f773 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/AccountMissingListenerTestModelMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.AccountMissingListenerTestModel; + +/** + * @author noear 2024/12/24 created + */ +public interface AccountMissingListenerTestModelMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/ArticleMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/ArticleMapper.java new file mode 100644 index 00000000..795fd494 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/ArticleMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.Article; + +/** + * @author noear 2024/12/24 created + */ +public interface ArticleMapper extends BaseMapper

{ +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingInnerMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingInnerMapper.java new file mode 100644 index 00000000..f437f87e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingInnerMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.FieldMappingInner; + +/** + * @author noear 2024/12/24 created + */ +public interface FieldMappingInnerMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingMapper.java new file mode 100644 index 00000000..ac12666f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/FieldMappingMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.FieldMapping; + +/** + * @author noear 2024/12/24 created + */ +public interface FieldMappingMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/GoodMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/GoodMapper.java new file mode 100644 index 00000000..22403503 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/GoodMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.Good; + +/** + * @author noear 2024/12/24 created + */ +public interface GoodMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/InnerMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/InnerMapper.java new file mode 100644 index 00000000..3f477854 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/InnerMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.entity.Inner; + +/** + * @author noear 2024/12/24 created + */ +public interface InnerMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapper.java new file mode 100644 index 00000000..bef52c32 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapper.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.loveqq.test.model.Account; +import com.mybatisflex.loveqq.test.model.AccountDto; +import com.mybatisflex.loveqq.test.model.AccountView; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +import java.util.Map; + +public interface MyAccountMapper extends AccountMapper { + + + AccountDto selectByName(@Param("name") String name); + + AccountView selectViewObject(); + + @Select("select * from tb_account where id = #{id} and id =#{id}") + Account selectById(@Param("id") Object id); + + @Select("select * from tb_account where id = #{id}") + Map selectMapById(@Param("id") Object id); + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/OuterMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/OuterMapper.java new file mode 100644 index 00000000..ebc23c32 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/OuterMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.entity.Outer; + +/** + * @author noear 2024/12/24 created + */ +public interface OuterMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/PatientMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/PatientMapper.java new file mode 100644 index 00000000..dc2fd7e9 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/PatientMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.Patient; + +/** + * @author noear 2024/12/24 created + */ +public interface PatientMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/SysUserMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/SysUserMapper.java new file mode 100644 index 00000000..13acf7b4 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/SysUserMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.alias.SysUser; + +/** + * @author noear 2024/12/24 created + */ +public interface SysUserMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/TbClassMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/TbClassMapper.java new file mode 100644 index 00000000..809de86e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/TbClassMapper.java @@ -0,0 +1,7 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.TbClass; + +public interface TbClassMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapper.java new file mode 100644 index 00000000..8634189c --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.UnmappedUser; + +/** + * @author noear 2024/12/24 created + */ +public interface UnmappedUserMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UserMapper.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UserMapper.java new file mode 100644 index 00000000..95a71afd --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/mapper/UserMapper.java @@ -0,0 +1,10 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.loveqq.test.model.User; + +/** + * @author noear 2024/12/24 created + */ +public interface UserMapper extends BaseMapper { +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Account.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Account.java new file mode 100644 index 00000000..ccd2a571 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Account.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Table; + +import java.util.Date; + +/** + * 账户信息。 + */ +@Table(value = "tb_account", onSet = AccountOnSetListener.class) +public class Account extends BaseEntity { + + /*@Id(keyType = KeyType.Auto) + private Long id;*/ + //private String userName; + /** + * 年龄。 + */ + private Integer age; + + /** + * 生日。 + */ + private Date birthday; + + /** + * 逻辑删除。 + */ + @Column(isLogicDelete = true) + private Boolean isDelete; + + @Column(ignore = true) + private String anotherColumn; + +// private Gender gender; +// +// public Gender getGender() { +// return gender; +// } +// +// public void setGender(Gender gender) { +// this.gender = gender; +// } + + /*public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + }*/ + + /*public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + }*/ + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public Boolean getDelete() { + return isDelete; + } + + public void setDelete(Boolean delete) { + isDelete = delete; + } + + public String getAnotherColumn() { + return anotherColumn; + } + + public void setAnotherColumn(String anotherColumn) { + this.anotherColumn = anotherColumn; + } + + @Override + public String toString() { + return "Account{" + + "id=" + id + + ", userName='" + userName + '\'' + + ", age=" + age + + ", birthday=" + birthday + + ", isDelete=" + isDelete + + ", anotherColumn=" + anotherColumn + +// ", roles=" + roles + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountDto.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountDto.java new file mode 100644 index 00000000..8944c919 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountDto.java @@ -0,0 +1,37 @@ +package com.mybatisflex.loveqq.test.model; + +import java.util.List; +import java.util.Map; + +public class AccountDto { + + private Long id; + + private String name; + + private List> other; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List> getOther() { + return other; + } + + public void setOther(List> other) { + this.other = other; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountMissingListenerTestModel.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountMissingListenerTestModel.java new file mode 100644 index 00000000..398fea48 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountMissingListenerTestModel.java @@ -0,0 +1,89 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.AccountAgeInsertListenerFlag; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.AccountTableAnnoInsertListener; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.BaseLogicDelete; + +import java.util.Objects; + +/** + * 缺失的监听器测试 + * + * @author Ice 2023/10/23 + * @version 1.0 + */ +@Table(value = "tb_account", onInsert = AccountTableAnnoInsertListener.class) +public class AccountMissingListenerTestModel extends BaseLogicDelete implements AccountAgeInsertListenerFlag { + + /** + * 主键。 + */ + @Id(keyType = KeyType.Auto) + private Long id; + + private String userName; + + private Integer age; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + AccountMissingListenerTestModel that = (AccountMissingListenerTestModel) o; + return Objects.equals(id, that.id) && Objects.equals(userName, that.userName) && Objects.equals(age, that.age) && Objects.equals(getDelete(), that.getDelete()); + } + + @Override + public int hashCode() { + return Objects.hash(id, userName, age, getDelete()); + } + + @Override + public String toString() { + return "AccountMissingListenerTestModel{" + + "id=" + id + + ", userName='" + userName + '\'' + + ", age=" + age + + ", isDelete=" + getDelete() + + '}'; + } +} + + + + + + + + + + + + diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountOnSetListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountOnSetListener.java new file mode 100644 index 00000000..e2993dbc --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountOnSetListener.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.SetListener; + +public class AccountOnSetListener implements SetListener { + + @Override + public Object onSet(Object entity, String property, Object value) { + System.out.println(">>>>>>> property: " + property + " value:" + value); + return value; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO.java new file mode 100644 index 00000000..87c2e7f7 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.model; + +import java.util.Date; + +public class AccountVO extends IdEntity { + + private Integer age; + private Date birthday; + + private Gender gender; + private RoleVO2 role; + + public RoleVO2 getRole() { + return role; + } + + public void setRole(RoleVO2 role) { + this.role = role; + } + + public Gender getGender() { + return gender; + } + + public void setGender(Gender gender) { + this.gender = gender; + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + @Override + public String toString() { + return "Account{" + + "id=" + id + + ", age=" + age + + ", birthday=" + birthday + + ", roleName=" + role + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO2.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO2.java new file mode 100644 index 00000000..9b4e3f1f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountVO2.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.ColumnAlias; + +/** + * @author 王帅 + * @since 2023-06-30 + */ +public class AccountVO2 extends IdEntity { + + private Integer age; + + @ColumnAlias("account_name") + private String userName; + + + private User user; + + + @Override + @ColumnAlias("account_id") + public Long getId() { + return super.getId(); + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public User getUser() { + return user; + } + + public void setUser(User user) { + this.user = user; + } + + @Override + public String toString() { + return "AccountVO2{" + + "id=" + id + + ", age=" + age + + ", userName='" + userName + '\'' + + ", user='" + user + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountView.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountView.java new file mode 100644 index 00000000..f9dfdb33 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/AccountView.java @@ -0,0 +1,54 @@ +package com.mybatisflex.loveqq.test.model; + +import java.util.Date; +import java.util.List; + +/** + * 复杂查询接收类 + * 演示问题。 + * + * @author 王帅 + * @since 2024-10-03 + */ +@SuppressWarnings({"LombokGetterMayBeUsed", "LombokSetterMayBeUsed"}) +public class AccountView { + + private Long id; + private String userName; + private Date birthday; + + private List accountList; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Date getBirthday() { + return birthday; + } + + public void setBirthday(Date birthday) { + this.birthday = birthday; + } + + public List getAccountList() { + return accountList; + } + + public void setAccountList(List accountList) { + this.accountList = accountList; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Article.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Article.java new file mode 100644 index 00000000..45387da8 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Article.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Table; + +@Table(value = "tb_article") +public class Article extends IdEntity { + + private static final long serialVersionUID = 1L; + + + private Long accountId; + + private String title; + + private String content; + + @Column(isLogicDelete = true) + private Boolean isDelete; + + public Long getAccountId() { + return accountId; + } + + public void setAccountId(Long accountId) { + this.accountId = accountId; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + @Override + public String toString() { + return "Article{" + + "id=" + id + + ", accountId=" + accountId + + ", title='" + title + '\'' + + ", content='" + content + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/BaseEntity.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/BaseEntity.java new file mode 100644 index 00000000..d7ef41a1 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/BaseEntity.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Column; + +import java.util.List; + +/** + * @author 王帅 + * @since 2.0 + */ +public class BaseEntity extends IdEntity { + + /** + * 用户名。 + */ + protected T userName; + + /** + * 用户角色。 + */ + @Column(ignore = true) + protected List roles; + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + + public T getUserName() { + return userName; + } + + public void setUserName(T userName) { + this.userName = userName; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Disease.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Disease.java new file mode 100644 index 00000000..8882f4b4 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Disease.java @@ -0,0 +1,45 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; + +import java.io.Serializable; + +/** + * 疾病 + * + * @author Ice 2023/09/26 + * @version 1.0 + */ +@Table(value = "tb_disease") +public class Disease implements Serializable { + private static final long serialVersionUID = -3195530228167432902L; + + /** + * ID + */ + @Id(keyType = KeyType.Generator, value = "uuid") + private String diseaseId; + + /** + * 疾病名称 + */ + private String name; + + public String getDiseaseId() { + return diseaseId; + } + + public void setDiseaseId(String diseaseId) { + this.diseaseId = diseaseId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMapping.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMapping.java new file mode 100644 index 00000000..9a81414f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMapping.java @@ -0,0 +1,66 @@ +package com.mybatisflex.loveqq.test.model; + + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.activerecord.Model; +import com.mybatisflex.core.keygen.KeyGenerators; + +import java.util.Date; +import java.util.Objects; + + +@Table("field_mapping") +public class FieldMapping extends Model { + @Id(keyType = KeyType.Generator,value = KeyGenerators.snowFlakeId) + private String id; + @Column(ignore = true) + private Date innerDate; + + public String getId() { + return id; + } + + public static FieldMapping create() { + return new FieldMapping(); + } + + public FieldMapping setId(String id) { + this.id = id; + return this; + } + + public Date getInnerDate() { + return innerDate; + } + + public FieldMapping setInnerDate(Date innerDate) { + this.innerDate = innerDate; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FieldMapping that = (FieldMapping) o; + return Objects.equals(id, that.id) && Objects.equals(innerDate, that.innerDate); + } + + @Override + public int hashCode() { + return Objects.hash(id, innerDate); + } + + @Override + public String toString() { + return "FieldMapping{" + + "id='" + id + '\'' + + ", innerDate=" + innerDate + + '}'; + } + +} + diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMappingInner.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMappingInner.java new file mode 100644 index 00000000..395bec52 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/FieldMappingInner.java @@ -0,0 +1,71 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.activerecord.Model; +import com.mybatisflex.core.keygen.KeyGenerators; + +import java.util.Date; +import java.util.Objects; + +@Table("field_mapping_inner") +public class FieldMappingInner extends Model { + @Id(keyType = KeyType.Generator,value = KeyGenerators.snowFlakeId) + private String id; + private String outId; + private Date createDate; + + public static FieldMappingInner create() { + return new FieldMappingInner(); + } + + public String getId() { + return id; + } + + public FieldMappingInner setId(String id) { + this.id = id; + return this; + } + + public String getOutId() { + return outId; + } + + public FieldMappingInner setOutId(String outId) { + this.outId = outId; + return this; + } + + public Date getCreateDate() { + return createDate; + } + + public FieldMappingInner setCreateDate(Date createDate) { + this.createDate = createDate; + return this; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + FieldMappingInner that = (FieldMappingInner) o; + return Objects.equals(id, that.id) && Objects.equals(outId, that.outId) && Objects.equals(createDate, that.createDate); + } + + @Override + public int hashCode() { + return Objects.hash(id, outId, createDate); + } + + @Override + public String toString() { + return "FieldMappingInner{" + + "id='" + id + '\'' + + ", outId='" + outId + '\'' + + ", createDate=" + createDate + + '}'; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Gender.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Gender.java new file mode 100644 index 00000000..2a12bc67 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Gender.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.EnumValue; + +/** + * @author 王帅 + * @since 2023-06-14 + */ +public enum Gender { + + // MALE, FEMALE; + MALE(1), FEMALE(0); + + public int getCode() { + return code; + } + + @EnumValue + private final int code; + + Gender(int code) { + this.code = code; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Good.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Good.java new file mode 100644 index 00000000..c6315adf --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Good.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.activerecord.Model; + +import java.util.Objects; + +/** + * 商品。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table(value = "tb_good", onSet = GoodOnSetListener.class) +public class Good extends Model { + + @Id(keyType = KeyType.Auto) + private Integer goodId; + private String name; + private Double price; + + public static Good create() { + return new Good(); + } + + public Integer getGoodId() { + return goodId; + } + + public Good setGoodId(Integer goodId) { + this.goodId = goodId; + return this; + } + + public String getName() { + return name; + } + + public Good setName(String name) { + this.name = name; + return this; + } + + public Double getPrice() { + return price; + } + + public Good setPrice(Double price) { + this.price = price; + return this; + } + + @Override + public String toString() { + return "Good{" + + "goodId=" + goodId + + ", name='" + name + '\'' + + ", price=" + price + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Good good = (Good) o; + + if (!Objects.equals(goodId, good.goodId)) { + return false; + } + if (!Objects.equals(name, good.name)) { + return false; + } + return Objects.equals(price, good.price); + } + + @Override + public int hashCode() { + int result = goodId != null ? goodId.hashCode() : 0; + result = 31 * result + (name != null ? name.hashCode() : 0); + result = 31 * result + (price != null ? price.hashCode() : 0); + return result; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/GoodOnSetListener.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/GoodOnSetListener.java new file mode 100644 index 00000000..fea52c6e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/GoodOnSetListener.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.SetListener; + +/** + * @author 王帅 + * @since 2023-08-11 + */ +public class GoodOnSetListener implements SetListener { + + @Override + public Object onSet(Object entity, String property, Object value) { + System.out.println("Good: " + property + " --- " + value); + return value; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdCard.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdCard.java new file mode 100644 index 00000000..fb13a153 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdCard.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Table; + +/** + * @author 王帅 + * @since 2023-07-12 + */ +@Table("tb_id_card") +public class IdCard { + + private Integer id; + private String idNumber; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getIdNumber() { + return idNumber; + } + + public void setIdNumber(String idNumber) { + this.idNumber = idNumber; + } + + @Override + public String toString() { + return "IdCard{" + + "id=" + id + + ", IdNumber='" + idNumber + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdEntity.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdEntity.java new file mode 100644 index 00000000..f036ee20 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/IdEntity.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; + +import java.io.Serializable; + +/** + * @author 王帅 + * @since 2023-06-13 + */ +public class IdEntity implements Serializable { + + /** + * 主键。 + */ + @Id(keyType = KeyType.Auto) + protected T id; + + public T getId() { + return id; + } + + public void setId(T id) { + this.id = id; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Order.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Order.java new file mode 100644 index 00000000..55624be7 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Order.java @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.time.LocalDateTime; + +/** + * 订单。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table("tb_order") +public class Order { + + @Id + private int orderId; + private LocalDateTime createTime; + + public int getOrderId() { + return orderId; + } + + public void setOrderId(int orderId) { + this.orderId = orderId; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + @Override + public String toString() { + return "Order{" + + "orderId=" + orderId + + ", createTime=" + createTime + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderGood.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderGood.java new file mode 100644 index 00000000..edd92cc7 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderGood.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Table; + +/** + * 订单与商品连接表。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table("tb_order_good") +public class OrderGood { + + private Integer orderId; + private Integer goodId; + + public Integer getOrderId() { + return orderId; + } + + public void setOrderId(Integer orderId) { + this.orderId = orderId; + } + + public Integer getGoodId() { + return goodId; + } + + public void setGoodId(Integer goodId) { + this.goodId = goodId; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderInfo.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderInfo.java new file mode 100644 index 00000000..bfdcde3a --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/OrderInfo.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.RelationManyToMany; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.Objects; + +/** + * 订单信息。 + * + * @author 王帅 + * @since 2023-06-07 + */ +public class OrderInfo { + + private Integer orderId; + private LocalDateTime createTime; + + @RelationManyToMany( + selfField = "orderId", + targetField = "goodId", + joinTable = "tb_order_good", + joinSelfColumn = "order_id", + joinTargetColumn = "good_id" + ) + private List goodList; + + public Integer getOrderId() { + return orderId; + } + + public void setOrderId(Integer orderId) { + this.orderId = orderId; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public List getGoodList() { + return goodList; + } + + public void setGoodList(List goodList) { + this.goodList = goodList; + } + + @Override + public String toString() { + return "OrderInfo{" + + "orderId=" + orderId + + ", createTime=" + createTime + + ", goodList=" + goodList + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + OrderInfo orderInfo = (OrderInfo) o; + + if (!Objects.equals(orderId, orderInfo.orderId)) { + return false; + } + if (!Objects.equals(createTime, orderInfo.createTime)) { + return false; + } + return Objects.equals(goodList, orderInfo.goodList); + } + + @Override + public int hashCode() { + int result = orderId != null ? orderId.hashCode() : 0; + result = 31 * result + (createTime != null ? createTime.hashCode() : 0); + result = 31 * result + (goodList != null ? goodList.hashCode() : 0); + return result; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Patient.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Patient.java new file mode 100644 index 00000000..421e4ef6 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Patient.java @@ -0,0 +1,72 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.activerecord.Model; + +import java.io.Serializable; + +/** + * 患者信息 + * + * @author Ice 2023/09/26 + * @version 1.0 + */ +@Table(value = "tb_patient") +public class Patient extends Model implements Serializable { + private static final long serialVersionUID = 5117723684832788508L; + + + /** + * ID + */ + @Id + private Integer patientId; + + /** + * 姓名 + */ + private String name; + + /** + * 所患病症(对应字符串类型) 英文逗号 分割 + */ + private String diseaseIds; + + /** + * 患者标签(对应数字类型) / 分割 + */ + private String tagIds; + + public Integer getPatientId() { + return patientId; + } + + public void setPatientId(Integer patientId) { + this.patientId = patientId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDiseaseIds() { + return diseaseIds; + } + + public void setDiseaseIds(String diseaseIds) { + this.diseaseIds = diseaseIds; + } + + public String getTagIds() { + return tagIds; + } + + public void setTagIds(String tagIds) { + this.tagIds = tagIds; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/PatientVO1.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/PatientVO1.java new file mode 100644 index 00000000..86309225 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/PatientVO1.java @@ -0,0 +1,121 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.RelationOneToMany; +import com.mybatisflex.annotation.Table; + +import java.io.Serializable; +import java.util.List; +import java.util.Map; + +/** + * 患者VO + * + * @author Ice 2023/09/26 + * @version 1.0 + */ +@Table(value = "tb_patient") +public class PatientVO1 implements Serializable { + private static final long serialVersionUID = -2298625009592638988L; + + /** + * ID + */ + @Id + private Integer patientId; + + /** + * 姓名 + */ + private String name; + + /** + * 所患病症(对应字符串类型) 英文逗号 分割 + */ + private String diseaseIds; + + /** + * 患者标签(对应数字类型) / 分割 + */ + private String tagIds; + + @RelationOneToMany( + selfField = "diseaseIds", + selfValueSplitBy = ",", //使用 , 进行分割 + targetTable = "tb_disease", //只获取某个字段值需要填入目标表名 + targetField = "diseaseId", //测试目标字段是字符串类型是否正常转换 + valueField = "name" //测试只获取某个字段值是否正常 + ) + private List diseaseNameList; + + @RelationOneToMany( + selfField = "tagIds", + selfValueSplitBy = "/", //使用 / 进行分割 + targetField = "tagId" //测试目标字段是数字类型是否正常转换 + ) + private List tagList; + + @RelationOneToMany( + selfField = "diseaseIds", + selfValueSplitBy = ",", //使用 , 进行分割 + targetField = "diseaseId", //测试目标字段是字符串类型是否正常转换 + mapKeyField = "diseaseId" //测试Map映射 + ) + private Map diseaseMap; + + public Integer getPatientId() { + return patientId; + } + + public void setPatientId(Integer patientId) { + this.patientId = patientId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDiseaseIds() { + return diseaseIds; + } + + public void setDiseaseIds(String diseaseIds) { + this.diseaseIds = diseaseIds; + } + + public String getTagIds() { + return tagIds; + } + + public void setTagIds(String tagIds) { + this.tagIds = tagIds; + } + + public List getDiseaseNameList() { + return diseaseNameList; + } + + public void setDiseaseNameList(List diseaseNameList) { + this.diseaseNameList = diseaseNameList; + } + + public List getTagList() { + return tagList; + } + + public void setTagList(List tagList) { + this.tagList = tagList; + } + + public Map getDiseaseMap() { + return diseaseMap; + } + + public void setDiseaseMap(Map diseaseMap) { + this.diseaseMap = diseaseMap; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Role.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Role.java new file mode 100644 index 00000000..94199608 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Role.java @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Column; +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.util.List; +import java.util.Objects; + +/** + * 角色。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table("tb_role") +public class Role implements Comparable { + + @Id + private Integer roleId; + private String roleKey; + private String roleName; + + @Column(ignore = true) + private List userVOS; + + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + public String getRoleKey() { + return roleKey; + } + + public void setRoleKey(String roleKey) { + this.roleKey = roleKey; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public List getUserVOS() { + return userVOS; + } + + public void setUserVOS(List userVOS) { + this.userVOS = userVOS; + } + + @Override + public String toString() { + return "Role{" + + "roleId=" + roleId + + ", roleKey='" + roleKey + '\'' + + ", roleName='" + roleName + '\'' + + '}'; + } + + @Override + public int compareTo(Role o) { + return Integer.compare(this.roleId, o.roleId); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + + Role role = (Role) o; + + if (!Objects.equals(roleId, role.roleId)) { + return false; + } + if (!Objects.equals(roleKey, role.roleKey)) { + return false; + } + if (!Objects.equals(roleName, role.roleName)) { + return false; + } + return Objects.equals(userVOS, role.userVOS); + } + + @Override + public int hashCode() { + int result = roleId != null ? roleId.hashCode() : 0; + result = 31 * result + (roleKey != null ? roleKey.hashCode() : 0); + result = 31 * result + (roleName != null ? roleName.hashCode() : 0); + result = 31 * result + (userVOS != null ? userVOS.hashCode() : 0); + return result; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleKey.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleKey.java new file mode 100644 index 00000000..c898a278 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleKey.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * @author 王帅 + * @since 2023-06-15 + */ +public class RoleKey { + + private T roleKey; + + public T getRoleKey() { + return roleKey; + } + + public void setRoleKey(T roleKey) { + this.roleKey = roleKey; + } + + @Override + public String toString() { + return roleKey.toString(); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO1.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO1.java new file mode 100644 index 00000000..6e02805a --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO1.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * 角色。 + * + * @author 王帅 + * @since 2023-06-13 + */ +public class RoleVO1 { + + private Integer roleId; + private String roleKey; + private String roleName; + private UserVO1 user; + + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + public String getRoleKey() { + return roleKey; + } + + public void setRoleKey(String roleKey) { + this.roleKey = roleKey; + } + + public String getRoleName() { + return roleName; + } + + public void setRoleName(String roleName) { + this.roleName = roleName; + } + + public UserVO1 getUser() { + return user; + } + + public void setUser(UserVO1 user) { + this.user = user; + } + + @Override + public String toString() { + return "Role{" + + "roleId=" + roleId + + ", roleKey='" + roleKey + '\'' + + ", roleName='" + roleName + '\'' + + ", userVO1='" + user + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO2.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO2.java new file mode 100644 index 00000000..b4d12c37 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO2.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * @author 王帅 + * @since 2023-06-15 + */ +public class RoleVO2 { + + private T roleName; + private RoleKey roleKey; + + public T getRoleName() { + return roleName; + } + + public void setRoleName(T roleName) { + this.roleName = roleName; + } + + public RoleKey getRoleKey() { + return roleKey; + } + + public void setRoleKey(RoleKey roleKey) { + this.roleKey = roleKey; + } + + @Override + public String toString() { + return "RoleName{" + + "roleName=" + roleName + + ", roleKey=" + roleKey + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO3.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO3.java new file mode 100644 index 00000000..3a1f67f0 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/RoleVO3.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * @author 王帅 + * @since 2023-06-15 + */ +public class RoleVO3 { + + private Integer roleId; + private String roleKey; + private String userName; + + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + + public String getRoleKey() { + return roleKey; + } + + public void setRoleKey(String roleKey) { + this.roleKey = roleKey; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + return "RoleVO3{" + + "roleId=" + roleId + + ", roleKey='" + roleKey + '\'' + + ", roleName='" + userName + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Tag.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Tag.java new file mode 100644 index 00000000..ba16d2cc --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/Tag.java @@ -0,0 +1,44 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +import java.io.Serializable; + +/** + * 标签 + * + * @author Ice 2023/09/26 + * @version 1.0 + */ +@Table(value = "tb_tag") +public class Tag implements Serializable { + private static final long serialVersionUID = 5600670055904157386L; + + /** + * ID + */ + @Id + private Integer tagId; + + /** + * 标签名称 + */ + private String name; + + public Integer getTagId() { + return tagId; + } + + public void setTagId(Integer tagId) { + this.tagId = tagId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/TbClass.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/TbClass.java new file mode 100644 index 00000000..23c850ad --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/TbClass.java @@ -0,0 +1,47 @@ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.Table; + +@Table(value = "tb_class") +public class TbClass { + @Id + private Long id; + + private Long user_id; + + private String className; + + public Long getId() { + return id; + } + + public Long getUser_id() { + return user_id; + } + + public String getClassName() { + return className; + } + + public void setId(Long id) { + this.id = id; + } + + public void setUser_id(Long user_id) { + this.user_id = user_id; + } + + public void setClassName(String className) { + this.className = className; + } + + @Override + public String toString() { + return "TbClass{" + + "id=" + id + + ", user_id=" + user_id + + ", className='" + className + '\'' + + '}'; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedBaseEntity.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedBaseEntity.java new file mode 100644 index 00000000..5608f80f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedBaseEntity.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.model; + +import lombok.Getter; +import lombok.Setter; + +import java.util.Map; + +/** + * UnMappedBaseEntity + * + * @author wy + * @version 1.0 + * @date 2024/9/12 11:36 + **/ +@Getter +@Setter +public class UnmappedBaseEntity { + + protected Map unmappedMap; +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedUser.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedUser.java new file mode 100644 index 00000000..89b8b2f6 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UnmappedUser.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.KeyType; +import com.mybatisflex.annotation.Table; +import lombok.Getter; +import lombok.Setter; +import org.springframework.util.CollectionUtils; + +/** + * UnMapped + * + * @author wy + * @version 1.0 + * @date 2024/9/12 11:28 + **/ +@Getter +@Setter +@Table("tb_unmapped_user") +public class UnmappedUser extends UnmappedBaseEntity { + + @Id(keyType = KeyType.Auto) + private Long id; + + private Integer age; + + private String name; + + @Override + public String toString() { + return "UnmappedUser{" + + "id='" + id + '\'' + + ", name='" + name + '\'' + + ", age=" + age + + (CollectionUtils.isEmpty(unmappedMap) ? "" : ", unmappedMap=" + unmappedMap.toString()) + + '}'; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/User.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/User.java new file mode 100644 index 00000000..3e3ef1f8 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/User.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; +import com.mybatisflex.annotation.RelationManyToMany; +import com.mybatisflex.annotation.Table; +import com.mybatisflex.core.activerecord.Model; + +import java.util.List; + +/** + * 用户。 + * + * @author 王帅 + * @since 2023-06-07 + */ + +@Table("tb_user") +public class User extends Model { + + @Id + private Integer userId; + private String userName; + private String password; + + @RelationManyToMany( + selfField = "userId", + targetField = "roleId", + joinTable = "tb_user_role", + joinSelfColumn = "user_id", + joinTargetColumn = "role_id" + ) + private List roleList; + + public static User create() { + return new User(); + } + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + @Override + public String toString() { + return "User{" + + "userId=" + userId + + ", userName='" + userName + '\'' + + ", password='" + password + '\'' + + ", roleList=" + roleList + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserInfo.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserInfo.java new file mode 100644 index 00000000..b8e9d321 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserInfo.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.RelationManyToMany; + +import java.util.List; + +/** + * 用户信息。 + * + * @author 王帅 + * @since 2023-06-07 + */ +public class UserInfo { + + private Integer userId; + private String userName; + private String password; + private String idNumber; + + @RelationManyToMany( + selfField = "userId", + targetField = "roleId", + joinTable = "tb_user_role", + joinSelfColumn = "user_id", + joinTargetColumn = "role_id" + ) + private List roleList; + + @RelationManyToMany( + selfField = "userId", + targetField = "orderId", + targetTable = "tb_order", + joinTable = "tb_user_order", + joinSelfColumn = "user_id", + joinTargetColumn = "order_id" + ) + private List orderInfoList; + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public String getIdNumber() { + return idNumber; + } + + public void setIdNumber(String idNumber) { + this.idNumber = idNumber; + } + + public List getRoleList() { + return roleList; + } + + public void setRoleList(List roleList) { + this.roleList = roleList; + } + + public List getOrderInfoList() { + return orderInfoList; + } + + public void setOrderInfoList(List orderInfoList) { + this.orderInfoList = orderInfoList; + } + + @Override + public String toString() { + return "UserInfo{" + + "userId=" + userId + + ", userName='" + userName + '\'' + + ", password='" + password + '\'' + + ", idNumber='" + idNumber + '\'' + + ", roleList=" + roleList + + ", orderInfoList=" + orderInfoList + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserOrder.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserOrder.java new file mode 100644 index 00000000..f570898b --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserOrder.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Table; + +/** + * 用户订单映射。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table("tb_user_order") +public class UserOrder { + + private Integer userId; + private Integer orderId; + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Integer getOrderId() { + return orderId; + } + + public void setOrderId(Integer orderId) { + this.orderId = orderId; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserRole.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserRole.java new file mode 100644 index 00000000..5f2b0e78 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserRole.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Table; + +/** + * 用户与角色连接表。 + * + * @author 王帅 + * @since 2023-06-07 + */ +@Table("tb_user_role") +public class UserRole { + + private Integer userId; + private Integer roleId; + + public Integer getUserId() { + return userId; + } + + public void setUserId(Integer userId) { + this.userId = userId; + } + + public Integer getRoleId() { + return roleId; + } + + public void setRoleId(Integer roleId) { + this.roleId = roleId; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO.java new file mode 100644 index 00000000..61106bab --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import java.util.HashMap; +import java.util.Map; + +/** + * 用户 VO 对象。 + * + * @author 王帅 + * @since 2023-06-07 + */ + +public class UserVO { + + private String userId; + private String userName; + // private TreeSet roleList; +// private Role[] roleList; + private HashMap roleList; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public Map getRoleList() { + return roleList; + } + + public void setRoleList(HashMap roleList) { + this.roleList = roleList; + } + + @Override + public String toString() { + return "UserVO{" + + "userId='" + userId + '\'' + + ", userName='" + userName + '\'' + + ", roleList=" + roleList + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO1.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO1.java new file mode 100644 index 00000000..a571acc3 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO1.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * @author 王帅 + * @since 2023-06-07 + */ +public class UserVO1 { + + private String userId; + private String userName; + private RoleVO1 role; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public RoleVO1 getRole() { + return role; + } + + public void setRole(RoleVO1 role) { + this.role = role; + } + + @Override + public String toString() { + return "UserVO1{" + + "userId='" + userId + '\'' + + ", userName='" + userName + '\'' + + ", roleVO1=" + role + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO2.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO2.java new file mode 100644 index 00000000..db46c857 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO2.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import java.util.List; + +/** + * @author 王帅 + * @since 2023-06-07 + */ + +public class UserVO2 { + + private String userId; + private String userName; + private List roles; + private List roleIds; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getRoles() { + return roles; + } + + public void setRoles(List roles) { + this.roles = roles; + } + + public List getRoleIds() { + return roleIds; + } + + public void setRoleIds(List roleIds) { + this.roleIds = roleIds; + } + + @Override + public String toString() { + return "UserVO2{" + + "userId='" + userId + '\'' + + ", userName='" + userName + '\'' + + ", roles=" + roles + + ", roleIds=" + roleIds + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO3.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO3.java new file mode 100644 index 00000000..fc076fd4 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO3.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +import com.mybatisflex.annotation.Id; + +import java.util.List; + +/** + * @author 王帅 + * @since 2023-06-07 + */ + +public class UserVO3 { + + @Id + private String userId; + private String userName; + private List roleVO3; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public List getRoleVO3() { + return roleVO3; + } + + public void setRoleVO3(List roleVO3) { + this.roleVO3 = roleVO3; + } + + @Override + public String toString() { + return "UserVO3{" + + "userId='" + userId + '\'' + + ", userName='" + userName + '\'' + + ", roleVO3=" + roleVO3 + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO4.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO4.java new file mode 100644 index 00000000..d365cbc0 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO4.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.model; + +/** + * 用户 VO 对象。 + * + * @author 王帅 + * @since 2023-06-30 + */ + +public class UserVO4 { + + private String userId; + + private String userName; + + public String getUserId() { + return userId; + } + + public void setUserId(String userId) { + this.userId = userId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + @Override + public String toString() { + return "UserVO{" + + "userId='" + userId + '\'' + + ", userName='" + userName + '\'' + + '}'; + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO5.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO5.java new file mode 100644 index 00000000..d9ebada9 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/model/UserVO5.java @@ -0,0 +1,108 @@ +package com.mybatisflex.loveqq.test.model;//package com.mybatisflex.test.model; +// +//import com.mybatisflex.annotation.*; +// +//import java.io.Serializable; +//import java.util.List; +// +///** +// * 字段绑定测试 +// * @author Ice 2023/09/16 +// * @version 1.0 +// */ +//@Table("tb_user") +//public class UserVO5 implements Serializable { +// private static final long serialVersionUID = 474700189859144273L; +// +// @Id +// private Integer userId; +// private String userName; +// private String password; +// +// @RelationOneToOne( +// selfField = "userId", +// targetTable = "tb_id_card", +// targetField = "id", +// valueField = "idNumber" +// ) +// private String idNumberCustomFieldName; +// +// @RelationOneToMany( +// selfField = "userId", +// targetTable = "tb_user_order", +// targetField = "userId", +// valueField = "orderId" +// ) +// private List orderIdList; +// +// @RelationManyToMany( +// selfField = "userId", +// targetTable = "tb_role", +// targetField = "roleId", +// valueField = "roleName", +// joinTable = "tb_user_role", +// joinSelfColumn = "user_id", +// joinTargetColumn = "role_id" +// ) +// private List roleNameList; +// +// public Integer getUserId() { +// return userId; +// } +// +// public void setUserId(Integer userId) { +// this.userId = userId; +// } +// +// public String getUserName() { +// return userName; +// } +// +// public void setUserName(String userName) { +// this.userName = userName; +// } +// +// public String getPassword() { +// return password; +// } +// +// public void setPassword(String password) { +// this.password = password; +// } +// +// public String getIdNumberCustomFieldName() { +// return idNumberCustomFieldName; +// } +// +// public void setIdNumberCustomFieldName(String idNumberCustomFieldName) { +// this.idNumberCustomFieldName = idNumberCustomFieldName; +// } +// +// public List getOrderIdList() { +// return orderIdList; +// } +// +// public void setOrderIdList(List orderIdList) { +// this.orderIdList = orderIdList; +// } +// +// public List getRoleNameList() { +// return roleNameList; +// } +// +// public void setRoleNameList(List roleNameList) { +// this.roleNameList = roleNameList; +// } +// +// @Override +// public String toString() { +// return "UserVO5{" + +// "userId=" + userId + +// ", userName='" + userName + '\'' + +// ", password='" + password + '\'' + +// ", idNumberCustomFieldName='" + idNumberCustomFieldName + '\'' + +// ", orderIdList=" + orderIdList + +// ", roleNameList=" + roleNameList + +// '}'; +// } +//} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/AccountService.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/AccountService.java new file mode 100644 index 00000000..17c2d4db --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/AccountService.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.service; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Service; +import com.mybatisflex.loveqq.test.mapper.AccountMapper; +import com.mybatisflex.loveqq.test.model.Account; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.util.concurrent.TimeUnit; + +@Service +public class AccountService { + + + @Resource + AccountMapper accountMapper; + + + @Transactional + public void update2() { + int x = 1 / 0; + Account account = new Account(); + account.setId(2L); + account.setUserName("haha"); + accountMapper.update(account); + } + + @Transactional(rollbackFor = Exception.class, timeout = 3) + public void transactionTimeTest() throws InterruptedException { + Account account = new Account(); + account.setId(100L); + account.setUserName("aliothmoon"); + accountMapper.insert(account); + TimeUnit.SECONDS.sleep(5); + accountMapper.selectOneById(account.getId()); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/ArticleService.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/ArticleService.java new file mode 100644 index 00000000..8c32d7fb --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/ArticleService.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.service; + +import com.mybatisflex.core.service.IService; +import com.mybatisflex.loveqq.test.model.Article; + +/** + * @author 王帅 + * @since 2023-07-22 + */ +public interface ArticleService extends IService

{ + + void changeDataSource(); + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/impl/ArticleServiceImpl.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/impl/ArticleServiceImpl.java new file mode 100644 index 00000000..6126c8ec --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/service/impl/ArticleServiceImpl.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.service.impl; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Service; +import com.mybatisflex.annotation.UseDataSource; +import com.mybatisflex.core.datasource.DataSourceKey; +import com.mybatisflex.loveqq.framework.boot.autoconfig.service.ServiceImpl; +import com.mybatisflex.loveqq.test.mapper.ArticleMapper; +import com.mybatisflex.loveqq.test.model.Article; +import com.mybatisflex.loveqq.test.service.ArticleService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * @author 王帅 + * @since 2023-07-22 + */ +@Service +public class ArticleServiceImpl extends ServiceImpl implements ArticleService { + + private static final Logger LOGGER = LoggerFactory.getLogger(ArticleServiceImpl.class); + + @Override + @UseDataSource("annotation ds") + public void changeDataSource() { + LOGGER.info("start1: {}", DataSourceKey.get()); + DataSourceKey.use("ds outer", () -> { + LOGGER.info("start2: {}", DataSourceKey.get()); + DataSourceKey.use("ds inner", () -> { + LOGGER.info("start3: {}", DataSourceKey.get()); + LOGGER.info("end3: {}", DataSourceKey.get()); + }); + LOGGER.info("end2: {}", DataSourceKey.get()); + }); + LOGGER.info("end1: {}", DataSourceKey.get()); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/unmapped/MyUnMappedColumnHandler.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/unmapped/MyUnMappedColumnHandler.java new file mode 100644 index 00000000..a523ba74 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/java/com/mybatisflex/loveqq/test/unmapped/MyUnMappedColumnHandler.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.unmapped; + +import com.mybatisflex.core.mybatis.UnMappedColumnHandler; +import com.mybatisflex.loveqq.test.model.UnmappedBaseEntity; +import org.apache.ibatis.reflection.MetaObject; + +import java.util.HashMap; +import java.util.Map; + +/** + * MyUnMappedColumnHandler + * + * @author wy + * @version 1.0 + * @date 2024/9/12 11:34 + **/ +public class MyUnMappedColumnHandler implements UnMappedColumnHandler { + @Override + public void handleUnMappedColumn(MetaObject metaObject, String unmappedColumnName, Object value) { + if (metaObject.getOriginalObject() instanceof UnmappedBaseEntity){ + Object object = metaObject.getValue("unmappedMap"); + if(object == null){ + Map map = new HashMap<>(); + map.put(unmappedColumnName, value); + metaObject.setValue("unmappedMap", map); + }else { + ((Map)object).put(unmappedColumnName, value); + } + } + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/application.yml b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/application.yml new file mode 100644 index 00000000..053a5f9d --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/application.yml @@ -0,0 +1,48 @@ +# DataSource Config +#spring: +# # h2: +# # console: +# # enabled: true +# datasource: +# driver-class-name: com.mysql.cj.jdbc.Driver +# url: jdbc:mysql://localhost:3306/flex_test +# username: root +# password: 12345678 + # driver-class-name: + # datasource: + # driver-class-name: org.h2.Driver + # username: root + # password: test +# sql: +# init: +# schema-locations: classpath:schema.sql +# data-locations: classpath:data.sql +#mybatis-flex: +# admin-config: +# enable: true +# endpoint: http://localhost/admin +# secret-key: secretKey +# mapper-locations: +# - classpath*:/mapper/*.xml +# global-config: +# print-banner: false +# key-config: +# key-type: generator +# value: uuid +# configuration: +# use-generated-keys: true +# datasource: +# data-center: +# url: jdbc:mysql://localhost:3306/flex_test +# username: root +# password: 12345678 +mybatis-flex: + datasource: + ds1: + url: jdbc:mysql://localhost:3306/flex_test + username: root + password: 12345678 + ds2: + url: jdbc:mysql://localhost:3306/flex_test + username: root + password: 12345678 diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/mapper/accountMapper.xml b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/mapper/accountMapper.xml new file mode 100644 index 00000000..66546a11 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/main/resources/mapper/accountMapper.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/LoveqqExtension.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/LoveqqExtension.java new file mode 100644 index 00000000..ba1ed3b3 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/LoveqqExtension.java @@ -0,0 +1,28 @@ +package com.mybatisflex.loveqq.test; + +import com.kfyty.loveqq.framework.boot.K; +import com.kfyty.loveqq.framework.core.autoconfig.ApplicationContext; +import com.kfyty.loveqq.framework.core.autoconfig.beans.AutowiredCapableSupport; +import com.kfyty.loveqq.framework.core.utils.BeanUtil; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.BeforeEachCallback; +import org.junit.jupiter.api.extension.ExtensionContext; + +public class LoveqqExtension implements BeforeAllCallback, BeforeEachCallback { + private static ApplicationContext context; + private static AutowiredCapableSupport autowiredCapable; + + @Override + public void beforeAll(ExtensionContext extensionContext) throws Exception { + if (context == null) { + context = K.start(SampleApplication.class); + autowiredCapable = context.getBean(AutowiredCapableSupport.BEAN_NAME); + } + } + + @Override + public void beforeEach(ExtensionContext extensionContext) throws Exception { + Object instance = extensionContext.getRequiredTestInstance(); + autowiredCapable.autowiredBean(BeanUtil.getBeanName(instance.getClass()), instance); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/CloneTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/CloneTest.java new file mode 100644 index 00000000..876b74ca --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/CloneTest.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONWriter; +import com.mybatisflex.core.query.CPI; +import com.mybatisflex.core.query.QueryWrapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.function.Supplier; + +import static com.mybatisflex.core.query.QueryMethods.count; +import static com.mybatisflex.core.query.QueryMethods.distinct; +import static com.mybatisflex.loveqq.test.model.table.AccountTableDef.ACCOUNT; +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-06-09 + */ +class CloneTest { + + @Test + void test03() { + String jsonString = JSON.toJSONString(newQueryWrapper(), JSONWriter.Feature.FieldBased, JSONWriter.Feature.ReferenceDetection); + System.out.println(jsonString); + } + + @Test + void test() { + QueryWrapper queryWrapper = newQueryWrapper(); + Class queryWrapperClass = QueryWrapper.class; + int count = 10000; + + /* + * new: 41ms + * clone: 65ms + * fastjson: 620ms + * serial: 2003ms + */ + calcTime(count, "new", this::newQueryWrapper); + calcTime(count, "clone", queryWrapper::clone); + calcTime(count, "fastjson", () -> SerialUtil.cloneObject(queryWrapper, queryWrapperClass)); + calcTime(count, "serial", () -> SerialUtil.cloneObject(queryWrapper)); + } + + @Test + void test02() { + QueryWrapper queryWrapper = newQueryWrapper(); + QueryWrapper queryWrapper1 = queryWrapper.clone(); + QueryWrapper queryWrapper2 = SerialUtil.cloneObject(queryWrapper); +// QueryWrapper queryWrapper3 = SerialUtil.cloneObject(queryWrapper, QueryWrapper.class); + System.err.println(SerialUtil.toJSONString(queryWrapper)); + System.out.println(queryWrapper.toSQL()); + System.out.println(queryWrapper1.toSQL()); + System.out.println(queryWrapper2.toSQL()); +// System.out.println(queryWrapper3.toSQL()); + + Assertions.assertEquals(queryWrapper.toSQL(), queryWrapper1.toSQL()); + Assertions.assertEquals(queryWrapper.toSQL(), queryWrapper2.toSQL()); +// Assertions.assertEquals(queryWrapper.toSQL(), queryWrapper3.toSQL()); + } + + private void calcTime(int count, String type, Supplier supplier) { + long start = System.currentTimeMillis(); + for (int i = 0; i < count; i++) { + supplier.get(); + } + long end = System.currentTimeMillis(); + System.out.println(type + ": " + (end - start) + "ms"); + } + + private QueryWrapper newQueryWrapper() { + return QueryWrapper.create() + .select(count(distinct(USER.USER_ID))/*case_() + .when(USER.USER_ID.eq(3)).then("x3") + .when(USER.USER_ID.eq(5)).then("x4") + .end(), + distinct(USER.USER_ID.add(4)), + USER.USER_NAME, + ROLE.ALL_COLUMNS*/) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)) + .and(ROLE.ROLE_NAME.in(Arrays.asList(1, 2, 3))) + .or(ROLE.ROLE_ID.ge(USER.USER_ID)) + .groupBy(ROLE.ROLE_NAME) + .having(ROLE.ROLE_ID.ge(7)) + .orderBy(ROLE.ROLE_NAME.asc()); + } + + @Test + void test04() { + QueryWrapper queryWrapper = QueryWrapper.create() + .from(ACCOUNT) + .select(ACCOUNT.DEFAULT_COLUMNS) + .where(ACCOUNT.ID.eq(1)); + + QueryWrapper clone = queryWrapper.clone(); + + CPI.setSelectColumns(clone, null); + + clone.select(ACCOUNT.ID, ACCOUNT.USER_NAME); + + String sql1 = queryWrapper.toSQL(); + String sql2 = clone.toSQL(); + + System.out.println(sql1); + System.out.println(sql2); + + Assertions.assertNotEquals(sql1, sql2); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/FieldTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/FieldTest.java new file mode 100644 index 00000000..83d2ffdc --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/FieldTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.mybatisflex.loveqq.test.model.Account; +import com.mybatisflex.loveqq.test.model.BaseEntity; +import com.mybatisflex.loveqq.test.model.UserVO; +import org.apache.ibatis.reflection.Reflector; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Method; +import java.util.Arrays; + +/** + * @author 王帅 + * @since 2023-06-13 + */ +class FieldTest { + + @Test + void test() { + String genericString = BaseEntity.class.toGenericString(); + System.out.println(genericString); + } + + @Test + void test02() { + Class accountClass = Account.class; + Method[] declaredMethods = accountClass.getMethods(); + Arrays.stream(declaredMethods) + .filter(e -> e.getName().startsWith("get")) + .forEach(System.out::println); + } + + @Test + void test03() { + Reflector reflector = new Reflector(Account.class); + Class id = reflector.getGetterType("id"); + Class userName = reflector.getGetterType("userName"); + Class age = reflector.getGetterType("age"); + System.out.println(id); + System.out.println(userName); + System.out.println(age); + } + + @Test + void test04() { + Reflector reflector = new Reflector(UserVO.class); + Class roleList = reflector.getGetterType("roleList"); + System.out.println(roleList); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ListenerTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ListenerTest.java new file mode 100644 index 00000000..4e8cf70e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ListenerTest.java @@ -0,0 +1,89 @@ +package com.mybatisflex.loveqq.test.common; + +import com.mybatisflex.annotation.InsertListener; +import com.mybatisflex.core.BaseMapper; +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.mybatis.Mappers; +import com.mybatisflex.core.table.TableInfo; +import com.mybatisflex.core.table.TableInfoFactory; +import com.mybatisflex.core.util.CollectionUtil; +import com.mybatisflex.core.util.MapUtil; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.AccountAgeInsertListener; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.AccountAgeInsertListenerFlag; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.AccountTableAnnoInsertListener; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.LogicDeleteInsertListener; +import com.mybatisflex.loveqq.test.listener.missingListenerFix.LogicDeleteInsertListenerFlag; +import com.mybatisflex.loveqq.test.model.AccountMissingListenerTestModel; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.stream.Collectors; + +/** + * 监听器测试 + * + * @author Ice 2023/10/23 + * @version 1.0 + */ +class ListenerTest { + + @Test + void missingListenerTest() { + + AccountMissingListenerTestModel accountMissingListenerTestModel = new AccountMissingListenerTestModel(); + + //加入配置 + FlexGlobalConfig config = FlexGlobalConfig.getDefaultConfig(); + config.registerInsertListener(new LogicDeleteInsertListener(), LogicDeleteInsertListenerFlag.class); + config.registerInsertListener(new AccountAgeInsertListener(), AccountAgeInsertListenerFlag.class); + + //获取TableInfo + TableInfo tableInfo = TableInfoFactory.ofEntityClass(AccountMissingListenerTestModel.class); + + //执行测试 ===> Listener列表比对 + Map, List> tempOnInsertListenerMap = new ConcurrentHashMap<>();//替代原本的缓存Map + + List insertListeners = MapUtil.computeIfAbsent(tempOnInsertListenerMap, AccountMissingListenerTestModel.class, aClass -> { + List globalListeners = FlexGlobalConfig.getDefaultConfig() + .getSupportedInsertListener(AccountMissingListenerTestModel.class); + List allListeners = CollectionUtil.merge(tableInfo.getOnInsertListeners(), globalListeners); + Collections.sort(allListeners); + return allListeners; + }); + + List> resolvedInsertListeners = insertListeners.stream().map(InsertListener::getClass).collect(Collectors.toList()); + List> expectedInsertListeners = CollectionUtil.newArrayList(LogicDeleteInsertListener.class, AccountAgeInsertListener.class, AccountTableAnnoInsertListener.class); + + Assertions.assertTrue( + () -> { + for (Class clazz : expectedInsertListeners) { + if (!resolvedInsertListeners.contains(clazz)) { + return false; + } + } + return true; + }, + String.format("InsertListener与预期结果不一致\n预期Listener列表:%s\n实际Listener列表:%s", expectedInsertListeners, resolvedInsertListeners) + ); + + //执行测试 ===> 插入结果比对 + BaseMapper baseMapper = Mappers.ofEntityClass(accountMissingListenerTestModel.getClass()); + baseMapper.insert(accountMissingListenerTestModel); + + //实际执行结果 + AccountMissingListenerTestModel dbData = (AccountMissingListenerTestModel) baseMapper.selectOneById(accountMissingListenerTestModel.getId()); + + //预期数据 + AccountMissingListenerTestModel expectedData = new AccountMissingListenerTestModel(); + expectedData.setId(dbData.getId()); + expectedData.setUserName("测试缺失的监听器-userName"); + expectedData.setAge(18); + expectedData.setDelete(false); + + Assertions.assertEquals(expectedData, dbData); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/MapperUtilTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/MapperUtilTest.java new file mode 100644 index 00000000..bf5afb53 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/MapperUtilTest.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.util.MapperUtil; +import org.junit.jupiter.api.Test; + +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-06-09 + */ +class MapperUtilTest { + + @Test + void testOptimizeCountQueryWrapper() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME, ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)) + .and(USER_ROLE.ROLE_ID.eq(6)) + .groupBy(ROLE.ROLE_ID); + System.out.println(queryWrapper.toSQL()); + System.out.println(MapperUtil.rawCountQueryWrapper(queryWrapper).toSQL()); + System.out.println(MapperUtil.optimizeCountQueryWrapper(queryWrapper).toSQL()); + } + + /** + * 测试 (sql1) union (sql2) + */ + @Test + void testOptimizeCountQueryWrapperOfUnion1() { + //简单union + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1 order by user_id desc + QueryWrapper union1 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_ID.eq(1)).orderBy(USER.USER_ID.desc()); + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%' + QueryWrapper union2 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_NAME.like("test")); + + QueryWrapper query1 = union1.union(union2); + + String sql = MapperUtil.optimizeCountQueryWrapper(query1).toSQL(); + //SELECT COUNT(*) AS `total` FROM ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1) UNION (SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%')) AS `t` + System.out.println(sql); + } + + /** + * 测试 (sql1 ) union (sql2 with group by) + */ + @Test + void testOptimizeCountQueryWrapperOfUnion2() { + //with group by union + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1 order by user_id desc + QueryWrapper union1 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_ID.eq(1)).orderBy(USER.USER_ID.desc()); + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%' group by user_id, user_name + QueryWrapper union2 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_NAME.like("test")).groupBy(USER.USER_ID, USER.USER_NAME); + + QueryWrapper query1 = union1.union(union2); + + //SELECT COUNT(*) AS `total` FROM ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1) UNION (SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%' GROUP BY `user_id`, `user_name`)) AS `t` + String sql = MapperUtil.optimizeCountQueryWrapper(query1).toSQL(); + System.out.println(sql); + } + + /** + * 测试 (sql1) union (sql2 union sql3) + */ + @Test + void testOptimizeCountQueryWrapperOfUnion3() { + //with sub query union + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1 order by user_id desc + QueryWrapper union1 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_ID.eq(1)).orderBy(USER.USER_ID.desc()); + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%' group by user_id, user_name + QueryWrapper union2 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_NAME.like("test")).orderBy(USER.USER_NAME.desc()); + + QueryWrapper union3 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.PASSWORD.isNull()).orderBy(USER.USER_NAME.desc()); + + + QueryWrapper query1 = union1.union(union2.union(union3)); + + //SELECT COUNT(*) AS `total` FROM ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1) UNION ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%') UNION (SELECT `user_id`, `user_name` FROM `tb_user` WHERE `password` IS NULL ))) AS `t` + String sql = MapperUtil.optimizeCountQueryWrapper(query1).toSQL(); + + System.out.println(sql); + } + + @Test + void testOptimizeCountQueryWrapperOfUnion4() { + //with sub query union + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1 order by user_id desc + QueryWrapper union1 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_ID.eq(1)).orderBy(USER.USER_ID.desc()); + //SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%' group by user_id, user_name + QueryWrapper union2 = QueryWrapper.create().select(USER.USER_ID, USER.USER_NAME).from(USER).where(USER.USER_NAME.like("test")).orderBy(USER.USER_NAME.desc()); + + QueryWrapper union3 = QueryWrapper.create().from(union2).as("a"); + + + QueryWrapper query1 = union1.union(union3); + + //SELECT COUNT(*) AS `total` FROM ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_id` = 1) UNION ((SELECT `user_id`, `user_name` FROM `tb_user` WHERE `user_name` LIKE '%test%') UNION (SELECT `user_id`, `user_name` FROM `tb_user` WHERE `password` IS NULL ))) AS `t` + String sql = MapperUtil.optimizeCountQueryWrapper(query1).toSQL(); + + System.out.println(sql); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/QueryWrapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/QueryWrapperTest.java new file mode 100644 index 00000000..effecd5e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/QueryWrapperTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.github.vertical_blank.sqlformatter.SqlFormatter; +import com.mybatisflex.core.query.CPI; +import com.mybatisflex.core.query.QueryColumnBehavior; +import com.mybatisflex.core.query.QueryCondition; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.query.RawQueryTable; +import com.mybatisflex.loveqq.test.model.table.RoleTableDef; +import com.mybatisflex.loveqq.test.model.table.UserTableDef; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import static com.mybatisflex.core.query.QueryMethods.case_; +import static com.mybatisflex.core.query.QueryMethods.column; +import static com.mybatisflex.core.query.QueryMethods.count; +import static com.mybatisflex.core.query.QueryMethods.distinct; +import static com.mybatisflex.core.query.QueryMethods.select; +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-06-12 + */ +class QueryWrapperTest { + + @Test + void test01() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, ROLE.ALL_COLUMNS) + .hint("hint") + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER.USER_ID.eq(USER_ROLE.USER_ID)) + .leftJoin(ROLE).as("r").on(ROLE.ROLE_ID.eq(USER_ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)) + .and(USER.USER_ID.eq(ROLE.ROLE_ID)) + .or(USER.USER_ID.in(4, 5, 6)) + .groupBy(ROLE.ROLE_KEY) + .having(ROLE.ROLE_ID.eq(USER_ROLE.ROLE_ID)) + .orderBy(ROLE.ROLE_NAME.asc()); + + Assertions.assertEquals("SELECT /*+ hint */ `u`.`user_id`, `r`.* " + + "FROM `tb_user` AS `u` " + + "LEFT JOIN `tb_user_role` AS `ur` ON `u`.`user_id` = `ur`.`user_id` " + + "LEFT JOIN `tb_role` AS `r` ON `r`.`role_id` = `ur`.`role_id` " + + "WHERE `u`.`user_id` = 3 AND `u`.`user_id` = `r`.`role_id` OR `u`.`user_id` IN (4, 5, 6) " + + "GROUP BY `r`.`role_key` " + + "HAVING `r`.`role_id` = `ur`.`role_id` " + + "ORDER BY `r`.`role_name` ASC" + , queryWrapper.toSQL()); + + System.out.println(queryWrapper.toSQL()); + + + System.out.println(queryWrapper.toSQL()); + } + + @Test + void test02() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(count(distinct(USER.USER_ID)), case_() + .when(USER.USER_ID.eq(3)).then("x3") + .when(USER.USER_ID.eq(5)).then("x4") + .end(), + distinct(USER.USER_ID.add(4)), + USER.USER_NAME, + ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)) + .and(ROLE.ROLE_NAME.in(Arrays.asList(1, 2, 3))) + .or(ROLE.ROLE_ID.ge(USER.USER_ID)) + .groupBy(ROLE.ROLE_NAME) + .having(ROLE.ROLE_ID.ge(7)) + .orderBy(ROLE.ROLE_NAME.asc()); + + Assertions.assertEquals("SELECT COUNT(DISTINCT `u`.`user_id`), " + + "CASE WHEN `u`.`user_id` = 3 THEN 'x3' WHEN `u`.`user_id` = 5 " + + "THEN 'x4' END, DISTINCT `u`.`user_id` + 4, `u`.`user_name`, `r`.* " + + "FROM `tb_user` AS `u` " + + "LEFT JOIN `tb_user_role` AS `ur` ON `ur`.`user_id` = `u`.`user_id` " + + "LEFT JOIN `tb_role` AS `r` ON `ur`.`role_id` = `r`.`role_id` " + + "WHERE `u`.`user_id` = 3 AND `r`.`role_name` IN (1, 2, 3) OR `r`.`role_id` >= `u`.`user_id` " + + "GROUP BY `r`.`role_name` " + + "HAVING `r`.`role_id` >= 7 " + + "ORDER BY `r`.`role_name` ASC" + , queryWrapper.toSQL()); + + System.out.println(queryWrapper.toSQL()); + } + + @Test + void test03() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select() + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER.USER_ID.eq(USER_ROLE.USER_ID)) + .where(QueryCondition.createEmpty()) + .and(USER.USER_ID.eq(1).or(USER.USER_ID.in( + QueryWrapper.create().select(USER_ROLE.USER_ID).from(USER_ROLE))) + ) + .and(USER_ROLE.USER_ID.eq(1)); + System.out.println(queryWrapper.toSQL()); + QueryCondition whereQueryCondition = CPI.getWhereQueryCondition(queryWrapper); + boolean contained = CPI.containsTable(whereQueryCondition, "tb_user_role"); + + Assertions.assertTrue(contained); + } + + @Test + void test04() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select("a.*") + .from(new RawQueryTable("(select * from app)").as("a")); + + Assertions.assertEquals("SELECT a.* FROM (select * from app) AS `a`" + , queryWrapper.toSQL()); + + System.out.println(queryWrapper.toSQL()); + } + + @Test + void test05() { + RoleTableDef r = ROLE.as("r"); + UserTableDef u = USER.as("u"); + + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_NAME) + .from(USER) + .leftJoin(u).on(u.USER_ID.eq(USER.USER_ID)) + .where(USER.USER_ID.eq(1)) + // 子查询里面用了父查询里面的表 + .and(column(select(r.ROLE_ID).from(r).where(u.USER_ID.eq(r.ROLE_ID))).le(2)); + + String sql = SqlFormatter.format(queryWrapper.toSQL()); + System.out.println(sql); + + Assertions.assertEquals("SELECT\n" + + " ` tb_user `.` user_name `\n" + + "FROM\n" + + " ` tb_user `\n" + + " LEFT JOIN ` tb_user ` AS ` u ` ON ` u `.` user_id ` = ` tb_user `.` user_id `\n" + + "WHERE\n" + + " ` tb_user `.` user_id ` = 1\n" + + " AND (\n" + + " SELECT\n" + + " ` r `.` role_id `\n" + + " FROM\n" + + " ` tb_role ` AS ` r `\n" + + " WHERE\n" + + " ` u `.` user_id ` = ` r `.` role_id `\n" + + " ) <= 2", sql); + } + + @Test + void test06() { + List ids = Collections.emptyList(); + + QueryColumnBehavior.setIgnoreFunction(QueryColumnBehavior.IGNORE_EMPTY); + QueryWrapper queryWrapper = QueryWrapper.create() + .from(USER) + .where(USER.USER_ID.in(ids, v -> !v.isEmpty())) + .and(USER.USER_ID.eq(null, true)) + .and(USER.USER_NAME.eq("", true)); + QueryColumnBehavior.setIgnoreFunction(QueryColumnBehavior.IGNORE_NULL); + + String sql = SqlFormatter.format(queryWrapper.toSQL()); + System.out.println(sql); + + Assertions.assertEquals("SELECT\n" + + " *\n" + + "FROM\n" + + " ` tb_user `\n" + + "WHERE\n" + + " ` user_id ` = null\n" + + " AND ` user_name ` = ''", sql); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ReflectTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ReflectTest.java new file mode 100644 index 00000000..3b505834 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/ReflectTest.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.mybatisflex.core.util.ClassUtil; +import com.mybatisflex.loveqq.test.model.Account; +import org.apache.ibatis.reflection.TypeParameterResolver; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Type; +import java.util.List; + +/** + * @author 王帅 + * @since 2023-06-14 + */ +class ReflectTest { + + @Test + void test() { + List allFields = ClassUtil.getAllFields(Account.class); + for (Field field : allFields) { + Type type = TypeParameterResolver.resolveFieldType(field, Account.class); + System.out.println("field: " + field + "----->Type:" + type); + } + + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/SerialUtil.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/SerialUtil.java new file mode 100644 index 00000000..e19519a1 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/common/SerialUtil.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.common; + +import com.alibaba.fastjson2.JSON; +import com.alibaba.fastjson2.JSONReader; +import com.alibaba.fastjson2.JSONWriter; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.mybatisflex.core.query.QueryCondition; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; + +/** + * 序列化工具类。 + * + * @author 王帅 + * @since 2023-06-10 + */ +public class SerialUtil { + + public static byte[] writeObject(Object obj) { + try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(bos)) { + oos.writeObject(obj); + oos.flush(); + return bos.toByteArray(); + } catch (IOException e) { + return new byte[0]; + } + } + + public static Object readObject(byte[] bytes) { + try (ByteArrayInputStream bis = new ByteArrayInputStream(bytes); + ObjectInputStream ois = new ObjectInputStream(bis)) { + return ois.readObject(); + } catch (IOException | ClassNotFoundException e) { + return null; + } + } + + public static T cloneObject(Object obj) { + //noinspection unchecked + return (T) readObject(writeObject(obj)); + } + + public static String toJSONString(Object obj) { + return JSON.toJSONString(obj, JSONWriter.Feature.FieldBased, + JSONWriter.Feature.WriteClassName, + JSONWriter.Feature.NotWriteRootClassName, + JSONWriter.Feature.ReferenceDetection); + } + + public static T parseObject(String str, Class tClass) { + return JSON.parseObject(str, tClass, JSONReader.Feature.FieldBased, + JSONReader.Feature.SupportClassForName); + } + + public static T cloneObject(Object obj, Class tClass) { + return parseObject(toJSONString(obj), tClass); + } + + + /** + * 使用jackson对QueryWrapper进行序列化反序列化操作,需要注意QueryCondition的protected属性以及prev和next的递归问题。 + * + * @return Jackson序列化映射 + */ + public static ObjectMapper jacksonMapper(){ + ObjectMapper mapper = new ObjectMapper(); + // 为了将QueryWrapper里的protected属性可见 + mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.PROTECTED_AND_PUBLIC); + // 避免QueryCondition里的prev和next在序列化时出现递归调用错误 + mapper.addMixIn(QueryCondition.class,QueryConditionMixIn.class); + return mapper; + } + + /** + * 因无法修改QueryCondition而添加的映射属性包装 + */ + class QueryConditionMixIn{ + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + protected QueryCondition prev; + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AccountMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AccountMapperTest.java new file mode 100644 index 00000000..72331295 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AccountMapperTest.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.logicdelete.LogicDeleteManager; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryMethods; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.row.Db; +import com.mybatisflex.core.update.UpdateWrapper; +import com.mybatisflex.core.util.UpdateEntity; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.Account; +import com.mybatisflex.loveqq.test.model.AccountVO; +import com.mybatisflex.loveqq.test.model.AccountVO2; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Date; + +import static com.mybatisflex.core.query.QueryMethods.column; +import static com.mybatisflex.core.query.QueryMethods.concat; +import static com.mybatisflex.core.query.QueryMethods.distinct; +import static com.mybatisflex.loveqq.test.model.table.AccountTableDef.ACCOUNT; +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-06-13 + */ +@Component +@ExtendWith(LoveqqExtension.class) +@SuppressWarnings("all") +class AccountMapperTest { + + @Autowired + private AccountMapper accountMapper; + + @Autowired + private MyAccountMapper myAccountMapper; + + @Test + void testAppendCondition() { + QueryWrapper queryWrapper = QueryWrapper.create() + .where(ACCOUNT.ID.ge(0)); + Page page = Page.of(1, 10); + myAccountMapper.xmlPaginate("selectByName", page, queryWrapper); + Assertions.assertTrue(page.getRecords().size() > 0); + } + + @Test + void testInsertRaw() { + Account account = UpdateEntity.of(Account.class); + account.setUserName("I'm a joker."); + account.setBirthday(new Date()); + UpdateWrapper wrapper = (UpdateWrapper) account; + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.AGE) + .from(ACCOUNT) + .where(ACCOUNT.ID.eq(1)); + wrapper.set(ACCOUNT.AGE, queryWrapper); + wrapper.set(ACCOUNT.BIRTHDAY, QueryMethods.now()); + Assertions.assertThrows(Throwable.class, () -> accountMapper.insert(account)); + } + + @Test + void testCount() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select() + .from(ACCOUNT) + .groupBy(ACCOUNT.AGE); + + long count = accountMapper.selectCountByQuery(queryWrapper); + +// Assertions.assertEquals(2, count); + + queryWrapper = QueryWrapper.create() + .select(distinct(ACCOUNT.AGE)) + .from(ACCOUNT); + + count = accountMapper.selectCountByQuery(queryWrapper); + +// Assertions.assertEquals(2, count); + } + + /** + * 测试db执行的情况下, sql日志打印情况 + */ + @Test + void testDbSqlLogger() { + QueryWrapper wrapper = QueryWrapper.create() + .select(ACCOUNT.ALL_COLUMNS) + .from(ACCOUNT); + + Db.selectOneByQuery(wrapper); + } + + @Test + void testInsert() { + Account account = new Account(); + account.setBirthday(new Date()); + account.setUserName("张三"); + account.setAge(18); + accountMapper.insert(account); + } + + @Test + void testUpdate() { + Account account = new Account(); + account.setId(1L); + account.setAge(58); + accountMapper.update(account); + } + + @Test + void testDelete() { + accountMapper.deleteById(1L); + } + + @Test + void testSelect() { + accountMapper.selectListByQuery(QueryWrapper.create()).forEach(System.err::println); + } + + @Test + void testGenericEntity() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.ALL_COLUMNS, ROLE.ALL_COLUMNS) + .from(ACCOUNT) + .leftJoin(USER_ROLE).on(USER_ROLE.USER_ID.eq(ACCOUNT.ID)) + .leftJoin(ROLE).on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)); + accountMapper.selectListByQueryAs(queryWrapper, AccountVO.class).forEach(System.err::println); + } + + @Test + void testEnum() { + Account account = new Account(); + account.setId(1L); + account.setAge(18); + int result = accountMapper.update(account); + System.out.println(result); + } + + @Test + void testSelectListWithNullQuery() { + Assertions.assertThrows(Exception.class, () -> accountMapper.selectListByQuery(null)); + Assertions.assertThrows(Exception.class, () -> Db.selectListByQuery("tb_account", null)); + } + + @Test + void testUpdateAll() { + Account account = new Account(); + account.setAge(10); + Assertions.assertThrows(Exception.class, () -> + LogicDeleteManager.execWithoutLogicDelete(() -> accountMapper.updateByQuery(account, QueryWrapper.create()))); + } + + @Test + void testDeleteAll() { + Assertions.assertThrows(Exception.class, () -> + LogicDeleteManager.execWithoutLogicDelete(() -> accountMapper.deleteByQuery(QueryWrapper.create()))); + } + + @Test + void testAs() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.ID, + ACCOUNT.AGE, + USER.USER_ID, + USER.USER_NAME) + .from(ACCOUNT.as("a"), USER.as("u")) + .where(ACCOUNT.ID.eq(1)) + .limit(1); + AccountVO2 account = accountMapper.selectOneByQueryAs(queryWrapper, AccountVO2.class); + System.out.println(account); + } + + @Test + void testAs0() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.ID.as("account_id"), + ACCOUNT.AGE, + concat(column("'account name: '"), ACCOUNT.USER_NAME).as("user_name"), + USER.USER_ID, + concat(column("'user name: '"), USER.USER_NAME).as("1_account_name")) + .from(ACCOUNT.as("a"), USER.as("u")) + .where(ACCOUNT.ID.eq(1)) + .limit(1); + AccountVO2 account = accountMapper.selectOneByQueryAs(queryWrapper, AccountVO2.class); + System.out.println(account); + } + + @Test + void testAs1() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.ID.as(AccountVO2::getId), + ACCOUNT.AGE, + concat(column("'account name: '"), ACCOUNT.USER_NAME).as(AccountVO2::getUserName), + USER.USER_ID, + concat(column("'user name: '"), USER.USER_NAME).as("1_account_name")) + .from(ACCOUNT.as("a"), USER.as("u")) + .where(ACCOUNT.ID.eq(1)) + .limit(1); + AccountVO2 account = accountMapper.selectOneByQueryAs(queryWrapper, AccountVO2.class); + System.out.println(account); + } + + @Test + void testIgnoreColumn() { + accountMapper.selectListByQuery(QueryWrapper.create()); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/ActiveRecordTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/ActiveRecordTest.java new file mode 100644 index 00000000..ebf65212 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/ActiveRecordTest.java @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.mybatis.Mappers; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.Good; +import com.mybatisflex.loveqq.test.model.User; +import com.mybatisflex.loveqq.test.model.table.RoleTableDef; +import com.mybatisflex.loveqq.test.model.table.UserRoleTableDef; +import com.mybatisflex.loveqq.test.model.table.UserTableDef; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static com.mybatisflex.loveqq.test.model.table.GoodTableDef.GOOD; +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-07-23 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class ActiveRecordTest { + + @Test + void testMapper() { + Good good = Good.create(); + + good.setPrice(28.0); + + GoodMapper goodMapper = (GoodMapper) Mappers.ofEntityClass(Good.class); + + goodMapper.selectListByQuery(QueryWrapper.create(good)); + } + + @Test + void testInsert() { + boolean saved = Good.create() + .setPrice(28.0) + .setName("摆渡人") + .save(); + + Assertions.assertTrue(saved); + } + + @Test + void testInsertCallback() { + Integer goodId = Good.create() + .setPrice(28.0) + .setName("摆渡人") + .saveOpt() + .orElseThrow(RuntimeException::new) + .getGoodId(); + + System.out.println(goodId); + } + + @Test + void testUpdate() { + Good.create() + .setGoodId(11) + .setPrice(38.0) + .updateById(); + } + + @Test + void testDelete() { + boolean removed = Good.create() + .setGoodId(1) + .removeById(); + + System.out.println(removed); + } + + @Test + void testSelectById() { + Good good = Good.create() + .setGoodId(11) + .oneById(); + + System.out.println(good); + } + + @Test + void testSelectOne() { + Good good1 = Good.create() + .setName("摆渡人") + .one(); + + Good good2 = Good.create() + .where(GOOD.NAME.eq("摆渡人")) + .one(); + + Good good3 = Good.create() + .where(Good::getName).eq("摆渡人") + .one(); + + System.out.println(good1); + System.out.println(good2); + System.out.println(good3); + } + + @Test + void testSelectList() { + Good.create() + .where(GOOD.PRICE.ge(28.0)) + .list() + .forEach(System.out::println); + } + + @Test + void testRelation() { + User user1 = User.create() + .as("u") + .select(USER.DEFAULT_COLUMNS, ROLE.DEFAULT_COLUMNS) + .leftJoin(USER_ROLE.as("ur")).on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE.as("r")).on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(2)) + .list() + .get(0); + + User user2 = User.create() + .where(USER.USER_ID.eq(2)) + .withRelations() + .one(); + + Assertions.assertEquals(user1.toString(), user2.toString()); + } + + @Test + void testRelationsQuery() { + User.create() + .where(USER.USER_ID.ge(1)) + .withRelations() // 使用 Relations Query 的方式进行关联查询。 + .maxDepth(3) // 设置父子关系查询中,默认的递归查询深度。 + .ignoreRelations("orderList") // 忽略查询部分 Relations 注解标记的属性。 + .extraConditionParam("id", 100) // 添加额外的 Relations 查询条件。 + .list() + .forEach(System.out::println); + } + + @Test + void testFieldsQuery() { + User.create() + .where(USER.USER_ID.ge(1)) + .withFields() // 使用 Fields Query 的方式进行关联查询。 + .fieldMapping(User::getRoleList, user -> // 设置属性对应的 QueryWrapper 查询。 + QueryWrapper.create() + .select() + .from(ROLE) + .where(ROLE.ROLE_ID.in( + QueryWrapper.create() + .select(USER_ROLE.ROLE_ID) + .from(USER_ROLE) + .where(USER_ROLE.USER_ID.eq(user.getUserId())) + ))) + .list() + .forEach(System.out::println); + } + + @Test + void testToSql() { + String sql1 = User.create() + .as("u") + .select(USER.ALL_COLUMNS, ROLE.ALL_COLUMNS) + .leftJoin(USER_ROLE.as("ur")).on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE.as("r")).on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(2)) + .toQueryWrapper() + .toSQL(); + + UserTableDef u = USER.as("u"); + RoleTableDef r = ROLE.as("r"); + UserRoleTableDef ur = USER_ROLE.as("ur"); + + String sql2 = User.create() + .as(u.getAlias()) + .select(u.ALL_COLUMNS, r.ALL_COLUMNS) + .leftJoin(ur).on(ur.USER_ID.eq(u.USER_ID)) + .leftJoin(r).on(ur.ROLE_ID.eq(r.ROLE_ID)) + .where(u.USER_ID.eq(2)) + .toQueryWrapper() + .toSQL(); + + Assertions.assertEquals(sql1, sql2); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AliasTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AliasTest.java new file mode 100644 index 00000000..ecf2033e --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/AliasTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectWriter; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.FlexGlobalConfig; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.alias.SysUser; +import com.mybatisflex.loveqq.test.alias.UserVO; +import org.apache.ibatis.mapping.ResultMap; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Arrays; +import java.util.List; + +import static com.mybatisflex.core.query.QueryMethods.column; +import static com.mybatisflex.core.query.QueryMethods.select; +import static com.mybatisflex.loveqq.test.alias.table.SysDeptTableDef.SYS_DEPT; +import static com.mybatisflex.loveqq.test.alias.table.SysRoleTableDef.SYS_ROLE; +import static com.mybatisflex.loveqq.test.alias.table.SysUserTableDef.SYS_USER; + +/** + * 别名测试。 + * + * @author 王帅 + * @since 2023-11-16 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class AliasTest { + + @Autowired + SysUserMapper userMapper; + + @Autowired + ObjectMapper objectMapper; + + void printList(QueryWrapper queryWrapper) { + List users = userMapper.selectListByQuery(queryWrapper); + Assertions.assertDoesNotThrow(() -> + System.out.println(objectMapper.writerWithDefaultPrettyPrinter() + .writeValueAsString(users))); + } + + @Test + void test01() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(SYS_USER.DEFAULT_COLUMNS) + .select(SYS_ROLE.DEFAULT_COLUMNS) + .from(SYS_USER.as("u")) + .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1)); + + printList(queryWrapper); + } + + @Test + void test02() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(SYS_USER.DEFAULT_COLUMNS) + .select(SYS_ROLE.DEFAULT_COLUMNS) + .select(SYS_DEPT.DEFAULT_COLUMNS) + .from(SYS_USER.as("u")) + .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1)) + .leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1)); + + printList(queryWrapper); + } + + @Test + void test03() { + QueryWrapper queryWrapper = QueryWrapper.create() + // 调整 SELECT 顺序 + .select(SYS_ROLE.DEFAULT_COLUMNS) + .select(SYS_DEPT.DEFAULT_COLUMNS) + .select(SYS_USER.DEFAULT_COLUMNS) + .from(SYS_USER.as("u")) + .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1)) + .leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1)); + + printList(queryWrapper); + } + + @Test + void test04() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(column("`u`.`create_by` AS `sys_user$create_by`")) + .select(column("`u`.`update_by` AS `sys_user$update_by`")) + .from(SYS_USER.as("u")); + + printList(queryWrapper); + } + + @Test + void test05() { + QueryWrapper queryWrapper = QueryWrapper.create() + // 不支持的情况 + .select(column("`u`.`create_by`")) + .select(column("`u`.`update_by`")) + .select(column("`d`.`create_by`")) + .select(column("`d`.`update_by`")) + .from(select(column("*")).from(SYS_USER)).as("u") + .from(SYS_DEPT.as("d")); + + printList(queryWrapper); + } + + @Test + void test06() { + QueryWrapper queryWrapper = QueryWrapper.create() + // SELECT 里没有重名列 例如:id + .select(SYS_USER.ID, SYS_USER.USER_NAME, SYS_USER.AGE, SYS_USER.BIRTHDAY) + .select(SYS_ROLE.CREATE_BY.as("sys_role$create_by")) + .from(SYS_USER.as("u")) + .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1)); + + Object[] objects = FlexGlobalConfig.getDefaultConfig() + .getConfiguration() + .getResultMaps() + .toArray(); + + Object[] resultMaps = Arrays.stream(objects) + .filter(e -> e instanceof ResultMap) + .map(e -> (ResultMap) e) + .filter(e -> e.getId().contains("Sys")) + .filter(e -> !e.getId().contains("select")) + .toArray(); + + System.out.println(resultMaps.length); + + printList(queryWrapper); + } + + @Test + void test07() throws JsonProcessingException { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(SYS_USER.DEFAULT_COLUMNS) + .select(SYS_ROLE.DEFAULT_COLUMNS) + .select(SYS_DEPT.DEFAULT_COLUMNS) + .from(SYS_USER.as("u")) + .leftJoin(SYS_ROLE.as("r")).on(SYS_USER.ID.eq(1)) + .leftJoin(SYS_DEPT.as("d")).on(SYS_USER.ID.eq(1)); + + ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter(); + + String userList1 = objectWriter.writeValueAsString(userMapper.selectListByQuery(queryWrapper)); + String userList2 = objectWriter.writeValueAsString(userMapper.selectListByQueryAs(queryWrapper, UserVO.class)); + + Assertions.assertEquals(userList1, userList2); + } + + @Test + void test08() throws JsonProcessingException { + SysUser user = userMapper.selectOneById(1); + ObjectWriter objectWriter = objectMapper.writerWithDefaultPrettyPrinter(); + System.out.println(objectWriter.writeValueAsString(user)); + Assertions.assertTrue(true); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/CombinedMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/CombinedMapperTest.java new file mode 100644 index 00000000..148ac31f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/CombinedMapperTest.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.Account; +import com.mybatisflex.loveqq.test.model.Article; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.List; + +@Component +@ExtendWith(LoveqqExtension.class) +public class CombinedMapperTest { + + @Autowired + private AccountMapper accountMapper; + + @Autowired + private ArticleMapper articleMapper; + + @Test + void testQuery() { + + for (int i = 0; i < 10; i++) { + List accounts = accountMapper.selectListByQuery(QueryWrapper.create()); + List

articles = articleMapper.selectListByQuery(QueryWrapper.create()); + } + + + System.out.println(">>>>>>finished!!!"); + } + + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapperTest.java new file mode 100644 index 00000000..0444a74c --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/MyAccountMapperTest.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.Account; +import com.mybatisflex.loveqq.test.model.AccountView; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * @author 庄佳彬 + * @since 2023/4/24 19:37 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class MyAccountMapperTest { + + @Autowired + private MyAccountMapper mapper; + + @Test + void complexSelect() { + AccountView accountView = Assertions.assertDoesNotThrow(() -> mapper.selectViewObject()); + System.out.println(accountView); + } + + @Test + void insertBatch() { + List accounts = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + Account account = new Account(); + account.setBirthday(new Date()); + account.setAge(i % 60); + account.setUserName(String.valueOf(i)); + accounts.add(account); + } + //删除初始化数据 + mapper.deleteById(1); + mapper.deleteById(2); + try { + mapper.insertBatch(accounts); + } catch (Exception e) { + System.out.println("异常"); + } + int i = mapper.insertBatch(accounts, 1000); + assertEquals(10, i); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/OuterMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/OuterMapperTest.java new file mode 100644 index 00000000..bc36bcd9 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/OuterMapperTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.entity.Outer; +import com.mybatisflex.loveqq.test.entity.table.InnerTableDef; +import com.mybatisflex.loveqq.test.entity.table.OuterTableDef; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static com.mybatisflex.loveqq.test.entity.table.InnerTableDef.INNER; +import static com.mybatisflex.loveqq.test.entity.table.OuterTableDef.OUTER; + +/** + * @author 王帅 + * @since 2023-07-01 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class OuterMapperTest { + + @Autowired + private OuterMapper outerMapper; + + @Autowired + private InnerMapper innerMapper; + + @Test + void testInsert() { + Outer outer = new Outer(); + outer.setName("outer 01"); + int result = outerMapper.insertSelective(outer); + Assertions.assertEquals(result,1); + } + + @Test + void testSelect() { + OuterTableDef outer = OUTER.as("o"); + InnerTableDef inner = INNER.as("i"); + QueryWrapper queryWrapper = QueryWrapper.create() + .select(outer.ID, + outer.NAME, + inner.ID, + inner.TYPE) + .from(outer) + .leftJoin(inner).on(inner.ID.eq(2)) + .limit(1); + Outer outer1 = outerMapper.selectOneByQuery(queryWrapper); + System.out.println(outer1); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/PatientMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/PatientMapperTest.java new file mode 100644 index 00000000..5f2a703f --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/PatientMapperTest.java @@ -0,0 +1,30 @@ +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import javax.annotation.Resource; + +/** + * 患者相关测试 + * + * @author Ice 2023/09/26 + * @version 1.0 + */ +@Component +@ExtendWith(LoveqqExtension.class) +@SuppressWarnings("all") +public class PatientMapperTest { + + @Resource + private PatientMapper patientMapper; + + @Test + public void testRelationOneToManySplitBy() { +// QueryWrapper wrapper = QueryWrapper.create().orderBy(PatientVO1::getPatientId, false).limit(1); +// PatientVO1 patientVO1 = patientMapper.selectOneWithRelationsByQueryAs(wrapper, PatientVO1.class); +// System.out.println(JSON.toJSONString(patientVO1)); + } +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/QueryChainTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/QueryChainTest.java new file mode 100644 index 00000000..ce76ca4b --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/QueryChainTest.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.field.QueryBuilder; +import com.mybatisflex.core.query.QueryChain; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.core.update.UpdateChain; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.Gender; +import com.mybatisflex.loveqq.test.model.User; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-08-08 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class QueryChainTest { + + @Autowired + UserMapper userMapper; + + @Test + void testFields() { + QueryBuilder builder = user -> + QueryWrapper.create() + .select() + .from(ROLE) + .where(ROLE.ROLE_ID.in( + QueryWrapper.create() + .select(USER_ROLE.ROLE_ID) + .from(USER_ROLE) + .where(USER_ROLE.USER_ID.eq(user.getUserId())) + )); + + User user1 = QueryChain.of(userMapper) + .where(USER.USER_ID.eq(1)) + .withFields() + .fieldMapping(User::getRoleList, builder) + .one(); + + User user2 = User.create() + .where(USER.USER_ID.eq(1)) + .withFields() + .fieldMapping(User::getRoleList, builder) + .one(); + + Assertions.assertEquals(user1.toString(), user2.toString()); + } + + @Test + void testRelations() { + User user1 = QueryChain.of(userMapper) + .where(USER.USER_ID.eq(2)) + .withRelations() + .one(); + + User user2 = User.create() + .where(USER.USER_ID.eq(2)) + .withRelations() + .one(); + + Assertions.assertEquals(user1.toString(), user2.toString()); + } + + @Test + void testToSql() { + String sql = UpdateChain.create(userMapper) + .set(USER.USER_NAME, "张三") + .set(User::getUserId, Gender.MALE) + .where(USER.USER_ID.eq(1)) + .toSQL(); + + System.out.println(sql); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapperTest.java new file mode 100644 index 00000000..39032f89 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UnmappedUserMapperTest.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.query.QueryColumn; +import com.mybatisflex.core.query.QueryMethods; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.UnmappedUser; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.List; + +import static com.mybatisflex.loveqq.test.model.table.UnmappedUserTableDef.UNMAPPED_USER; + +/** + * UnMappedUserMapperTest + * + * @author wy + * @version 1.0 + * @date 2024/9/12 11:39 + **/ +@Component +@ExtendWith(LoveqqExtension.class) +@SuppressWarnings("all") +public class UnmappedUserMapperTest { + + @Autowired + private UnmappedUserMapper unmappedUserMapper; + + /** + * 额外字段查询,数据库中有,但是实体类中没有 + * 应用:前端具有一定查询数据库能力时,不改后端代码情况下,返回新增字段数据 + */ + @Test + void testExtraColumn() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(UNMAPPED_USER.ID, UNMAPPED_USER.AGE, UNMAPPED_USER.NAME, + // 额外字段查询 + new QueryColumn("code")) + .where(UNMAPPED_USER.ID.in(1, 2, 3)); + List unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper); + System.out.println(unmappedUserList); + } + + /** + * 同名字段 + * 多数据源下同表同名字段不同含义或者需要同时展示 + */ + @Test + void testSameColumn() { + // 可能多数据源下会存在同表同名字段不同值 + QueryWrapper queryWrapper = QueryWrapper.create() + .select(UNMAPPED_USER.ID, UNMAPPED_USER.AGE, UNMAPPED_USER.NAME, + // 同名字段重置 + UNMAPPED_USER.NAME.as("ext_name")) + .where(UNMAPPED_USER.ID.in(1, 2, 3)); + List unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper); + System.out.println(unmappedUserList); + } + + /** + * 计算或者处理的字段 + * sql中进行处理的字段,不直接映射到实体类上的域 + */ + @Test + void testCalColumn() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(UNMAPPED_USER.ID, UNMAPPED_USER.NAME, UNMAPPED_USER.AGE, + // 字段计算结果 + QueryMethods.case_() + .when(UNMAPPED_USER.AGE.ge(18)).then("adult") + .when(UNMAPPED_USER.AGE.le(14)).then("child") + .else_("juvenile") + .end() + .as("age_group")) + .where(UNMAPPED_USER.ID.in(1, 2, 3)); + List unmappedUserList = unmappedUserMapper.selectListByQuery(queryWrapper); + System.out.println(unmappedUserList); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UserMapperTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UserMapperTest.java new file mode 100644 index 00000000..0cda4dcd --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/mapper/UserMapperTest.java @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2022-2025, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.mapper; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.paginate.Page; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.model.OrderInfo; +import com.mybatisflex.loveqq.test.model.User; +import com.mybatisflex.loveqq.test.model.UserInfo; +import com.mybatisflex.loveqq.test.model.UserVO; +import com.mybatisflex.loveqq.test.model.UserVO1; +import com.mybatisflex.loveqq.test.model.UserVO2; +import com.mybatisflex.loveqq.test.model.UserVO3; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.List; + +import static com.mybatisflex.core.query.QueryMethods.select; +import static com.mybatisflex.loveqq.test.model.table.GoodTableDef.GOOD; +import static com.mybatisflex.loveqq.test.model.table.IdCardTableDef.ID_CARD; +import static com.mybatisflex.loveqq.test.model.table.OrderGoodTableDef.ORDER_GOOD; +import static com.mybatisflex.loveqq.test.model.table.OrderTableDef.ORDER; +import static com.mybatisflex.loveqq.test.model.table.RoleTableDef.ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserOrderTableDef.USER_ORDER; +import static com.mybatisflex.loveqq.test.model.table.UserRoleTableDef.USER_ROLE; +import static com.mybatisflex.loveqq.test.model.table.UserTableDef.USER; + +/** + * @author 王帅 + * @since 2023-06-07 + */ +@Component +@ExtendWith(LoveqqExtension.class) +@SuppressWarnings("all") +class UserMapperTest { + + @Autowired + private UserMapper userMapper; + + @Test + void testSelectOne() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME, ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)); + System.out.println(queryWrapper.toSQL()); + // UserVO userVO = userMapper.selectOneByQueryAs(queryWrapper, UserVO.class); + // UserVO1 userVO = userMapper.selectOneByQueryAs(queryWrapper, UserVO1.class); + // UserVO2 userVO = userMapper.selectOneByQueryAs(queryWrapper, UserVO2.class); + UserVO3 userVO = userMapper.selectOneByQueryAs(queryWrapper, UserVO3.class); + System.err.println(userVO); + } + + @Test + void testFieldQuery() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME) + .from(USER.as("u")) + .where(USER.USER_ID.eq(3)); + System.out.println(queryWrapper.toSQL()); + List userVOs = userMapper.selectListByQueryAs(queryWrapper, UserVO.class, + fieldQueryBuilder -> fieldQueryBuilder + .field(UserVO::getRoleList) + .prevent(true) + .queryWrapper(user -> QueryWrapper.create() + .select() + .from(ROLE) + .where(ROLE.ROLE_ID.in( + select(USER_ROLE.ROLE_ID) + .from(USER_ROLE) + .where(USER_ROLE.USER_ID.eq(user.getUserId()) + ) + ) + ) + ) + ); + System.err.println(userVOs); + } + + @Test + void testSelectList() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME, ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(3)); + System.out.println(queryWrapper.toSQL()); + List userVOS = userMapper.selectListByQueryAs(queryWrapper, UserVO.class); + userVOS.forEach(System.err::println); + } + + @Test + void testSelectListNoJoin() { + List users = userMapper.selectListByQueryAs(QueryWrapper.create(), User.class); + users.forEach(System.err::println); + List userVOS = userMapper.selectListByQueryAs(QueryWrapper.create(), UserVO.class); + userVOS.forEach(System.err::println); + } + + @Test + void testComplexSelectList() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.ALL_COLUMNS, ID_CARD.ID_NUMBER, ROLE.ALL_COLUMNS, ORDER.ALL_COLUMNS, GOOD.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(ID_CARD).as("i").on(USER.USER_ID.eq(ID_CARD.ID)) + .leftJoin(USER_ROLE).as("ur").on(USER.USER_ID.eq(USER_ROLE.USER_ID)) + .leftJoin(ROLE).as("r").on(ROLE.ROLE_ID.eq(USER_ROLE.ROLE_ID)) + .leftJoin(USER_ORDER).as("uo").on(USER.USER_ID.eq(USER_ORDER.USER_ID)) + .leftJoin(ORDER).as("o").on(ORDER.ORDER_ID.eq(USER_ORDER.ORDER_ID)) + .leftJoin(ORDER_GOOD).as("og").on(ORDER.ORDER_ID.eq(ORDER_GOOD.ORDER_ID)) + .leftJoin(GOOD).as("g").on(GOOD.GOOD_ID.eq(ORDER_GOOD.GOOD_ID)); + System.err.println(queryWrapper.toSQL()); + List userInfos = userMapper.selectListByQueryAs(queryWrapper, UserInfo.class); + userInfos.forEach(System.err::println); + } + + @Test + void testComplexSelectListRelations() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.ALL_COLUMNS, ID_CARD.ID_NUMBER) + .from(USER.as("u")) + .leftJoin(ID_CARD).as("i").on(USER.USER_ID.eq(ID_CARD.ID)) + .where(USER.USER_ID.eq(2)); +// List userInfos = userMapper.selectListWithRelationsByQueryAs(queryWrapper, UserInfo.class); +// userInfos.forEach(System.err::println); + UserInfo userInfo = userMapper.selectOneWithRelationsByQueryAs(queryWrapper, UserInfo.class); + System.out.println(userInfo); + } + + @Test + void testComplexSelectListFields() { + List userInfos = userMapper.selectListByQueryAs(QueryWrapper.create(), UserInfo.class, + c -> c.field(UserInfo::getIdNumber).queryWrapper(userInfo -> + QueryWrapper.create() + .select(ID_CARD.ID_NUMBER) + .from(ID_CARD) + .where(ID_CARD.ID.eq(userInfo.getUserId())) + ), + c -> c.field(UserInfo::getRoleList).prevent().queryWrapper(userInfo -> + QueryWrapper.create() + .select() + .from(ROLE.as("r")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER_ROLE.USER_ID.eq(userInfo.getUserId())) + ), + c -> c.field(UserInfo::getOrderInfoList).queryWrapper(userInfo -> + /*QueryWrapper.create() + .select() + .from(ORDER.as("o")) + .leftJoin(USER_ORDER).as("uo").on(USER_ORDER.ORDER_ID.eq(ORDER.ORDER_ID)) + .where(USER_ORDER.USER_ID.eq(userInfo.getUserId()))*/ + null + ), + c -> c.nestedField(OrderInfo::getGoodList).prevent().queryWrapper(orderInfo -> + QueryWrapper.create() + .select() + .from(GOOD.as("g")) + .leftJoin(ORDER_GOOD).as("og").on(ORDER_GOOD.GOOD_ID.eq(GOOD.GOOD_ID)) + .where(ORDER_GOOD.ORDER_ID.eq(orderInfo.getOrderId())) + ) + ); + userInfos.forEach(System.err::println); + } + + @Test + void testEquals() { + QueryWrapper queryWrapper1 = QueryWrapper.create() + .select(USER.ALL_COLUMNS, ID_CARD.ID_NUMBER, ROLE.ALL_COLUMNS, ORDER.ALL_COLUMNS, GOOD.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(ID_CARD).as("i").on(USER.USER_ID.eq(ID_CARD.ID)) + .leftJoin(USER_ROLE).as("ur").on(USER.USER_ID.eq(USER_ROLE.USER_ID)) + .leftJoin(ROLE).as("r").on(ROLE.ROLE_ID.eq(USER_ROLE.ROLE_ID)) + .leftJoin(USER_ORDER).as("uo").on(USER.USER_ID.eq(USER_ORDER.USER_ID)) + .leftJoin(ORDER).as("o").on(ORDER.ORDER_ID.eq(USER_ORDER.ORDER_ID)) + .leftJoin(ORDER_GOOD).as("og").on(ORDER.ORDER_ID.eq(ORDER_GOOD.ORDER_ID)) + .leftJoin(GOOD).as("g").on(GOOD.GOOD_ID.eq(ORDER_GOOD.GOOD_ID)) + .orderBy(USER.USER_ID.asc(), ROLE.ROLE_ID.asc(), ORDER.ORDER_ID.asc(), GOOD.GOOD_ID.asc()); + List userInfos1 = userMapper.selectListByQueryAs(queryWrapper1, UserInfo.class); + + QueryWrapper queryWrapper2 = QueryWrapper.create() + .select(USER.ALL_COLUMNS, ID_CARD.ID_NUMBER) + .from(USER.as("u")) + .leftJoin(ID_CARD).as("i").on(USER.USER_ID.eq(ID_CARD.ID)); + List userInfos2 = userMapper.selectListWithRelationsByQueryAs(queryWrapper2, UserInfo.class); + + List userInfos3 = userMapper.selectListByQueryAs(QueryWrapper.create(), UserInfo.class, + c -> c.field(UserInfo::getIdNumber).queryWrapper(userInfo -> + QueryWrapper.create() + .select(ID_CARD.ID_NUMBER) + .from(ID_CARD) + .where(ID_CARD.ID.eq(userInfo.getUserId())) + ), + c -> c.field(UserInfo::getRoleList).prevent().queryWrapper(userInfo -> + QueryWrapper.create() + .select() + .from(ROLE.as("r")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER_ROLE.USER_ID.eq(userInfo.getUserId())) + .orderBy(ROLE.ROLE_ID.asc()) + ), + c -> c.field(UserInfo::getOrderInfoList).queryWrapper(userInfo -> + QueryWrapper.create() + .select() + .from(ORDER.as("o")) + .leftJoin(USER_ORDER).as("uo").on(USER_ORDER.ORDER_ID.eq(ORDER.ORDER_ID)) + .where(USER_ORDER.USER_ID.eq(userInfo.getUserId())) + .orderBy(ORDER.ORDER_ID.asc()) + ), + c -> c.nestedField(OrderInfo::getGoodList).prevent().queryWrapper(orderInfo -> + QueryWrapper.create() + .select() + .from(GOOD.as("g")) + .leftJoin(ORDER_GOOD).as("og").on(ORDER_GOOD.GOOD_ID.eq(GOOD.GOOD_ID)) + .where(ORDER_GOOD.ORDER_ID.eq(orderInfo.getOrderId())) + .orderBy(GOOD.GOOD_ID.asc()) + ) + ); + + Assertions.assertEquals(userInfos1.toString(), userInfos2.toString()); + Assertions.assertEquals(userInfos1.toString(), userInfos3.toString()); + } + + @Test + void testCircularReference() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME, ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(1)); + List userVO1s = userMapper.selectListByQueryAs(queryWrapper, UserVO1.class); + System.err.println(userVO1s); + } + + @Test + void testPage() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, USER.USER_NAME, ROLE.ALL_COLUMNS) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)); + System.err.println(queryWrapper.toSQL()); + Page page = new Page<>(); + page.setOptimizeCountQuery(false); + int pageNumber = 0; + do { + page = userMapper.paginateAs(page, queryWrapper, UserVO.class); + System.err.println(page); + page.setPageNumber(page.getPageNumber() + 1); + } while (page.hasNext()); + } + + @Test + void testListString() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, + USER.USER_NAME, + ROLE.ROLE_NAME.as("roles"), + ROLE.ROLE_ID.as("role_ids")) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(2)); + UserVO2 user = userMapper.selectOneByQueryAs(queryWrapper, UserVO2.class); + System.err.println(user); + user = userMapper.selectOneByQueryAs(queryWrapper, UserVO2.class); + System.err.println(user); + } + + + @Test + void testQueryWrapper() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(USER.USER_ID, + USER.USER_NAME, + ROLE.ROLE_NAME.as("roles"), + ROLE.ROLE_ID.as("role_ids")) + .from(USER.as("u")) + .leftJoin(USER_ROLE).as("ur").on(USER_ROLE.USER_ID.eq(USER.USER_ID)) + .leftJoin(ROLE).as("r").on(USER_ROLE.ROLE_ID.eq(ROLE.ROLE_ID)) + .where(USER.USER_ID.eq(2)); + + String sql = queryWrapper.toSQL(); + System.out.println(sql); + } + +// @Test +// public void testFieldBindRelations() { +// List userVO5List = userMapper.selectListWithRelationsByQueryAs(QueryWrapper.create(), UserVO5.class); +// System.out.println(userVO5List); +// } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/ArticleServiceTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/ArticleServiceTest.java new file mode 100644 index 00000000..4e58fc38 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/ArticleServiceTest.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2022-2024, Mybatis-Flex (fuhai999@gmail.com). + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.mybatisflex.loveqq.test.service; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.core.query.QueryWrapper; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.transaction.annotation.Transactional; + +import static com.mybatisflex.core.query.QueryMethods.case_; +import static com.mybatisflex.core.query.QueryMethods.length; +import static com.mybatisflex.loveqq.test.model.table.AccountTableDef.ACCOUNT; +import static com.mybatisflex.loveqq.test.model.table.ArticleTableDef.ARTICLE; + +/** + * @author 王帅 + * @since 2023-07-22 + */ +@Component +@ExtendWith(LoveqqExtension.class) +class ArticleServiceTest { + + @Autowired + ArticleService articleService; + + @Test + void testChangeDataSource() { + articleService.changeDataSource(); + Assertions.assertTrue(true); + } + + @Test + void testChain() { + Assertions.assertDoesNotThrow(() -> + articleService.queryChain() + .select(ARTICLE.DEFAULT_COLUMNS) + .from(ARTICLE) + .where(ARTICLE.ID.ge(100)) + .objList() + .forEach(System.out::println) + ); + } + + @Test + void testExists() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ARTICLE.DEFAULT_COLUMNS) + .from(ARTICLE) + .where(ARTICLE.ACCOUNT_ID.eq(1)) + .orderBy(ARTICLE.ACCOUNT_ID.desc()); + boolean exists = articleService.exists(queryWrapper); + Assertions.assertTrue(exists); + } + + @Test + @Transactional + void testSubUpdate() { + QueryWrapper queryWrapper = QueryWrapper.create() + .select(ACCOUNT.AGE) + .from(ACCOUNT) + .where(ACCOUNT.ID.eq(1)); + + boolean updated = articleService.updateChain() + .set(ARTICLE.CONTENT, "hhhh") + .set(ARTICLE.ACCOUNT_ID, queryWrapper) + .set(ARTICLE.IS_DELETE, ARTICLE.IS_DELETE.eq(0)) + .set(ARTICLE.TITLE, case_(length(ARTICLE.TITLE)).when(1).then("title1").else_("大标题").end()) + .update(); + + Assertions.assertTrue(updated); + } + +} diff --git a/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/FieldMappingTest.java b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/FieldMappingTest.java new file mode 100644 index 00000000..bb34a044 --- /dev/null +++ b/mybatis-flex-test/mybatis-flex-loveqq-test/src/test/java/com/mybatisflex/loveqq/test/service/FieldMappingTest.java @@ -0,0 +1,35 @@ +package com.mybatisflex.loveqq.test.service; + +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Autowired; +import com.kfyty.loveqq.framework.core.autoconfig.annotation.Component; +import com.mybatisflex.loveqq.test.LoveqqExtension; +import com.mybatisflex.loveqq.test.mapper.FieldMappingInnerMapper; +import com.mybatisflex.loveqq.test.mapper.FieldMappingMapper; +import com.mybatisflex.loveqq.test.model.FieldMapping; +import com.mybatisflex.loveqq.test.model.FieldMappingInner; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; + +import java.util.Date; + +@Component +@ExtendWith(LoveqqExtension.class) +class FieldMappingTest { + @Autowired + FieldMappingMapper fieldMappingMapper; + + @Autowired + FieldMappingInnerMapper fieldMappingInnerMapper; + + @Test + void testFieldMapping() { + String fieldId = FieldMapping.create().saveOpt().get().getId(); + FieldMappingInner.create().setCreateDate(new Date()).setOutId(fieldId).save(); + FieldMapping.create() + .withFields() + .fieldMapping(FieldMapping::getInnerDate, con -> + FieldMappingInner.create().select(FieldMappingInner::getCreateDate).where(FieldMappingInner::getOutId).eq(con.getId()).toQueryWrapper() + ) + .list().forEach(System.out::println); + } +} diff --git a/mybatis-flex-test/pom.xml b/mybatis-flex-test/pom.xml index ac876c75..bebd8e10 100644 --- a/mybatis-flex-test/pom.xml +++ b/mybatis-flex-test/pom.xml @@ -20,6 +20,7 @@ mybatis-flex-spring-boot-test mybatis-flex-spring-cloud-test + mybatis-flex-loveqq-test diff --git a/pom.xml b/pom.xml index d5e91b29..987dd8d9 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,7 @@ mybatis-flex-spring-boot-starter mybatis-flex-spring-boot3-starter mybatis-flex-solon-plugin + mybatis-flex-loveqq-starter mybatis-flex-test mybatis-flex-processor @@ -77,7 +78,9 @@ 5.3.27 2.7.11 3.0.1 + 1.1.0-java8 + 1.18.30 4.13.2 1.19.3 1.5.0