Spring Data 2027 动态查询功能及实践

 更新时间:2026年04月28日 09:34:12   作者:程序员鸭梨  
文章主要介绍了SpringData2027中的动态查询功能,包括QueryByExample、Specification、QueryDSL、CriteriaAPI和动态JPQL等实现方式,文章详细阐述了每种方式的原理、实践方法及应用场景,并提供了优化性能、监控调试和最佳实践的建议,最后展望了该功能未来的发展趋势

Spring Data 2027 带来了强大的动态查询功能,让开发者能够更灵活地构建复杂的查询语句。动态查询是一种根据运行时条件构建查询的能力,它在处理复杂的业务场景时非常有用。本文将详细介绍 Spring Data 2027 中的动态查询功能及其实践。

1. 动态查询概述

1.1 什么是动态查询?

动态查询是指在运行时根据不同的条件动态构建查询语句的过程。与静态查询不同,动态查询的条件和结构可以根据用户输入、业务逻辑或其他因素在运行时发生变化。

在 Spring Data 中,动态查询通常用于以下场景:

  • 多条件搜索:用户可以根据多个条件组合进行搜索
  • 复杂过滤:根据不同的业务规则进行复杂的过滤
  • 动态排序:根据用户选择的字段进行排序
  • 条件聚合:根据不同的条件进行数据聚合

1.2 Spring Data 2027 的动态查询支持

Spring Data 2027 提供了多种动态查询的实现方式:

  • Query By Example (QBE):基于示例对象构建查询
  • Specification:使用 JPA Criteria API 构建复杂查询
  • QueryDSL:使用类型安全的查询构建器
  • Criteria API:直接使用 JPA Criteria API
  • 动态 JPQL:运行时构建 JPQL 查询

2. Query By Example (QBE)

2.1 原理

Query By Example 是一种简单直观的动态查询方式,它允许开发者通过创建一个示例对象来构建查询。Spring Data 会根据示例对象的非空属性生成查询条件。

2.2 实践

使用 Query By Example 实现动态查询:

// 实体类
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String email;
    private int age;
    private String department;
    // getters and setters
}
// Repository 接口
public interface UserRepository extends JpaRepository<User, Long>, QueryByExampleExecutor<User> {
}
// 服务层
@Service
public class UserService {
    private final UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public List<User> searchUsers(String name, String email, Integer age, String department) {
        // 创建示例对象
        User user = new User();
        if (name != null) {
            user.setName(name);
        }
        if (email != null) {
            user.setEmail(email);
        }
        if (age != null) {
            user.setAge(age);
        }
        if (department != null) {
            user.setDepartment(department);
        }
        // 创建 Example 对象
        Example<User> example = Example.of(user);
        // 执行查询
        return userRepository.findAll(example);
    }
    public List<User> searchUsersWithMatcher(String name, String email) {
        // 创建示例对象
        User user = new User();
        if (name != null) {
            user.setName(name);
        }
        if (email != null) {
            user.setEmail(email);
        }
        // 创建匹配器
        ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreCase() // 忽略大小写
            .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING); // 包含匹配
        // 创建 Example 对象
        Example<User> example = Example.of(user, matcher);
        // 执行查询
        return userRepository.findAll(example);
    }
}

3. Specification

3.1 原理

Specification 是 Spring Data JPA 提供的一种更灵活的动态查询方式,它基于 JPA Criteria API 构建查询。通过实现 Specification 接口,开发者可以构建复杂的查询条件。

3.2 实践

使用 Specification 实现动态查询:

// Repository 接口
public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
}
// Specification 工具类
public class UserSpecifications {
    public static Specification<User> hasName(String name) {
        return (root, query, criteriaBuilder) -> {
            if (name == null) {
                return null;
            }
            return criteriaBuilder.like(root.get("name"), "%" + name + "%");
        };
    }
    public static Specification<User> hasEmail(String email) {
        return (root, query, criteriaBuilder) -> {
            if (email == null) {
                return null;
            }
            return criteriaBuilder.like(root.get("email"), "%" + email + "%");
        };
    }
    public static Specification<User> hasAgeGreaterThan(Integer age) {
        return (root, query, criteriaBuilder) -> {
            if (age == null) {
                return null;
            }
            return criteriaBuilder.greaterThan(root.get("age"), age);
        };
    }
    public static Specification<User> hasDepartment(String department) {
        return (root, query, criteriaBuilder) -> {
            if (department == null) {
                return null;
            }
            return criteriaBuilder.equal(root.get("department"), department);
        };
    }
}
// 服务层
@Service
public class UserService {
    private final UserRepository userRepository;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public List<User> searchUsers(String name, String email, Integer age, String department) {
        Specification<User> spec = Specification.where(UserSpecifications.hasName(name))
            .and(UserSpecifications.hasEmail(email))
            .and(UserSpecifications.hasAgeGreaterThan(age))
            .and(UserSpecifications.hasDepartment(department));
        return userRepository.findAll(spec);
    }
    public List<User> searchUsersWithSorting(String name, String email, String sortBy, Sort.Direction direction) {
        Specification<User> spec = Specification.where(UserSpecifications.hasName(name))
            .and(UserSpecifications.hasEmail(email));
        Sort sort = Sort.by(direction, sortBy);
        return userRepository.findAll(spec, sort);
    }
}

4. QueryDSL

4.1 原理

QueryDSL 是一种类型安全的查询构建器,它可以生成类型安全的查询代码。Spring Data 2027 对 QueryDSL 提供了很好的支持,使得开发者可以更安全、更直观地构建查询。

4.2 实践

使用 QueryDSL 实现动态查询:

// 1. 添加依赖
// <dependency>
//     <groupId>com.querydsl</groupId>
//     <artifactId>querydsl-jpa</artifactId>
//     <version>5.0.0</version>
// </dependency>
// <dependency>
//     <groupId>com.querydsl</groupId>
//     <artifactId>querydsl-apt</artifactId>
//     <version>5.0.0</version>
//     <scope>provided</scope>
// </dependency>
// 2. 生成 Q 类
// 运行 mvn compile 生成 QUser 类
// 3. Repository 接口
public interface UserRepository extends JpaRepository<User, Long>, QuerydslPredicateExecutor<User> {
}
// 服务层
@Service
public class UserService {
    private final UserRepository userRepository;
    private final QUser qUser = QUser.user;
    @Autowired
    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }
    public List<User> searchUsers(String name, String email, Integer age, String department) {
        BooleanBuilder builder = new BooleanBuilder();
        if (name != null) {
            builder.and(qUser.name.containsIgnoreCase(name));
        }
        if (email != null) {
            builder.and(qUser.email.containsIgnoreCase(email));
        }
        if (age != null) {
            builder.and(qUser.age.gt(age));
        }
        if (department != null) {
            builder.and(qUser.department.eq(department));
        }
        return userRepository.findAll(builder);
    }
    public List<User> searchUsersWithSorting(String name, String email, String sortBy, Direction direction) {
        BooleanBuilder builder = new BooleanBuilder();
        if (name != null) {
            builder.and(qUser.name.containsIgnoreCase(name));
        }
        if (email != null) {
            builder.and(qUser.email.containsIgnoreCase(email));
        }
        // 动态排序
        PathBuilder<User> pathBuilder = new PathBuilder<>(User.class, "user");
        OrderSpecifier<?> orderSpecifier;
        if (direction == Direction.ASC) {
            orderSpecifier = pathBuilder.getString(sortBy).asc();
        } else {
            orderSpecifier = pathBuilder.getString(sortBy).desc();
        }
        return userRepository.findAll(builder, orderSpecifier);
    }
}

5. Criteria API

5.1 原理

JPA Criteria API 是一种编程式的查询构建方式,它允许开发者通过代码构建查询,而不是使用字符串形式的 JPQL。Spring Data 2027 支持直接使用 Criteria API 构建动态查询。

5.2 实践

使用 Criteria API 实现动态查询:

// 服务层
@Service
public class UserService {
    private final EntityManager entityManager;
    @Autowired
    public UserService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    public List<User> searchUsers(String name, String email, Integer age, String department) {
        // 创建 CriteriaBuilder
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        // 创建 CriteriaQuery
        CriteriaQuery<User> cq = cb.createQuery(User.class);
        // 创建 Root
        Root<User> root = cq.from(User.class);
        // 构建查询条件
        List<Predicate> predicates = new ArrayList<>();
        if (name != null) {
            predicates.add(cb.like(root.get("name"), "%" + name + "%"));
        }
        if (email != null) {
            predicates.add(cb.like(root.get("email"), "%" + email + "%"));
        }
        if (age != null) {
            predicates.add(cb.greaterThan(root.get("age"), age));
        }
        if (department != null) {
            predicates.add(cb.equal(root.get("department"), department));
        }
        // 添加查询条件
        if (!predicates.isEmpty()) {
            cq.where(cb.and(predicates.toArray(new Predicate[0])));
        }
        // 执行查询
        TypedQuery<User> query = entityManager.createQuery(cq);
        return query.getResultList();
    }
    public List<User> searchUsersWithSorting(String name, String email, String sortBy, Sort.Direction direction) {
        // 创建 CriteriaBuilder
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        // 创建 CriteriaQuery
        CriteriaQuery<User> cq = cb.createQuery(User.class);
        // 创建 Root
        Root<User> root = cq.from(User.class);
        // 构建查询条件
        List<Predicate> predicates = new ArrayList<>();
        if (name != null) {
            predicates.add(cb.like(root.get("name"), "%" + name + "%"));
        }
        if (email != null) {
            predicates.add(cb.like(root.get("email"), "%" + email + "%"));
        }
        // 添加查询条件
        if (!predicates.isEmpty()) {
            cq.where(cb.and(predicates.toArray(new Predicate[0])));
        }
        // 添加排序
        if (sortBy != null) {
            if (direction == Sort.Direction.ASC) {
                cq.orderBy(cb.asc(root.get(sortBy)));
            } else {
                cq.orderBy(cb.desc(root.get(sortBy)));
            }
        }
        // 执行查询
        TypedQuery<User> query = entityManager.createQuery(cq);
        return query.getResultList();
    }
}

6. 动态 JPQL

6.1 原理

动态 JPQL 是指在运行时根据条件动态构建 JPQL 查询语句。这种方式虽然灵活,但需要注意 SQL 注入的风险。

6.2 实践

使用动态 JPQL 实现动态查询:

// 服务层
@Service
public class UserService {
    private final EntityManager entityManager;
    @Autowired
    public UserService(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    public List<User> searchUsers(String name, String email, Integer age, String department) {
        // 构建 JPQL 查询
        StringBuilder jpql = new StringBuilder("SELECT u FROM User u WHERE 1=1");
        List<Object> parameters = new ArrayList<>();
        int paramIndex = 1;
        if (name != null) {
            jpql.append(" AND u.name LIKE ?").append(paramIndex++);
            parameters.add("%" + name + "%");
        }
        if (email != null) {
            jpql.append(" AND u.email LIKE ?").append(paramIndex++);
            parameters.add("%" + email + "%");
        }
        if (age != null) {
            jpql.append(" AND u.age > ?").append(paramIndex++);
            parameters.add(age);
        }
        if (department != null) {
            jpql.append(" AND u.department = ?").append(paramIndex++);
            parameters.add(department);
        }
        // 创建查询
        TypedQuery<User> query = entityManager.createQuery(jpql.toString(), User.class);
        // 设置参数
        for (int i = 0; i < parameters.size(); i++) {
            query.setParameter(i + 1, parameters.get(i));
        }
        // 执行查询
        return query.getResultList();
    }
    public List<User> searchUsersWithSorting(String name, String email, String sortBy, Sort.Direction direction) {
        // 构建 JPQL 查询
        StringBuilder jpql = new StringBuilder("SELECT u FROM User u WHERE 1=1");
        List<Object> parameters = new ArrayList<>();
        int paramIndex = 1;
        if (name != null) {
            jpql.append(" AND u.name LIKE ?").append(paramIndex++);
            parameters.add("%" + name + "%");
        }
        if (email != null) {
            jpql.append(" AND u.email LIKE ?").append(paramIndex++);
            parameters.add("%" + email + "%");
        }
        // 添加排序
        if (sortBy != null) {
            jpql.append(" ORDER BY u.").append(sortBy);
            if (direction == Sort.Direction.DESC) {
                jpql.append(" DESC");
            } else {
                jpql.append(" ASC");
            }
        }
        // 创建查询
        TypedQuery<User> query = entityManager.createQuery(jpql.toString(), User.class);
        // 设置参数
        for (int i = 0; i < parameters.size(); i++) {
            query.setParameter(i + 1, parameters.get(i));
        }
        // 执行查询
        return query.getResultList();
    }
}

7. 综合实践

7.1 组合使用多种动态查询方式

在实际应用中,我们可以根据具体场景选择合适的动态查询方式,甚至组合使用多种方式:

@Service
public class UserService {
    private final UserRepository userRepository;
    private final EntityManager entityManager;
    private final QUser qUser = QUser.user;
    @Autowired
    public UserService(UserRepository userRepository, EntityManager entityManager) {
        this.userRepository = userRepository;
        this.entityManager = entityManager;
    }
    // 使用 Query By Example
    public List<User> searchUsersByExample(String name, String email) {
        User user = new User();
        if (name != null) {
            user.setName(name);
        }
        if (email != null) {
            user.setEmail(email);
        }
        ExampleMatcher matcher = ExampleMatcher.matching()
            .withIgnoreCase()
            .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
        Example<User> example = Example.of(user, matcher);
        return userRepository.findAll(example);
    }
    // 使用 Specification
    public List<User> searchUsersBySpecification(String name, Integer age) {
        Specification<User> spec = Specification.where(UserSpecifications.hasName(name))
            .and(UserSpecifications.hasAgeGreaterThan(age));
        return userRepository.findAll(spec);
    }
    // 使用 QueryDSL
    public List<User> searchUsersByQueryDSL(String name, String department) {
        BooleanBuilder builder = new BooleanBuilder();
        if (name != null) {
            builder.and(qUser.name.containsIgnoreCase(name));
        }
        if (department != null) {
            builder.and(qUser.department.eq(department));
        }
        return userRepository.findAll(builder);
    }
    // 使用 Criteria API
    public List<User> searchUsersByCriteriaAPI(String email, Integer age) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<User> cq = cb.createQuery(User.class);
        Root<User> root = cq.from(User.class);
        List<Predicate> predicates = new ArrayList<>();
        if (email != null) {
            predicates.add(cb.like(root.get("email"), "%" + email + "%"));
        }
        if (age != null) {
            predicates.add(cb.greaterThan(root.get("age"), age));
        }
        if (!predicates.isEmpty()) {
            cq.where(cb.and(predicates.toArray(new Predicate[0])));
        }
        TypedQuery<User> query = entityManager.createQuery(cq);
        return query.getResultList();
    }
}

