【SpringBoot2.0系列04】SpringBoot之使用JPA完成簡單的rest api

目錄

【SpringBoot2.0文章匯總目錄,java多線程教程文章匯總 長期更新系列

請多多支持

【SpringBoot2.0系列01】初識SpringBoot
【SpringBoot2.0系列02】SpringBoot之使用Thymeleaf視圖模板
【SpringBoot2.0系列03】SpringBoot之使用freemark視圖模板
【SpringBoot2.0系列04】SpringBoot之使用JPA完成簡單的rest api
【SpringBoot2.0系列05】SpringBoot之整合Mybatis
【SpringBoot2.0系列06】SpringBoot之多數(shù)據(jù)源動態(tài)切換數(shù)據(jù)源
【SpringBoot2.0系列07】SpringBoot之redis使用(Lettuce版本)

一宏多、 前言

在前面我們已經(jīng)知道在springboot中如何使用freemarkthymeleaf之類的視圖模板引擎去渲染我們的視圖頁面算吩,但是沒涉及跟數(shù)據(jù)庫交互的東西,所以今天在這里我們將介紹了一下如何在springboot中通過spring data jpa操作mysql數(shù)據(jù)庫,并且構(gòu)建一套簡單的rest api接口。

1.1、Spring Data Jpa 介紹

Spring Data JPA是Spring基于Hibernate開發(fā)的一個JPA框架绰寞。如果用過Hibernate或者M(jìn)yBatis的話,就會知道對象關(guān)系映射(ORM)框架有多么方便。但是Spring Data JPA框架功能更進(jìn)一步克握,為我們做了 一個數(shù)據(jù)持久層框架幾乎能做的任何事情蕾管。并且提供了基礎(chǔ)的增刪改查方法,具體api請看官網(wǎng)菩暗。

2.2

REST是所有Web應(yīng)用都應(yīng)該遵守的架構(gòu)設(shè)計指導(dǎo)原則掰曾。
Representational State Transfer,翻譯是”表現(xiàn)層狀態(tài)轉(zhuǎn)化”停团。
面向資源是REST最明顯的特征旷坦,對于同一個資源的一組不同的操作。資源是服務(wù)器上一個可命名的抽象概念佑稠,資源是以名詞為核心來組織的秒梅,首先關(guān)注的是名詞。REST要求舌胶,必須通過統(tǒng)一的接口來對資源執(zhí)行各種操作捆蜀。對于每個資源只能執(zhí)行一組有限的操作。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
關(guān)于rest api如何涉及我也是從阮一峰老師那里學(xué)習(xí)的幔嫂。

二辆它、目標(biāo)

首先我們有一個user表,我們希望能通過構(gòu)建出對應(yīng)的rest api對表中的數(shù)據(jù)完成增刪改查操作履恩。
jpa的依賴如下

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    </dependencies>

接下來那么第一步就是創(chuàng)表了
1锰茉、創(chuàng)表
由于我們使用的spring data jpa 而jpa的底層實現(xiàn)是hibernate,用過hibernate的同學(xué)知道 hibernate可以通過實體類逆向創(chuàng)建表切心,只需要配置一下ddl-auto 就可以
所以我們需要在application.yml配置一下

server:
  port: 8989
spring:
  datasource:
    username: root
    password: root
    url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

在上面的配置文件中 我們配置了一個數(shù)據(jù)源跟tomcat端口還有jpa的配置飒筑。其中 show-sql: true 代表會在日志中打印我們操作的sql、
而另外 ddl-auto有四個值可選绽昏,分別是

  • create 啟動時刪數(shù)據(jù)庫中的表协屡,然后創(chuàng)建,退出時不刪除數(shù)據(jù)表
  • create-drop 啟動時刪數(shù)據(jù)庫中的表全谤,然后創(chuàng)建肤晓,退出時刪除數(shù)據(jù)表 如果表不存在報錯
  • update 最常用的屬性,第一次加載hibernate時根據(jù)model類會自動建立起表的結(jié)構(gòu)(前提是先建立好數(shù)據(jù)庫)啼县,以后加載hibernate時根據(jù) model類自動更新表結(jié)構(gòu),即使表結(jié)構(gòu)改變了但表中的行仍然存在不會刪除以前的行沸久。要注意的是當(dāng)部署到服務(wù)器后季眷,表結(jié)構(gòu)是不會被馬上建立起來的,是要等 應(yīng)用第一次運(yùn)行起來后才會卷胯。
  • validate 項目啟動表結(jié)構(gòu)進(jìn)行校驗 如果不一致則報錯

