Spring Boot 入門系列(七) 使用 JPA

文章使用版本為 Spring Boot 2.1.x

前言

JPA是Java Persistence API的簡稱,是一種標(biāo)準(zhǔn)鳖悠,具體實(shí)現(xiàn)交由各個(gè)廠商實(shí)現(xiàn)。Spring Data JPA 對其提供支持聋涨,內(nèi)部實(shí)現(xiàn)是Hibernate芙扎。

使用JPA開發(fā)代碼非常方便,只要寫一個(gè)接口繼承 JpaRepository 就可以實(shí)現(xiàn)基本的增刪改查的功能胚宦,比如下面這樣

public interface UserRepository extends JpaRepository<User, String> {

}

在大部分情況下都是使用單表操作時(shí)首有,使用JPA也是一個(gè)不錯(cuò)的選擇,下面我們就來一起學(xué)習(xí)下吧枢劝。

添加依賴

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

application.yml

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/spring_boot_learn?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&autoReconnect=true&useSSL=true
    driver-class-name: com.mysql.jdbc.Driver
    username: root
    password: root
    hikari:
      minimum-idle: 2
      maximum-pool-size: 5
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

datasource的部分就不多講了井联,我們主要來看一下jpa的配置部分

  • jpa.show-sql:這個(gè)很明顯是控制是否顯示SQL語句的,開發(fā)時(shí)我們可以選擇true
  • jpa.hibernate.ddl-auto:這個(gè)是用來控制數(shù)據(jù)庫表的生成策略您旁,有以下幾種值
    • create:每次加載hibernate時(shí)都會刪除上一次的生成的表烙常,然后根據(jù)你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執(zhí)行鹤盒,這就是導(dǎo)致數(shù)據(jù)庫表數(shù)據(jù)丟失的一個(gè)重要原因蚕脏。
    • create-drop:每次加載hibernate時(shí)根據(jù)model類生成表侦副,但是sessionFactory一關(guān)閉,表就自動刪除。
    • update:最常用的屬性蝗锥,第一次加載hibernate時(shí)根據(jù)model類會自動建立起表的結(jié)構(gòu)(前提是先建立好數(shù)據(jù)庫)跃洛,以后加載hibernate時(shí)根據(jù)model類自動更新表結(jié)構(gòu),即使表結(jié)構(gòu)改變了但表中的行仍然存在不會刪除以前的行终议。要注意的是當(dāng)部署到服務(wù)器后,表結(jié)構(gòu)是不會被馬上建立起來的葱蝗,是要等應(yīng)用第一次運(yùn)行起來后才會穴张。
    • validate:每次加載hibernate時(shí),驗(yàn)證創(chuàng)建數(shù)據(jù)庫表結(jié)構(gòu)两曼,只會和數(shù)據(jù)庫中的表進(jìn)行比較皂甘,不會創(chuàng)建新表,但是會插入新值悼凑。

雖然可以讓程序自動生成表結(jié)構(gòu)偿枕,但是我還是建議手寫建表語句。

CREATE SCHEMA IF NOT EXISTS `spring_boot_learn` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_bin;

CREATE TABLE IF NOT EXISTS `spring_boot_learn`.`user` (
  `id` VARCHAR(37) NOT NULL COMMENT 'UUID',
  `username` VARCHAR(128) NOT NULL COMMENT '用戶名',
  `age` INT(10) unsigned NOT NULL COMMENT '年齡',
  PRIMARY KEY (`id`)  COMMENT ''
  )
ENGINE = InnoDB
COMMENT = '用戶表';

創(chuàng)建實(shí)體

package org.schhx.springbootlearn.entity;

import lombok.Data;
import lombok.experimental.Accessors;

import javax.persistence.Entity;
import javax.persistence.Id;

@Data
@Accessors(chain = true)
@Entity
public class User {
    @Id
    private String id;

    private String username;

    private Integer age;

}

@Entity 表明是一個(gè)實(shí)體類
@Id 用來指明主鍵户辫,如果使用自增主鍵渐夸,可以在主鍵上加上@GeneratedValue

