SpringBoot | 第三十章:Spring-data-jpa的集成和使用

前言

在前面的第九章:Mybatis-plus的集成和使用章節中,介紹了使用ORM框架mybatis-plus進行數據庫的訪問。今天,咱們來簡單學習下如何使用 spring-data-jpa進行數據庫的訪問。因爲本人未使用過jpa,也是趁着寫博文的機會查閱了相關資料下,有錯誤的地方還望指出!html

一點知識

何爲JPA

JPAJava Persistence API的簡寫,是Sun官方提出的一種ORM規範!java

對於Sun官網而言, 一是想簡化現有Java EEJava SE應用開發工做。 二是想整合ORM技術,實現天下歸一mysql

對於JPA規範,都在包路徑:javax.persistence.*下,像一些經常使用的如:@Entity@Id@Transient都在此路徑下。這些也是一些如今市面上經常使用的ORM一些約定俗成的註解了。git

簡單來講,JPA是一套規範。因此使用Jpa的一個好處是,能夠更換實現而沒必要改動太多代碼。github

何爲Sping-data-jpa

Spring Data JPASpring基於Hibernate開發的一個JPA框架。能夠極大的簡化JPA的寫法,能夠在幾乎不用寫具體代碼的狀況下,實現對數據的訪問和操做。除了CRUD外,還包括如分頁排序等一些經常使用的功能。web

Spring Data JPA提供的接口,也是Spring Data JPA的核心概念:spring

  1. Repository:最頂層的接口,是一個空的接口,目的是爲了統一全部Repository的類型,且能讓組件掃描的時候自動識別。
  2. CrudRepository :是Repository的子接口,提供CRUD的功能
  3. PagingAndSortingRepository:是CrudRepository的子接口,添加分頁和排序的功能
  4. JpaRepository:是PagingAndSortingRepository的子接口,增長了一些實用的功能,好比:批量操3做等。
  5. JpaSpecificationExecutor:用來作負責查詢的接口
  6. Specification:是Spring Data JPA提供的一個查詢規範,要作複雜的查詢,只需圍繞這個規範來設置查詢條件便可。

題外話:剛開始,其實我看mybatis提供的都差很少,最讓我以爲神奇的是:能夠經過方法命名規則進行相關數據庫操做,這個確實能夠減小不少代碼的編寫。本來使用Mybatis-plus新增一個自定義方法,須要使用通用查詢模版EntityWrapper進行相應的操做的sql

其中,相關命名規範以下:數據庫

