Java Framework Protection Mechanisms
Java Framework Protection Mechanisms
Java's strong typing and enterprise frameworks provide robust SQL injection defenses:
// Spring Data JPA - Repository pattern with automatic security
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Method name queries - automatically safe
List<User> findByStatusAndCreatedAfter(String status, LocalDateTime date);
// JPQL with named parameters
@Query("SELECT u FROM User u WHERE u.email LIKE %:email% AND u.role IN :roles")
List<User> searchUsers(@Param("email") String email, @Param("roles") List<String> roles);
// Native SQL with indexed parameters
@Query(value = "SELECT * FROM users WHERE department_id = ?1 AND salary > ?2",
nativeQuery = true)
List<User> findByDepartmentAndSalary(Long departmentId, BigDecimal minSalary);
// Complex dynamic queries using Specifications
default List<User> findByComplexCriteria(UserSearchCriteria criteria) {
return findAll((root, query, criteriaBuilder) -> {
List<Predicate> predicates = new ArrayList<>();
if (criteria.getName() != null) {
predicates.add(criteriaBuilder.like(
root.get("name"),
"%" + criteria.getName() + "%"
));
}
if (criteria.getMinAge() != null) {
predicates.add(criteriaBuilder.greaterThanOrEqualTo(
root.get("age"),
criteria.getMinAge()
));
}
if (criteria.getRoles() != null && !criteria.getRoles().isEmpty()) {
predicates.add(root.get("role").in(criteria.getRoles()));
}
return criteriaBuilder.and(predicates.toArray(new Predicate[0]));
});
}
}
// MyBatis with type-safe queries
@Mapper
public interface ProductMapper {
// Automatic parameter binding with #{} syntax
@Select("SELECT * FROM products WHERE category_id = #{categoryId} AND price > #{minPrice}")
List<Product> findByCategoryAndPrice(@Param("categoryId") Long categoryId,
@Param("minPrice") BigDecimal minPrice);
// Dynamic SQL with safety
@SelectProvider(type = ProductSqlProvider.class, method = "buildFindByExample")
List<Product> findByExample(ProductExample example);
}
public class ProductSqlProvider {
public String buildFindByExample(ProductExample example) {
return new SQL() {{
SELECT("*");
FROM("products");
if (example.getName() != null) {
WHERE("name LIKE #{name}");
}
if (example.getMinPrice() != null) {
WHERE("price >= #{minPrice}");
}
if (example.getCategories() != null && !example.getCategories().isEmpty()) {
WHERE("category_id IN (" +
example.getCategories().stream()
.map(c -> "#{categories[" + example.getCategories().indexOf(c) + "]}")
.collect(Collectors.joining(",")) +
")");
}
ORDER_BY("created_at DESC");
}}.toString();
}
}