From 00de9c57cb6bc0fb421667a70727b10c16519bb7 Mon Sep 17 00:00:00 2001 From: dengqichen Date: Fri, 29 Nov 2024 12:39:21 +0800 Subject: [PATCH] =?UTF-8?q?=E5=8F=AF=E6=AD=A3=E5=B8=B8=E5=90=AF=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/converter/RoleConverter.java | 5 +- .../backend/converter/TenantConverter.java | 5 +- .../backend/converter/UserConverter.java | 4 +- .../framework/annotation/QueryField.java | 1 + .../converter/AbstractConverter.java | 29 ---- .../framework/converter/BaseConverter.java | 1 - .../framework/repository/IBaseRepository.java | 126 +++++------------- .../security/config/SecurityConfig.java | 2 + backend/src/main/resources/application.yml | 6 +- 9 files changed, 46 insertions(+), 133 deletions(-) delete mode 100644 backend/src/main/java/com/qqchen/deploy/backend/framework/converter/AbstractConverter.java diff --git a/backend/src/main/java/com/qqchen/deploy/backend/converter/RoleConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/converter/RoleConverter.java index 669d72f7..09c24b3b 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/converter/RoleConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/converter/RoleConverter.java @@ -4,9 +4,8 @@ import com.qqchen.deploy.backend.dto.RoleDTO; import com.qqchen.deploy.backend.entity.Role; import com.qqchen.deploy.backend.framework.converter.BaseConverter; import org.mapstruct.Mapper; -import org.mapstruct.ReportingPolicy; -@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +@Mapper(config = BaseConverter.class) public interface RoleConverter extends BaseConverter { - // MapStruct 会自动实现必要的方法 + // MapStruct 会自动实现所有方法 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/converter/TenantConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/converter/TenantConverter.java index 90fe4874..a1c3691e 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/converter/TenantConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/converter/TenantConverter.java @@ -2,10 +2,11 @@ package com.qqchen.deploy.backend.converter; import com.qqchen.deploy.backend.dto.TenantDTO; import com.qqchen.deploy.backend.entity.Tenant; -import com.qqchen.deploy.backend.framework.converter.AbstractConverter; import com.qqchen.deploy.backend.framework.converter.BaseConverter; import org.mapstruct.Mapper; + @Mapper(config = BaseConverter.class) -public abstract class TenantConverter extends AbstractConverter implements BaseConverter { +public interface TenantConverter extends BaseConverter { + // MapStruct 会自动实现所有方法 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/converter/UserConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/converter/UserConverter.java index f150166d..8dff4cbf 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/converter/UserConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/converter/UserConverter.java @@ -1,11 +1,11 @@ package com.qqchen.deploy.backend.converter; -import com.qqchen.deploy.backend.framework.converter.AbstractConverter; import com.qqchen.deploy.backend.framework.converter.BaseConverter; import com.qqchen.deploy.backend.entity.User; import com.qqchen.deploy.backend.dto.UserDTO; import org.mapstruct.Mapper; @Mapper(config = BaseConverter.class) -public abstract class UserConverter extends AbstractConverter implements BaseConverter { +public interface UserConverter extends BaseConverter { + // MapStruct 会自动实现所有方法 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/QueryField.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/QueryField.java index b925e9a1..9f6fff4f 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/QueryField.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/annotation/QueryField.java @@ -11,5 +11,6 @@ import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) public @interface QueryField { String field() default ""; // 实体类中的字段名 + QueryType type() default QueryType.EQUAL; // 查询方式 } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/AbstractConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/AbstractConverter.java deleted file mode 100644 index 2db2d0e1..00000000 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/AbstractConverter.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.qqchen.deploy.backend.framework.converter; - -import com.qqchen.deploy.backend.framework.domain.Entity; -import com.qqchen.deploy.backend.framework.dto.BaseDTO; -import org.springframework.core.GenericTypeResolver; - -public abstract class AbstractConverter, D extends BaseDTO> { - - private final Class entityClass; - private final Class dtoClass; - - @SuppressWarnings("unchecked") - protected AbstractConverter() { - Class[] genericTypes = GenericTypeResolver.resolveTypeArguments(getClass(), AbstractConverter.class); - if (genericTypes == null || genericTypes.length < 2) { - throw new IllegalStateException("Could not resolve generic types"); - } - this.entityClass = (Class) genericTypes[0]; - this.dtoClass = (Class) genericTypes[1]; - } - - public Class getEntityClass() { - return entityClass; - } - - public Class getDtoClass() { - return dtoClass; - } -} \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/BaseConverter.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/BaseConverter.java index 6e2d0262..4eccba00 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/BaseConverter.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/converter/BaseConverter.java @@ -59,5 +59,4 @@ public interface BaseConverter, D extends BaseDTO> { .map(this::toEntity) .collect(Collectors.toList()); } - } \ No newline at end of file diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/repository/IBaseRepository.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/repository/IBaseRepository.java index a38423f7..bda49972 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/repository/IBaseRepository.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/repository/IBaseRepository.java @@ -1,5 +1,6 @@ package com.qqchen.deploy.backend.framework.repository; +import com.google.common.collect.Lists; import com.qqchen.deploy.backend.framework.domain.Entity; import jakarta.persistence.LockModeType; import org.springframework.data.jpa.repository.JpaRepository; @@ -17,14 +18,12 @@ import java.util.List; import java.util.Optional; import java.util.Collection; import java.time.LocalDateTime; -import java.util.ArrayList; @NoRepositoryBean public interface IBaseRepository, ID extends Serializable> extends JpaRepository, QuerydslPredicateExecutor { -// extends JpaRepository, QuerydslPredicateExecutor, JpaSpecificationExecutor { - + // 基础查询方法 @Override @Query("select e from #{#entityName} e where e.deleted = false") List findAll(); @@ -33,6 +32,7 @@ public interface IBaseRepository, ID extends Serializable> @Query("select e from #{#entityName} e where e.id = ?1 and e.deleted = false") Optional findById(ID id); + // 逻辑删除 @Override default void delete(T entity) { entity.setDeleted(true); @@ -46,12 +46,18 @@ public interface IBaseRepository, ID extends Serializable> // 批量操作 @Modifying - @Query("update #{#entityName} e set e.deleted = true where e.id in ?1") - void logicDeleteByIds(Collection ids); + @Query("update #{#entityName} e set e.deleted = true where e.id in :ids") + void batchDelete(@Param("ids") Collection ids); -// @Modifying -// @Query("update #{#entityName} e set e.enabled = ?2 where e.id in ?1") -// void updateEnabledByIds(Collection ids, boolean enabled); + @Modifying + @Query("UPDATE #{#entityName} e SET e.updateTime = :updateTime, " + + "e.updateBy = :updateBy, e.version = e.version + 1 " + + "WHERE e.id IN :ids") + void batchUpdate( + @Param("ids") Collection ids, + @Param("updateTime") LocalDateTime updateTime, + @Param("updateBy") String updateBy + ); // 快速查询方法 Optional findByIdAndDeletedFalse(ID id); @@ -60,109 +66,41 @@ public interface IBaseRepository, ID extends Serializable> boolean existsByIdAndDeletedFalse(ID id); - // 自定义查询 + // 条件查询 @Query("select e from #{#entityName} e where e.deleted = false and " + - "(?1 is null or e.createTime >= ?1) and " + - "(?2 is null or e.createTime <= ?2)") - List findByCreateTimeBetween(LocalDateTime start, LocalDateTime end); + "(:start is null or e.createTime >= :start) and " + + "(:end is null or e.createTime <= :end)") + List findByCreateTimeBetween( + @Param("start") LocalDateTime start, + @Param("end") LocalDateTime end + ); @Query("select e from #{#entityName} e where e.deleted = false and " + - "(?1 is null or e.createBy = ?1)") - List findByCreateBy(String creator); + "(:creator is null or e.createBy = :creator)") + List findByCreateBy(@Param("creator") String creator); + + @Query("select e from #{#entityName} e where e.deleted = false " + + "order by e.createTime desc") + List findLatest(Pageable pageable); // 统计方法 @Query("select count(e) from #{#entityName} e where e.deleted = false") long countNonDeleted(); -// @Query("select count(e) from #{#entityName} e where e.deleted = false and e.enabled = ?1") -// long countByEnabled(boolean enabled); - - // 高级查询 - @Query("select e from #{#entityName} e where e.deleted = false " + - "order by e.createTime desc") - List findLatest(Pageable pageable); - - @Query("select distinct e.createBy from #{#entityName} e where e.deleted = false") - List findAllCreators(); - - // 批量更新 - @Modifying - @Query("update #{#entityName} e set e.updateBy = ?2, e.updateTime = ?3 where e.id in ?1") - void updateAuditInfo(Collection ids, String updateBy, LocalDateTime updateTime); - - /** - * 根据条件查询并排序 - */ + // QueryDSL支持 default List findAllByCondition(com.querydsl.core.types.Predicate predicate, Sort sort) { - Iterable iterable = findAll(predicate, sort); - List result = new ArrayList<>(); - iterable.forEach(result::add); - return result; + return Lists.newArrayList(findAll(predicate, sort)); } - // 批量保存并返回保存的实体 - default List saveAllAndReturn(Iterable entities) { - return saveAll(entities); - } - - /** - * 根据条件查询并排序 - * 使用QueryDSL的Predicate进行条件查询 - */ - @Override - Iterable findAll(com.querydsl.core.types.Predicate predicate); - - @Override - Iterable findAll(com.querydsl.core.types.Predicate predicate, Sort sort); - - /** - * 提供一个默认的转换方法 - */ - default List findAllAndConvert(com.querydsl.core.types.Predicate predicate, Sort sort) { - Iterable iterable = findAll(predicate, sort); - List result = new ArrayList<>(); - iterable.forEach(result::add); - return result; - } - - // 批量插入优化 - @Modifying - @Query(value = "INSERT INTO #{#entityName} (id, create_time, create_by) VALUES (:id, :createTime, :createBy)", - nativeQuery = true) - void batchInsert( - @Param("id") ID id, - @Param("createTime") LocalDateTime createTime, - @Param("createBy") String createBy - ); - - // 批量更新优化 - @Modifying - @Query("UPDATE #{#entityName} e SET e.updateTime = :updateTime, e.updateBy = :updateBy WHERE e.id IN :ids") - void batchUpdate( - @Param("ids") Collection ids, - @Param("updateTime") LocalDateTime updateTime, - @Param("updateBy") String updateBy - ); - - // 批量逻辑删除优化 - @Modifying - @Query("UPDATE #{#entityName} e SET e.deleted = true, e.updateTime = :updateTime, e.updateBy = :updateBy WHERE e.id IN :ids") - void batchLogicDelete( - @Param("ids") Collection ids, - @Param("updateTime") LocalDateTime updateTime, - @Param("updateBy") String updateBy - ); - - // 添加悲观锁查询 + // 乐观锁支持 @Lock(LockModeType.PESSIMISTIC_WRITE) @Query("SELECT e FROM #{#entityName} e WHERE e.id = :id AND e.deleted = false") Optional findByIdWithLock(@Param("id") ID id); - // 批量更新时添加版本控制 @Modifying @Query("UPDATE #{#entityName} e SET e.updateTime = :updateTime, " + - "e.updateBy = :updateBy, e.version = e.version + 1 " + - "WHERE e.id IN :ids AND e.version = :version") + "e.updateBy = :updateBy, e.version = e.version + 1 " + + "WHERE e.id IN :ids AND e.version = :version") int batchUpdateWithVersion( @Param("ids") Collection ids, @Param("updateTime") LocalDateTime updateTime, diff --git a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java index ca1f1c6c..eb6470fa 100644 --- a/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java +++ b/backend/src/main/java/com/qqchen/deploy/backend/framework/security/config/SecurityConfig.java @@ -23,7 +23,9 @@ import org.springframework.security.web.authentication.UsernamePasswordAuthentic public class SecurityConfig { private final CustomAuthenticationEntryPoint authenticationEntryPoint; + private final UserDetailsService userDetailsService; + private final JwtTokenUtil jwtTokenUtil; @Bean diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 05dfeb8e..0eebd610 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -13,7 +13,7 @@ spring: show-sql: true properties: hibernate: - format_sql: false + format_sql: true use_sql_comments: true dialect: org.hibernate.dialect.MySQL8Dialect jdbc: @@ -36,8 +36,10 @@ logging: org.springframework.web: DEBUG org.springframework.context.i18n: DEBUG org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping: TRACE - org.hibernate.type.descriptor.sql.BasicBinder: TRACE + org.hibernate.SQL: DEBUG org.hibernate.type.descriptor.sql: TRACE + org.hibernate.type.descriptor.sql.BasicBinder: TRACE + org.hibernate.orm.jdbc.bind: TRACE com.qqchen.deploy.backend.framework.utils.EntityPathResolver: DEBUG com.qqchen.deploy.backend: DEBUG jwt: