上一篇咱們瞭解瞭如何使用JdbcTemplate操做mysql數據庫,可是在實際開發過程當中絕大多數對數據庫的操做無非就是「增刪改查」,不少SQL語句都相似,兒開發人員還不得不一遍一遍的寫重複的代碼,爲了解決這種問題,咱們用到了ORM框架,下面介紹一下Spring-data-jpa的一些簡單使用。java
Spring Data JPA是在Spring JPA的基礎上,對持久層作了簡化。用戶只需聲明持久層的接口,不須要實現該接口。Spring Data JPA內部會根據不一樣的策略、經過不一樣的方法建立Query操做數據庫。mysql
Spring Data JPA自己已經抽象出了不少數據操做的接口,咱們只須要建立一個接口並集成Spring Data JPA中的接口便可完成數據表的增刪改查操做。以下圖,咱們只繼承了JpaRepository接口,便可完成對book表的基本的增刪改查操做。spring
public interface BookRepository extends JpaRepository<Book,Long> { }
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/restful?useUnicode=true&characterEncoding=UTF-8&useSSL=false username: root password: root initialize: true init-db: true jpa: database: mysql show-sql: true hibernate: ddl-auto: update naming: strategy: org.hibernate.cfg.ImprovedNamingStrategy
@Entity @Table(name="book") public class Book { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id", updatable = false) private Long id; @Column(nullable = false,name = "name") private String name; @Column(nullable = false,name = "isbn") private String isbn; @Column(nullable = false,name = "author") private String author; public Book (String name,String isbn,String author){ this.name = name; this.isbn = isbn; this.author = author; } //因爲添加了一個有參構造方法,此處必定要建立一個空的構造方法,不然查詢報錯 public Book(){ } public String getAuthor() { return author; } public String getIsbn() { return isbn; } public String getName() { return name; } public void setAuthor(String author) { this.author = author; } public void setIsbn(String isbn) { this.isbn = isbn; } public void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }
@Repository("bookRepository") public interface BookRepository extends JpaRepository<Book,Long> { Book findByIsbn(String isbn); Book findByName(String name); @Query("from Book b where b.name=:name") Book findBook(@Param("name") String name); }
此處我繼承的是JpaRepository這個接口,其實在jpa中提供了多套接口供咱們選擇sql
你們能夠根據本身的程序中的實際狀況進行選擇。jpa還有一個強大的功能就是經過解析方法名稱建立sql語句,上面方法中的Book findByIsbn(String isbn);
Book findByName(String name);這兩個方法就是使用這個特性。下面爲jap中支持的關鍵字:數據庫
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstname,findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1(parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1(parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1(parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
True | findByActiveTrue() | … where x.active = true |
False | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
固然除了使用方法名稱解析sql語句,咱們也能夠經過@Query註解來建立查詢,你們只須要在註解中使用JPQL語句,並經過相似「:name」來映射@Param指定的參數,就像上面的Book findBook(@Param("name") String name);方法同樣。restful
JPA的能力遠不如上面介紹的這一點,本篇主要是以介紹爲主,後續會補充一些JPA的其餘內容。app
根據慣例,咱們編寫一個單元測試對接口進行測試 框架
@RunWith(SpringRunner.class) @SpringBootTest public class Demo4ApplicationTests { @Resource private BookRepository bookRepository; @Test public void test() throws Exception { // 建立10條記錄 bookRepository.save(new Book("AAA", "10","123")); bookRepository.save(new Book("BBB", "20","123")); bookRepository.save(new Book("CCC", "30","123")); bookRepository.save(new Book("DDD", "40","123")); bookRepository.save(new Book("EEE", "50","123")); bookRepository.save(new Book("FFF", "60","123")); bookRepository.save(new Book("GGG", "70","123")); bookRepository.save(new Book("HHH", "80","123")); bookRepository.save(new Book("III", "90","123")); bookRepository.save(new Book("JJJ", "00","123")); // 測試findAll, 查詢全部記錄 Assert.assertEquals(10, bookRepository.findAll().size()); // 測試findByName, 查詢名爲FFF的Book Assert.assertEquals("60", bookRepository.findByName("FFF").getIsbn().toString()); // 測試findBook, 查詢名爲FFF的Book Assert.assertEquals("60", bookRepository.findBook("FFF").getIsbn().toString()); // 測試findByNameAndIsbn, 查詢名爲FFF而且isbn爲60的Book Assert.assertEquals("FFF", bookRepository.findByNameAndIsbn("FFF", "60").getName()); // 測試刪除名爲AAA的Book bookRepository.delete(bookRepository.findByName("AAA")); // 測試findAll, 查詢全部記錄, 驗證上面的刪除是否成功 Assert.assertEquals(9, bookRepository.findAll().size()); } }
最後介紹一個消除冗長代碼的工具「lombok」maven
maven座標爲:ide
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
lombok能夠去除pojo中冗餘的get、set等方法,經常使用的註解以下:
下面是簡單示例
不使用lombok時
public class Person { private String id; private String name; private String identity; private Logger log = Logger.getLogger(Person.class); public Person() { } public Person(String id, String name, String identity) { this.id = id; this.name = name; this.identity = identity; } public String getId() { return id; } public String getName() { return name; } public String getIdentity() { return identity; } public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public void setIdentity(String identity) { this.identity = identity; } }
使用lombok後
@Data @Log4j @NoArgsConstructor @AllArgsConstructor public class Person { private String id; private String name; private String identity; }