所以這里我們希望當(dāng)表創(chuàng)建成功后 下次啟動數(shù)據(jù)還在我們就選擇了update模式子刮,其次我們需要在本地的mysql數(shù)據(jù)庫新建一個test數(shù)據(jù)庫。
接下來我們需要編寫的我們實體類User.javahibernate將會通過實體類的結(jié)構(gòu)在test數(shù)據(jù)庫中創(chuàng)建一個對應(yīng)的user
新建包entity 創(chuàng)建User.java代碼如下:

@JsonIgnoreProperties(value={"hibernateLazyInitializer","handler","fieldHandler"}) 
@Entity
public class User {

    @Id
    @GeneratedValue
    private Long id;

    /**
     * 用戶名
     */
    @Column(name = "username", nullable = true, length = 32)
    private String username;

    /**
     * 密碼
     */
    @Column(name = "password", nullable = true, length = 32)
    private String password;

    /**
     * 年齡
     */
    @Column(name = "age", nullable = true, length = 11)
    private Integer age;

    /**
     * 性別 1=男 2=女 其他=保密
     */
    @Column(name = "sex", nullable = true, length = 11)
    private Integer sex;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

至此,我們的user表也算是創(chuàng)建好了挺峡,當(dāng)我們的程序第一個啟動的時候jpa會自動在test數(shù)據(jù)庫中創(chuàng)建與之對應(yīng)的表葵孤。


2、構(gòu)建rest api
這里我們需要構(gòu)建如下的rest api

url method 介紹
/user/ get 獲取所有的用戶信息
/user/id/{id} get 根據(jù)id獲取用戶信息
/user/username/{username} get 根據(jù)username獲取用戶信息
/user post 新增用戶信息
/user put 更新用戶信息
/user/id/{id} delete 根據(jù)id刪除用戶信息

那么這就是我們需要構(gòu)建的rest api橱赠,那么對應(yīng)的由mvc模式可知我們的rest apicontroller層的尤仍,所以我們的servicerepository層(備注在使用 jpa的時候我們喜歡把dao層命名為repository)需要提供對應(yīng)的接口。
首先我們首先需要編寫UserRepository接口狭姨,并且讓它基礎(chǔ)JpaRepository接口

新建包repository 創(chuàng)建UserRepository.java代碼如下:

public interface UserRepository extends JpaRepository<User, Long> {

    /**
     * 根據(jù)用戶名查找用戶信息
     * @param username
     * @return
     */
    User findUserByUsername(String username);

}

解釋一下上面的代碼宰啦,為什么只有一個方法,而前面我們是五個接口饼拍,因為是在JpaRepository中提供較為基礎(chǔ)的增刪改查方法赡模,我們無需編寫就看使用。如果大家不信按住ctrl點(diǎn)擊JpaRepository看源碼就知道了师抄。

image.png

從上面就可以看出JpaRespository提供了哪些基礎(chǔ)方法了漓柑。怎么樣 是不是覺得很方便。那么接下來的第二點(diǎn)就Jpa可以根據(jù)你的命名規(guī)則來推斷你這個方法作用叨吮,簡單的來說findUserByUsername 根據(jù)這個方法名辆布,jpa可以知道這個方法是通過用戶名去查找用戶。 具體的規(guī)則大家可以看文檔
image.png

如果大家用的idea的話挤安,那么它會用智能提示功能谚殊,如圖
image.png

所以我們只需要編寫方法名就可以輕輕松松的實現(xiàn)我們的查詢方法,怎么樣jpa是不是特別簡單蛤铜,但是需要注意的是方法名一定要命名規(guī)范嫩絮,不要嫌太長了。
接下來就是編寫我們的service層了围肥,
新建service包創(chuàng)建UserService.java代碼如下:

public interface UserService {

