JPA-自定義實現
常用實現
在springdata JPA 的使用過程我們通常是通過在接口中定義方法,
public interface BookCurdRepository extends CrudRepository <Book, Long>{
/**
* 通過書名查找書
* @param name
* @return
*/
Book findBookByName(String name);
}
其次復雜一點的就是通過@Query注解來實現
/**
* 更新名稱和作者信息
* @param name
* @param author
* @param id
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@Query("update Book set name = ?1,author = ?2 where id = ?3")
void updateNameAndAuthorById(String name,String author,long id);
自定義實現
在大多數的情況瞎,這兩種方式是可以滿足我們的需求,但是如果存在更加復雜的需要呢?可能在這個時候我們會吐槽沒有mybaties那么靈活了,在Jpa中也可以實現的,我們可以通過自定義的方式來進行實現
1、創建自定義的接口
public interface BookCustomRepository {
/**
* 查詢所有書列表
* @return
*/
List<Book> listBook();
}
2、自定接口實現
@Repository
public class BookCustomRepositoryImpl implements BookCustomRepository {
@Autowired
private JdbcTemplate jdbcTemplate;
@Override
public List<Book> listBook() {
//在這里就可以自由發揮了,可以根據自己需求來實現
String sql = "select * from book";
BeanPropertyRowMapper<Book> rowMapper = new BeanPropertyRowMapper<>(Book.class);
List<Book> bookList = jdbcTemplate.query(sql, rowMapper);
return bookList;
}
}
3、繼承自定接口
/**
* @Description:
* @Author: JackQ
* @CreateDate: 2020/6/22 11:06
*/
@Repository
public interface BookRepository extends org.springframework.data.repository.Repository<Book,Long>, BookCustomRepository {
/**
* 通過書名查找書
*
* @param name
* @return
*/
Book findBookByName(String name);
/**
* 更新名稱和作者信息
* @param name
* @param author
* @param id
*/
@Transactional(rollbackFor = Exception.class)
@Modifying
@Query("update Book set name = ?1,author = ?2 where id = ?3")
void updateNameAndAuthorById(String name,String author,long id);
}
4、測試,在其他的地方就可以調用自定方法中的實現了
@Test
public void listBooks(){
List<Book> books = bookService.listBooks();
books.stream().forEach(book -> System.out.println(book.toString()));
}
//結果
//Book(id=1, name=平凡的世界, price=30.2, author=路遙)
//Book(id=2, name=人生, price=60.0, author=路遙)
//Book(id=3, name=情書, price=38.0, author=岩井俊二)
自定義實現優先級別
在一個repository中可能存在繼承多個接口,那么就可能存在相同的實現方法;自定義 implementations 的優先級高於基本 implementation 和 repository 方面。如果兩個片段提供相同的方法簽名,則此 ordering 允許您覆蓋 base repository 和 aspect 方法並解決歧義。 Repository 片段不限於在單個 repository 接口中使用。多個 repositories 可以使用片段接口,讓您可以跨不同的 repositories 重用自定義。
interface CustomizedSave<T> {
<S extends T> S save(S entity);
}
class CustomizedSaveImpl<T> implements CustomizedSave<T> {
public <S extends T> S save(S entity) {
// Your custom implementation
}
}