7.2 实际应用场景

7.2.1 电商系统

在电商系统中,动态查询可以用于商品搜索:

@Service
public class ProductService {
    private final ProductRepository productRepository;
    private final QProduct qProduct = QProduct.product;
    @Autowired
    public ProductService(ProductRepository productRepository) {
        this.productRepository = productRepository;
    }
    public List<Product> searchProducts(String name, BigDecimal minPrice, BigDecimal maxPrice, 
                                       String category, String brand, Sort.Direction direction) {
        BooleanBuilder builder = new BooleanBuilder();
        if (name != null) {
            builder.and(qProduct.name.containsIgnoreCase(name));
        }
        if (minPrice != null) {
            builder.and(qProduct.price.goe(minPrice));
        }
        if (maxPrice != null) {
            builder.and(qProduct.price.loe(maxPrice));
        }
        if (category != null) {
            builder.and(qProduct.category.eq(category));
        }
        if (brand != null) {
            builder.and(qProduct.brand.eq(brand));
        }
        // 排序
        OrderSpecifier<?> orderSpecifier;
        if (direction == Sort.Direction.ASC) {
            orderSpecifier = qProduct.price.asc();
        } else {
            orderSpecifier = qProduct.price.desc();
        }
        return productRepository.findAll(builder, orderSpecifier);
    }
}

7.2.2 人力资源系统

在人力资源系统中,动态查询可以用于员工信息查询:

@Service
public class EmployeeService {
    private final EmployeeRepository employeeRepository;
    @Autowired
    public EmployeeService(EmployeeRepository employeeRepository) {
        this.employeeRepository = employeeRepository;
    }
    public List<Employee> searchEmployees(String name, String department, 
                                         LocalDate startDateFrom, LocalDate startDateTo, 
                                         Integer minSalary, Integer maxSalary) {
        Specification<Employee> spec = Specification.where(EmployeeSpecifications.hasName(name))
            .and(EmployeeSpecifications.hasDepartment(department))
            .and(EmployeeSpecifications.hasStartDateBetween(startDateFrom, startDateTo))
            .and(EmployeeSpecifications.hasSalaryBetween(minSalary, maxSalary));
        return employeeRepository.findAll(spec);
    }
}

8. 性能优化

8.1 动态查询性能优化

  • 使用索引:为经常用于查询的字段创建索引
  • 限制结果集:使用分页和限制返回的记录数
  • 优化查询条件:避免使用复杂的查询条件,特别是在大型表上
  • 使用缓存:对于频繁执行的查询结果进行缓存
  • 批量操作:对于批量查询,使用批量操作减少数据库交互

8.2 代码示例