創(chuàng)建數(shù)據(jù)訪問接口

package org.schhx.springbootlearn.dao;

import org.schhx.springbootlearn.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.List;

public interface UserRepository extends JpaRepository<User, String> {

    List<User> findByUsername(String username);
}

通過查看 JpaRepository 的源碼我們可以發(fā)現(xiàn),通用的增刪改查的方法都已經(jīng)有了渔欢,當(dāng)然你也可以自己寫一些方法墓塌,比如 List<User> findByUsername(String username),JPA會自動根據(jù)方法名來創(chuàng)建實(shí)現(xiàn)奥额。

測試

package org.schhx.springbootlearn.dao;

import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.schhx.springbootlearn.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Example;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.UUID;

import static org.junit.Assert.*;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRepositoryTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    @Transactional
    public void create() throws Exception {
        String id = UUID.randomUUID().toString();
        User user = new User().setId(id).setUsername("張三").setAge(20);
        User result = userRepository.save(user);
        System.out.println(result);
        Assert.assertNotEquals(null, result);
    }

    @Test
    @Transactional
    public void findByUserName() throws Exception {
        String id = UUID.randomUUID().toString();
        User user = new User().setId(id).setUsername("張三").setAge(20);
        userRepository.save(user);
        List<User> result = userRepository.findByUsername("張三");
        System.out.println(result);
        Assert.assertNotEquals(null, result);
    }

    @Test
    @Transactional
    public void findByExample() throws Exception {
        String id = UUID.randomUUID().toString();
        User user = new User().setId(id).setUsername("張三").setAge(20);
        userRepository.save(user);
        List<User> result = userRepository.findAll(Example.of(new User().setUsername("張三")));
        System.out.println(result);
        Assert.assertNotEquals(null, result);
    }
}

完整示例

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末苫幢,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子垫挨,更是在濱河造成了極大的恐慌韩肝,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,548評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件九榔,死亡現(xiàn)場離奇詭異哀峻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)帚屉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評論 3 399
  • 文/潘曉璐 我一進(jìn)店門谜诫,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人攻旦,你說我怎么就攤上這事喻旷。” “怎么了牢屋?”我有些...
    開封第一講書人閱讀 167,990評論 0 360
  • 文/不壞的土叔 我叫張陵且预,是天一觀的道長槽袄。 經(jīng)常有香客問我,道長锋谐,這世上最難降的妖魔是什么遍尺? 我笑而不...
    開封第一講書人閱讀 59,618評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮涮拗,結(jié)果婚禮上乾戏,老公的妹妹穿的比我還像新娘。我一直安慰自己三热,他們只是感情好鼓择,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著就漾,像睡著了一般呐能。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上抑堡,一...
    開封第一講書人閱讀 52,246評論 1 308
  • 那天摆出,我揣著相機(jī)與錄音,去河邊找鬼首妖。 笑死偎漫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的悯搔。 我是一名探鬼主播骑丸,決...
    沈念sama閱讀 40,819評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼妒貌!你這毒婦竟也來了通危?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,725評論 0 276
  • 序言:老撾萬榮一對情侶失蹤灌曙,失蹤者是張志新(化名)和其女友劉穎菊碟,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體在刺,經(jīng)...
    沈念sama閱讀 46,268評論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逆害,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蚣驼。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片魄幕。...
    茶點(diǎn)故事閱讀 40,488評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖颖杏,靈堂內(nèi)的尸體忽然破棺而出纯陨,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評論 5 350
  • 正文 年R本政府宣布翼抠,位于F島的核電站咙轩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏阴颖。R本人自食惡果不足惜活喊,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望量愧。 院中可真熱鬧钾菊,春花似錦、人聲如沸侠畔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,331評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽软棺。三九已至,卻和暖如春尤勋,著一層夾襖步出監(jiān)牢的瞬間喘落,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,445評論 1 272
  • 我被黑心中介騙來泰國打工最冰, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留瘦棋,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,897評論 3 376
  • 正文 我出身青樓暖哨,卻偏偏與公主長得像赌朋,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子篇裁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評論 2 359

推薦閱讀更多精彩內(nèi)容