如何创建Doctrine自定义Repository实现指定记录查询?
Hey there! Let's get your record-by-name repository sorted out. I’ll walk you through the correct implementation steps, plus the common pitfalls that might have been tripping you up—using Spring Data JPA as the example since it’s the most common approach for this kind of task.
Make sure your entity class correctly maps to your MySQL table—this is a super common source of issues:
import jakarta.persistence.Entity; import jakarta.persistence.Id; import jakarta.persistence.Table; import jakarta.persistence.Column; @Entity @Table(name = "your_table_name") // Match this exactly to your MySQL table name public class YourEntity { @Id private Long id; // If your DB column name is different (e.g., "full_name"), use @Column to specify @Column(name = "name") private String name; // Don't forget constructors, getters, setters, and toString() methods public YourEntity() {} public YourEntity(Long id, String name) { this.id = id; this.name = name; } // Getters and setters here public String getName() { return name; } public void setName(String name) { this.name = name; } }
Spring Data JPA lets you build queries with simple method naming (no manual SQL needed most of the time):
import org.springframework.data.jpa.repository.JpaRepository; import java.util.Optional; // Avoids null pointer issues public interface YourEntityRepository extends JpaRepository<YourEntity, Long> { // Query for a single record by name (use Optional if the name might not exist) Optional<YourEntity> findByName(String name); // Optional: Ignore case when searching // Optional<YourEntity> findByNameIgnoreCase(String name); // If multiple records can have the same name, return a list instead // List<YourEntity> findAllByName(String name); }
If You Prefer Custom SQL
If you want to write explicit MySQL queries, use the @Query annotation:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; // Add these methods to your repository interface @Query("SELECT e FROM YourEntity e WHERE e.name = :targetName") Optional<YourEntity> findByNameCustom(@Param("targetName") String name); // Or use native MySQL syntax: @Query(value = "SELECT * FROM your_table_name WHERE name = :targetName", nativeQuery = true) Optional<YourEntity> findByNameNative(@Param("targetName") String name);
If your previous attempt failed, check these:
- Mismatched names: Your entity's
@Table/@Columnvalues don't match your actual MySQL table/column names (MySQL is case-sensitive on some systems like Linux). - Typos in method names: Double-check for mistakes like
findByNaeminstead offindByName. - Missing injection: Make sure you're properly injecting the repository into your service/controller (constructor injection is recommended over
@Autowired). - Ignoring duplicate records: If multiple rows have the same name, using
Optionalwill only return the first result—switch toList<YourEntity>instead. - Transaction issues: Add
@Transactional(readOnly = true)to your service methods for read operations to avoid unexpected errors.
Here's an example service class that uses the repository:
import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Optional; @Service public class YourEntityService { private final YourEntityRepository repository; // Constructor injection (recommended for safety) public YourEntityService(YourEntityRepository repository) { this.repository = repository; } @Transactional(readOnly = true) public Optional<YourEntity> getRecordByName(String name) { return repository.findByName(name); } }
内容的提问来源于stack exchange,提问作者Dialkord