// 使用分页
public Page<User> searchUsersWithPagination(String name, String email, Pageable pageable) {
    Specification<User> spec = Specification.where(UserSpecifications.hasName(name))
        .and(UserSpecifications.hasEmail(email));
    return userRepository.findAll(spec, pageable);
}
// 使用缓存
@Cacheable(value = "users", key = "#name + #email")
public List<User> searchUsersWithCache(String name, String email) {
    Example<User> example = Example.of(new User(name, email));
    return userRepository.findAll(example);
}
// 批量查询
public List<User> batchSearchUsers(List<Long> ids) {
    return userRepository.findAllById(ids);
}

9. 监控与调试

9.1 监控动态查询

使用 Spring Boot Actuator 监控动态查询的执行情况:

@RestController
@RequestMapping("/actuator/queries")
public class QueryActuatorController {
    private final EntityManager entityManager;
    @Autowired
    public QueryActuatorController(EntityManager entityManager) {
        this.entityManager = entityManager;
    }
    @GetMapping("/statistics")
    public Map<String, Object> getQueryStatistics() {
        Map<String, Object> stats = new HashMap<>();
        // 获取查询执行统计信息
        Session session = entityManager.unwrap(Session.class);
        Statistics statistics = session.getSessionFactory().getStatistics();
        stats.put("queryCount", statistics.getQueryExecutionCount());
        stats.put("queryExecutionTime", statistics.getQueryExecutionTotalTime());
        stats.put("entityLoadCount", statistics.getEntityLoadCount());
        stats.put("collectionLoadCount", statistics.getCollectionLoadCount());
        return stats;
    }
}

9.2 调试动态查询

调试动态查询的技巧:

  • 启用 SQL 日志:在 application.properties 中设置 spring.jpa.show-sql=true
  • 使用 QueryLog:使用 Hibernate 的 QueryLog 记录查询执行情况
  • 使用断点:在查询构建过程中设置断点,查看生成的查询语句
  • 使用数据库工具:使用数据库工具(如 MySQL Workbench)分析查询执行计划

10. 最佳实践

10.1 选择合适的动态查询方式

场景推荐方式原因
简单条件查询Query By Example简单直观,代码量少
复杂条件查询Specification 或 QueryDSL更灵活,支持复杂条件
类型安全查询QueryDSL编译时检查,避免拼写错误
原生 SQL 查询动态 JPQL 或 Criteria API支持复杂的原生 SQL 功能

10.2 代码最佳实践

// 最佳实践 1:使用工厂方法创建查询条件
public class UserQueryBuilder {
    public static Specification<User> buildQuery(String name, String email, Integer age, String department) {
        return Specification.where(hasName(name))
            .and(hasEmail(email))
            .and(hasAgeGreaterThan(age))
            .and(hasDepartment(department));
    }
    private static Specification<User> hasName(String name) {
        return (root, query, cb) -> name != null ? cb.like(root.get("name"), "%" + name + "%") : null;
    }
    // 其他条件方法...
}
// 最佳实践 2:使用建造者模式构建查询
public class QueryBuilder<T> {
    private final Class<T> entityClass;
    private final List<Predicate> predicates = new ArrayList<>();
    private final CriteriaBuilder cb;
    private final CriteriaQuery<T> cq;
    private final Root<T> root;
    public QueryBuilder(EntityManager entityManager, Class<T> entityClass) {
        this.entityClass = entityClass;
        this.cb = entityManager.getCriteriaBuilder();
        this.cq = cb.createQuery(entityClass);
        this.root = cq.from(entityClass);
    }
    public QueryBuilder<T> eq(String field, Object value) {
        if (value != null) {
            predicates.add(cb.equal(root.get(field), value));
        }
        return this;
    }
    public QueryBuilder<T> like(String field, String value) {
        if (value != null) {
            predicates.add(cb.like(root.get(field), "%" + value + "%"));
        }
        return this;
    }
    public QueryBuilder<T> gt(String field, Comparable value) {
        if (value != null) {
            predicates.add(cb.greaterThan(root.get(field), value));
        }
        return this;
    }
    public List<T> build(EntityManager entityManager) {
        if (!predicates.isEmpty()) {
            cq.where(cb.and(predicates.toArray(new Predicate[0])));
        }
        return entityManager.createQuery(cq).getResultList();
    }
}
// 最佳实践 3:使用方法引用和 lambda 表达式
public List<User> searchUsers(String name, String email) {
    return userRepository.findAll((root, query, cb) -> {
        List<Predicate> predicates = new ArrayList<>();
        if (name != null) {
            predicates.add(cb.like(root.get("name"), "%" + name + "%"));
        }
        if (email != null) {
            predicates.add(cb.like(root.get("email"), "%" + email + "%"));
        }
        return predicates.isEmpty() ? null : cb.and(predicates.toArray(new Predicate[0]));
    });
}

