上一篇咱们了解了如何使用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; }