package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.jpa.domain.Specification;
import javax.persistence.criteria.Predicate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class UserSpecifications {
public static Specification<User> hasName(String name) {
return (root, query, cb) ->
name == null ? null : cb.like(cb.lower(root.get("name")),
"%" + name.toLowerCase() + "%");
}
public static Specification<User> hasEmail(String email) {
return (root, query, cb) ->
email == null ? null : cb.equal(root.get("email"), email);
}
public static Specification<User> isActive(Boolean active) {
return (root, query, cb) ->
active == null ? null : cb.equal(root.get("active"), active);
}
public static Specification<User> createdBetween(
LocalDateTime start,
LocalDateTime end
) {
return (root, query, cb) -> {
if (start == null && end == null) return null;
if (start == null) return cb.lessThanOrEqualTo(root.get("createdAt"), end);
if (end == null) return cb.greaterThanOrEqualTo(root.get("createdAt"), start);
return cb.between(root.get("createdAt"), start, end);
};
}
public static Specification<User> buildDynamicQuery(
String name,
String email,
Boolean active,
LocalDateTime startDate,
LocalDateTime endDate
) {
return (root, query, cb) -> {
List<Predicate> predicates = new ArrayList<>();
if (name != null && !name.isEmpty()) {
predicates.add(cb.like(cb.lower(root.get("name")),
"%" + name.toLowerCase() + "%"));
}
if (email != null && !email.isEmpty()) {
predicates.add(cb.equal(root.get("email"), email));
}
if (active != null) {
predicates.add(cb.equal(root.get("active"), active));
}
if (startDate != null) {
predicates.add(cb.greaterThanOrEqualTo(
root.get("createdAt"), startDate));
}
if (endDate != null) {
predicates.add(cb.lessThanOrEqualTo(
root.get("createdAt"), endDate));
}
return cb.and(predicates.toArray(new Predicate[0]));
};
}
}
// Usage:
// Page<User> results = userRepository.findAll(
// Specification.where(UserSpecifications.hasName("John"))
// .and(UserSpecifications.isActive(true)),
// PageRequest.of(0, 20, Sort.by("createdAt").descending())
// );
package com.example.demo.repository;
import com.example.demo.model.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;
@Repository
public interface UserRepository extends JpaRepository<User, Long>,
JpaSpecificationExecutor<User> {
// Query method - derived from method name
Optional<User> findByEmail(String email);
List<User> findByNameContainingIgnoreCase(String name);
List<User> findByCreatedAtBetween(LocalDateTime start, LocalDateTime end);
boolean existsByEmail(String email);
long countByActiveTrue();
// Custom JPQL query
@Query("SELECT u FROM User u WHERE u.email = :email AND u.active = true")
Optional<User> findActiveUserByEmail(@Param("email") String email);
// JPQL with pagination
@Query("SELECT u FROM User u WHERE u.name LIKE %:keyword%")
Page<User> searchByKeyword(@Param("keyword") String keyword, Pageable pageable);
// Native SQL query
@Query(value = "SELECT * FROM users WHERE created_at > :date", nativeQuery = true)
List<User> findUsersCreatedAfter(@Param("date") LocalDateTime date);
// Projection - returns only specific fields
@Query("SELECT u.name as name, u.email as email FROM User u")
List<UserProjection> findAllUserProjections();
// Custom update query
@Query("UPDATE User u SET u.active = :active WHERE u.id = :id")
void updateActiveStatus(@Param("id") Long id, @Param("active") boolean active);
interface UserProjection {
String getName();
String getEmail();
}
}
Spring Data JPA eliminates boilerplate DAO code with repository interfaces. I extend JpaRepository to get CRUD methods automatically—save, findById, findAll, delete. Custom query methods use method naming conventions—findByEmailAndActiveTrue generates queries from method names. @Query annotation defines JPQL or native SQL for complex queries. Pagination uses Pageable parameter and returns Page objects. Specifications enable dynamic queries with Criteria API. @EntityGraph optimizes fetching related entities, solving N+1 query problems. Projections return subsets of entity fields via interfaces. Transactions are managed declaratively with @Transactional. Auditing tracks creation and modification timestamps automatically. Spring Data JPA reduces database access code by 70% while maintaining flexibility for complex scenarios.
Related snips
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
createdAt: String!
GraphQL API with Spring Boot
# Vulnerable: user input is concatenated directly into SQL.
email = params[:email]
password = params[:password]
sql = "SELECT * FROM users WHERE email = '#{email}' AND password_hash = '#{password}'"
user = ActiveRecord::Base.connection.execute(sql).first
SQL injection prevention with unsafe and safe query patterns
package com.example.starter.config;
import com.example.starter.properties.CustomProperties;
import com.example.starter.service.CustomService;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
Custom Spring Boot starters
-- EXPLAIN ANALYZE (actual execution statistics)
EXPLAIN ANALYZE
SELECT u.username, COUNT(o.id) AS order_count
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.created_at >= '2024-01-01'
Advanced query optimization techniques
from django.db.models import Count, Avg, Sum, Q, F
from django.views.generic import TemplateView
from products.models import Product, Order, OrderItem
class DashboardView(TemplateView):
Django aggregation with annotate for statistics
package com.example.demo.config;
import org.apache.kafka.clients.consumer.ConsumerConfig;
import org.apache.kafka.clients.producer.ProducerConfig;
import org.apache.kafka.common.serialization.StringDeserializer;
import org.apache.kafka.common.serialization.StringSerializer;
Messaging with Apache Kafka
Share this code
Here's the card — post it anywhere.