    /**
     * 添加用戶信息
     * @param user
     * @return
     */
    User saveUser(User user);

    /**
     * 更新用戶信息
     * @param user
     */
    User updateUser(User user);

    /**
     * 根據(jù)id獲取用戶
     * @param id
     * @return
     */
    User getById(Long id);

    /**
     * 根據(jù)名稱獲取用戶
     * @param username
     * @return
     */
    User getByUserName(String username);

    /**
     * 查詢所有用戶
     * @return
     */
    List<User> queryAll();

    /**
     * 根據(jù)id刪除用戶信息
     * @param id
     */
    void deleteById(Long id);
}

接下里就下service的實現(xiàn)類剿干,帶service包下新建impl包并且創(chuàng)建實現(xiàn)類UserServiceImpl.java 代碼如下

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public User saveUser(User user) {
        return userRepository.save(user);
    }

    @Override
    public User updateUser(User user) {
        return userRepository.save(user);
    }

    @Override
    public User getById(Long id) {
        return userRepository.getOne(id);
    }

    @Override
    public User getByUserName(String username) {
        return userRepository.findUserByUsername(username);
    }

    @Override
    public List<User> queryAll() {
        return userRepository.findAll();
    }

    @Override
    public void deleteById(Long id) {
        userRepository.deleteById(id);
    }
}

那么緊接著就是控制層的代碼了,新建controller包,并且創(chuàng)建UserController.java

@RestController
@RequestMapping(value = "/user")
public class UserController {

    @Autowired
    private UserService userService;

    @PostMapping
    public User save(@RequestBody User user) {
        return userService.saveUser(user);
    }

    @PutMapping
    public User update(@RequestBody User user) {
        return userService.saveUser(user);
    }

    @DeleteMapping(value = "/id/{id}")
    public String delete(@PathVariable  Long id) {
        userService.deleteById(id);
        return "刪除成功";
    }

    @GetMapping(value = "/id/{id}")
    public User findById (@PathVariable Long id) {
        return userService.getById(id);
    }

    @GetMapping(value = "/username/{username}")
    public User findByUsername (@PathVariable String username) {
        return userService.getByUserName(username);
    }

    @GetMapping(value = "/")
    public List<User> findAll () {
        return userService.queryAll();
    }
}

這樣我們就完成了一個簡單的rest api了啊穆刻。
接下來我們來測試一下把置尔。
3、測試
由于我們這里測試的是rest api普通的瀏覽器是沒法支持 post delet put方式的訪問的氢伟,所以這里我們就用postman來測試榜轿。
1、首先我們看到test數(shù)據(jù)庫中現(xiàn)在是一張表都沒有的

image.png

啟動程序朵锣,注意觀察日志谬盐。
image.png

我們看到了日志打印了創(chuàng)建表的ddl那么我們再看看數(shù)據(jù)庫中有沒有表

image.png

此時我們看到了有兩張表,一張是我們user表诚些,而另一張就是主鍵生成序列表飞傀。
接下來就開始我們的rest api測試了皇型。
首先測試新增用戶
打開postman

image.png

選擇post模式,輸入訪問的url砸烦,然后選擇body中的raw弃鸦,因為我們使用的@RequestBody注解,所以我們選擇raw中的Json幢痘,如圖


image.png

因為我們的id是自增的唬格,所以我們不要輸入,直接點(diǎn)擊send訪問雪隧,如果返回的數(shù)據(jù)有id那么就是代表新增成功西轩。如下圖就是新增成功。


image.png

打開數(shù)據(jù)庫中的user表脑沿,看看數(shù)據(jù)有沒有保存成功藕畔。
image.png

由圖可知,保存成功庄拇。

接下來我們就多添加幾條數(shù)據(jù)注服。
那么我們測試一下查詢所有數(shù)據(jù)的方法。操作如圖