關鍵字 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection<?> c) where id in (?)
NotIn findByIdNotIn(Collection<?> c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

這個確實,夠強大!但查詢添加一多,是否是這個方法名就也很長了,(┬_┬)springboot

SpringBoot集成Spring-data-jpa

本示例,使用druid(鏈接池)+mysql進行演示。同時以User表舉例:

CREATE TABLE `user` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '惟一標示',
  `code` varchar(20) DEFAULT NULL COMMENT '編碼',
  `name` varchar(64) DEFAULT NULL COMMENT '名稱',
  `status` char(1) DEFAULT '1' COMMENT '狀態 1啓用 0 停用',
  `gmt_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
  `gmt_modified` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

題外話:雖然也提供了自動根據實體建立表的功能,但通常上開發應該不會這麼建立吧。由於表結構通常都須要通過評審的,評審後就建立好了。。

0.引入pom依賴

<!-- 引入jpa依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <!--druid -->
        <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid-spring-boot-starter</artifactId>
           <version>1.1.10</version>
        </dependency>
       <!-- mysql驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

1.編寫User的實體類。

/**
 * 用戶實體
 * @author oKong
 *
 */
@Entity
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EntityListeners(AuditingEntityListener.class)
//@Table(name="CUSTOM_USER")//自定義表名
public class User implements Serializable{
     /**
     * 
     */
    private static final long serialVersionUID = -3752294262021766827L;
    /**
     * 惟一標示
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    /**
     * 編碼
     */
    private String code;
    /**
     * 名稱
     */
    private String name;
    
    /**
     * 建立時間
     */
    @CreatedDate //自動建立
    private Date gmtCreate;
    /**
     * 修改時間
     */
    @LastModifiedDate //有修改時 會自動時間
    private Date gmtModified;
}

這裏須要注意,在使用mybatis-plus時,在《Mybatis-Plus使用全解》時,介紹過可如何設置公共字段自動填充功能,好比建立時間和修改時間,建立人和修改人等等,都是能夠統一進行賦值的。而在spring-data-jap中,是使用@CreatedDate@LastModifiedDate標記的,同時,須要在實體類上,加入@EntityListeners(AuditingEntityListener.class),而後在啓動類上加入註解@EnableJpaAuditing,這樣就實現了相似公共字段自動填充功能了。

2.建立資源類,這裏習慣了命名爲dao了,因此仍是以Dao進行結尾。

/**
 * 資源類
 * @author oKong
 *
 */
public interface UserDao extends PagingAndSortingRepository<User,Long>{

	List<User> findById(Long id);
	
	//使用自動命名規則進行查詢服務 
	List<User> findByCodeAndName(String code,String name);
	
	//使用@Query進行 自定義sql編寫
	//nativeQuery=true,正常的sql語法
	//負責是hsql語法
	@Query(value="select * from user where code = ?1",nativeQuery=true)
	List<User> queryByCode(String code);
	
	//分頁
	Page<User> findByCode(String code,Pageable pageable);
}

注意:這裏直接繼承了PagingAndSortingRepository,其自己實現了分頁功能,還能夠按須要繼承CrudRepository或者JpaRepository等。並且,佔位符爲:?+具體的參數索引值

3.建立控制層,引入資源類。示例了一些經常使用的操做,包括分頁,查詢、刪除、新增等等。

/**
 * 測試類
 * @author oKong
 *
 */
@RestController
@Slf4j
public class DemoController {

    @Autowired
    UserDao userDao;
    
    @PostMapping("/add")
    public String addUser(User user) {
        log.info("新增用戶:{}", user);
        user = userDao.save(user);
        return "新增成功,返回用戶id爲:" + user.getId();
    }
    
    @GetMapping("/find/{id}")
    public User findUser(@PathVariable Long id) {
        log.info("查找用戶ID:{}", id);
        return userDao.findOne(id);
    }
    
    @PostMapping("/del/{id}")
    public String delUser(Long id) {
        log.info("刪除用戶ID:{}", id);
        userDao.delete(id);
        return "用戶id爲:" + id + ",已被刪除!";
    }
    
    @GetMapping("/find/{code}/{name}")
    public List<User> findUserByCodeAndName(@PathVariable("code") String code, @PathVariable("name")String name) {
        log.info("命名規則方式,查找用戶:編碼:{},名稱:{}", code, name);
        return userDao.findByCodeAndName(code, name);
    }
    
    @GetMapping("/find/paging/{code}")
    public Page<User> findUserByCodePagin(@PathVariable("code") String code){
        log.info("分頁模式,查找用戶:編碼:{}", code);
        //這裏注意 page是從0開始的
        return userDao.findByCode(code, new PageRequest(0,10));
    }
    
    @GetMapping("/find/sql/{code}")
    public List<User> findUserByQuerySql(@PathVariable("code") String code){
        log.info("自定義sql方式,查找用戶:編碼:{}", code);

        return userDao.queryByCode(code);
    }
}

4.配置文件添加相關數據源及jpa相關信息。這裏使用druid做爲數據鏈接池。

#數據源設置
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/learning?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
#以上爲必須的
#選填
spring.datasource.druid.initial-size=5
# maxPoolSize
spring.datasource.druid.max-active=20
# minPoolSize
spring.datasource.druid.min-idle=5

#配置獲取鏈接等待超時的時間
spring.datasource.druid.max-wait=60000
# 校驗
spring.datasource.druid.validation-query=SELECT 'x'

spring.datasource.druid.test-on-borrow=false
spring.datasource.druid.test-on-return=false
spring.datasource.druid.test-while-idle=true
#配置間隔多久才進行一次檢測,檢測須要關閉的空閒鏈接,單位是毫秒
spring.datasource.druid.time-between-eviction-runs-millis=60000
#配置一個鏈接在池中最小生存的時間,單位是毫秒
spring.datasource.druid.min-evictable-idle-time-millis=300000

#jpa相關配置
# 顯示sql 但不會顯示具體的操做值 能夠替換成log4jdbc
spring.jpa.show-sql=true

5.編寫啓動類。

/**
 * jpa集成
 * 
 * @author oKong
 *
 */
@SpringBootApplication
@EnableJpaAuditing
@Slf4j
public class JpaApplication {

    public static void main(String[] args) throws Exception {
        SpringApplication.run(JpaApplication.class, args);
        log.info("spring-boot-jpa-chapter30啓動!");
    }

}

6.啓動服務。而後使用postman進行訪問(關於postman相關用法,能夠查看:第十五章:基於Postman的RESTful接口測試)。

add

查找

分頁查找 會返回相關信息,如總記錄數,總頁碼數等等。

控制檯輸出:

Hibernate: select user0_.id as id1_0_, user0_.code as code2_0_, user0_.gmt_create as gmt_crea3_0_, user0_.gmt_modified as gmt_modi4_0_, user0_.name as name5_0_ from user user0_ where user0_.code=? limit ?
Hibernate: select count(user0_.id) as col_0_0_ from user user0_ where user0_.code=?

自定義sql查找

控制檯輸出:

Hibernate: select * from user where code = ?

參考資料

  1. https://docs.spring.io/spring-data/data-jpa/docs/1.11.14.RELEASE/reference/html/

總結

本章節主要介紹了Spring-data-jpa的集成和簡單的使用。並未深刻了解,想了解更多細節,好比排序@Param使用等等,可去官網查閱下。待有機會深刻學習後,再寫一篇關於JPA的提升篇吧~使用起來其實也蠻簡單的,就是可能更開始接觸,不是很習慣到時真的,有機會一些小的項目或者demo項目,到時可使用下,切身體驗下~

最後

目前互聯網上不少大佬都有SpringBoot系列教程,若有雷同,請多多包涵了。原創不易,碼字不易,還但願你們多多支持。若文中有所錯誤之處,還望提出,謝謝。

老生常談

  • 我的QQ:499452441
  • 微信公衆號:lqdevOps

公衆號

我的博客:http://blog.lqdev.cn

原文地址:http://blog.lqdev.cn/2018/10/31/springboot/chapter-thirty/

完整示例:https://github.com/xie19900123/spring-boot-learning/tree/master/chapter-30

相關文章
相關標籤/搜索