这其实可以更优雅一点

Spring Data 2027 的动态查询功能,让数据查询变得更加优雅:

  1. 代码更简洁:使用声明式的方式构建查询
  2. 类型更安全:QueryDSL 提供编译时类型检查
  3. 灵活性更高:支持复杂的查询条件
  4. 可维护性更好:清晰的代码结构和逻辑
  5. 性能更优:优化的查询执行

11. 未来发展趋势

Spring Data 2027 的动态查询功能正在不断演进:

  • 更智能的查询构建:基于 AI 的智能查询构建
  • 更强大的类型安全:增强的 QueryDSL 功能
  • 更高效的查询执行:优化的查询执行计划
  • 更丰富的查询功能:支持更多的查询类型和操作
  • 更集成的生态系统:与其他 Spring 生态系统组件的深度集成

12. 总结

Spring Data 2027 的动态查询功能是构建灵活、高效数据访问层的关键。通过合理选择和使用 Query By Example、Specification、QueryDSL、Criteria API 和动态 JPQL 等方式,我们可以:

  • 构建复杂的查询条件:满足各种业务场景的需求
  • 提高代码的可维护性:清晰的代码结构和逻辑
  • 增强系统的性能:优化的查询执行
  • 减少开发工作量:简化查询构建的过程

记住,选择合适的动态查询方式取决于具体的业务场景和需求。在实际应用中,我们应该根据查询的复杂度、性能要求和代码可维护性等因素,选择最适合的动态查询方式。

到此这篇关于Spring Data 2027 动态查询功能及实践的文章就介绍到这了,更多相关Spring Data 动态查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 如何使用Sentry 监控你的Spring Boot应用

    如何使用Sentry 监控你的Spring Boot应用

    这篇文章主要介绍了如何使用Sentry 监控你的Spring Boot应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Redis工具类封装RedisUtils的使用示例

    Redis工具类封装RedisUtils的使用示例

    本文主要介绍了Redis工具类封装RedisUtils的使用示例,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • java8中新的Date和Time详解

    java8中新的Date和Time详解

    这篇文章主要是java8中新的Date和Time,探讨新Date类和Time类背后的设计原则,有所需要的小伙伴希望能帮助到你
    2016-07-07
  • SpringMVC源码之HandlerMapping处理器映射器解析

    SpringMVC源码之HandlerMapping处理器映射器解析

    这篇文章主要介绍了SpringMVC源码之HandlerMapping处理器映射器解析,在Spring MVC中,HandlerMapping处理器映射器用于确定请求处理器对象,请求处理器可以是任何对象,只要它们使用了@Controller注解或注解@RequestMapping,需要的朋友可以参考下
    2023-08-08
  • Spring MVC中的常用注解及用法小结

    Spring MVC中的常用注解及用法小结

    这篇文章主要介绍了Spring MVC中的常用注解及其用法,本文通过实例代码给大家介绍的非常详细,需要的朋友可以参考下
    2024-02-02
  • 一文详解Java如何创建和销毁对象

    一文详解Java如何创建和销毁对象

    Java由Sun Microsystems发明并在1995年发布,是世界上使用最广泛的编程语言之一。本文主要和大家介绍一下Java是如何创建和销毁对象的,希望对大家有所帮助
    2022-11-11
  • SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表

    SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表

    本文主要介绍了SpringBoot+MybatisPlus+Mysql+Sharding-JDBC分库分表,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • java异常和错误类总结(必看篇)

    java异常和错误类总结(必看篇)

    下面小编就为大家带来一篇java异常和错误类总结(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-09-09
  • JDK动态代理接口和接口实现类深入详解

    JDK动态代理接口和接口实现类深入详解

    这篇文章主要介绍了JDK动态代理接口和接口实现类,JDK动态代理是代理模式的一种实现方式,因为它是基于接口来做代理的,所以也常被称为接口代理,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-06-06
  • 详解Spring 拦截器流程及多个拦截器的执行顺序

    详解Spring 拦截器流程及多个拦截器的执行顺序

    这篇文章主要介绍了Spring 拦截器流程及多个拦截器的执行顺序的相关资料,帮助大家更好的理解和学习使用Spring框架,感兴趣的朋友可以了解下
    2021-05-05

最新评论