image.png

我們剛剛一共添加三條數(shù)據(jù)措近,全部都查詢出來了溶弟。
我們繼續(xù)測試一下修改方法把。我們把id為2的數(shù)據(jù)密碼修改為跟用戶名一樣瞭郑,具體操作如圖辜御,
image.png

點(diǎn)擊send操作成功,我們用根據(jù)id查詢的方法來查詢一下剛剛id為2的數(shù)據(jù)有沒有修改成功屈张,那么我們查詢一下id為2的數(shù)據(jù)擒权,操作如圖。
image.png

由圖中可以看到我們的修改是成功的阁谆,用戶名跟密碼已經(jīng)一樣的碳抄,那么代表我們的根據(jù)id查詢方法也是沒問題的。那么另外幾個方法我們不測試了场绿,留給大家測試剖效。

三、總結(jié)

這里我們通過這次選擇對于jpa的使用有了一個初步的了解焰盗,并且對于rest api的規(guī)范也有了個了解璧尸。

最后配套教程的代碼全部在這里
github https://github.com/YuKongEr/SpringBoot-Study。麻煩點(diǎn)個star或者fork吧熬拒。
最后大家關(guān)注一下我的個人公眾號把爷光。

公眾號

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市梦湘,隨后出現(xiàn)的幾起案子瞎颗,更是在濱河造成了極大的恐慌,老刑警劉巖捌议,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件哼拔,死亡現(xiàn)場離奇詭異,居然都是意外死亡瓣颅,警方通過查閱死者的電腦和手機(jī)倦逐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宫补,“玉大人檬姥,你說我怎么就攤上這事》叟拢” “怎么了健民?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長贫贝。 經(jīng)常有香客問我秉犹,道長,這世上最難降的妖魔是什么稚晚? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任崇堵,我火速辦了婚禮,結(jié)果婚禮上客燕,老公的妹妹穿的比我還像新娘鸳劳。我一直安慰自己,他們只是感情好也搓,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布赏廓。 她就那樣靜靜地躺著,像睡著了一般还绘。 火紅的嫁衣襯著肌膚如雪楚昭。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天拍顷,我揣著相機(jī)與錄音抚太,去河邊找鬼。 笑死昔案,一個胖子當(dāng)著我的面吹牛尿贫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播庆亡,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼捞稿!你這毒婦竟也來了又谋?” 一聲冷哼從身側(cè)響起拼缝,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎彰亥,沒想到半個月后咧七,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡任斋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年继阻,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片废酷。...
    茶點(diǎn)故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡瘟檩,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出澈蟆,到底是詐尸還是另有隱情墨辛,我是刑警寧澤,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布趴俘,位于F島的核電站背蟆,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哮幢。R本人自食惡果不足惜带膀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望橙垢。 院中可真熱鬧垛叨,春花似錦、人聲如沸柜某。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喂击。三九已至剂癌,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翰绊,已是汗流浹背佩谷。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留监嗜,地道東北人谐檀。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像裁奇,于是被迫代替她去往敵國和親桐猬。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評論 2 348

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

  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,773評論 6 342
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理刽肠,服務(wù)發(fā)現(xiàn)溃肪,斷路器免胃,智...
    卡卡羅2017閱讀 134,629評論 18 139
  • 原文鏈接:https://docs.spring.io/spring-boot/docs/1.4.x/refere...
    pseudo_niaonao閱讀 4,680評論 0 9
  • 聽了宋老師的講座,認(rèn)識了許多的新名詞“釘釘惫撰、花花草草杜秸、藍(lán)牙音響、問卷润绎。”在講座中宋老師還提到了美篇诞挨,云端...
    通化1031張麗群閱讀 297評論 0 1
  • 從歷史的眼光看惶傻,天下大勢棍郎,分久必合合久必分;分分合合银室,永續(xù)的運(yùn)動下去涂佃。經(jīng)過幾千年的發(fā)展,現(xiàn)如今的社會也不例外蜈敢,我們...
    邊凱閱讀 349評論 0 4