在Spring Data JPA存储库中,可以提供自定义方法的实现,从而完全控制查询和返回类型。具体步骤如下:
- 定义一个带有所需方法签名的接口。
- 实现该接口以实现所需行为。
- 使存储库同时扩展
JpaRepository
和自定义接口。
以下是一个使用JpaRepository
的工作示例,假设有一个包含两个列user_id
和user_name
的user_table
。
模型包中的UserEntity类:
@Entity
@Table(name = "user_table")
public class UserEntity {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
@Column(name = "user_id")
private Long userId;
@Column(name = "user_name")
private String userName;
protected UserEntity() {}
public UserEntity(String userName) {
this.userName = userName;
}
在存储库包中定义自定义存储库的接口:
public interface UserCustomRepository {
List<String> findUserNames();
}
在存储库包中提供自定义接口的实现类:
public class UserCustomRepositoryImpl implements UserCustomRepository {
JdbcTemplate jdbcTemplate;
@Autowired
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
@Override
public List<String> findUserNames() throws DataAccessException {
String sql = "SELECT user_name FROM user_table";
return jdbcTemplate.queryForList(sql, String.class);
}
}
最后,我们只需要让
UserRepository
同时扩展
JpaRepository
和我们刚刚实现的自定义接口即可。
public interface UserRepository extends JpaRepository<UserEntity, Long>, UserCustomRepository {}
使用JUnit 5编写的简单测试类(假设数据库最初为空):
@SpringBootTest
class UserRepositoryTest {
private static final String JANE = "Jane";
private static final String JOE = "Joe";
@Autowired
UserRepository repo;
@Test
void shouldFindUserNames() {
UserEntity jane = new UserEntity(JANE);
UserEntity joe = new UserEntity(JOE);
repo.saveAndFlush(jane);
repo.saveAndFlush(joe);
List<UserEntity> users = repo.findAll();
assertEquals(2, users.size());
List<String> names = repo.findUserNames();
assertEquals(2, names.size());
assertTrue(names.contains(JANE));
assertTrue(names.contains(JOE));
}
}