spring boot通过JPA访问Mysql
本文主要介紹spring boot如何使用JPA來訪問Mysql,對單表做簡單的增刪改查操作。
環境說明:
- IntelliJ IDEA
- JDK 1.8
- spring boot 2.1.0
- Maven 3.5.0
- Mysql
一、初始化mysql
進入mysql,創建數據庫,創建數據表,并生成一些測試數據。
CREATE DATABASE spring_boot_study; USE spring_boot_study; DROP TABLE IF EXISTS `novel_type`; CREATE TABLE `novel_type` (`id` int(11) NOT NULL AUTO_INCREMENT,`novelname` varchar(20) NOT NULL,`novelauthor` varchar(20) NOT NULL,`type` varchar(20) NOT NULL,`introduce` text NOT NULL,`download` varchar(20) DEFAULT 'false',PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;-- ---------------------------- -- Records of novel_type -- ---------------------------- INSERT INTO `novel_type` VALUES ('1', '大主宰', '天蠶土豆', '連載中', '大千世界,位面交匯,萬族林立,群雄薈萃,一位位來自下位面的天之至尊,在這無盡世界,演繹著令人向往的傳奇,追求著那主宰之路。 無盡火域,炎帝執掌,萬火焚蒼穹。 武境之內,武祖之威,震懾乾坤。 西天之殿,百戰之皇,戰威無可敵。 北荒之丘,萬墓之地,不死之主鎮天地。 ...... 少年自北靈境而出,騎九幽冥雀,闖向了那精彩絕倫的紛紜', 'true'); INSERT INTO `novel_type` VALUES ('2', '斗破蒼穹', '天蠶土豆', '已完結', '這里是屬于斗氣的世界,沒有花俏艷麗的魔法,有的,僅僅是繁衍到巔峰的斗氣! 新書等級制度:斗者,斗師,大斗師,斗靈,斗王,斗皇,斗宗,斗尊,斗圣,斗帝。', 'true'); INSERT INTO `novel_type` VALUES ('3', '都市無上仙醫', '斷橋殘雪', '已完結', '他當過搬磚工,當過酒吧服務生,當過辦公室文員,當過老師,當過醫生……他是千千萬萬打工仔中的一名,為了生計而奔波勞碌,但同時他卻又是一位得上古巫王夏禹血脈傳承的巫師。 巫,上一橫頂天,下一橫立地,中間一豎直通天地,中統人與人,是真正通天達地,掌控天地萬物生靈之大能者!', 'true'); INSERT INTO `novel_type` VALUES ('4', '遮天', '辰東', '已完結', '冰冷與黑暗并存的宇宙深處,九具龐大的龍尸拉著一口青銅古棺,亙古長存。 這是太空探測器在枯寂的宇宙中捕捉到的一幅極其震撼的畫面。 九龍拉棺,究竟是回到了上古,還是來到了星空的彼岸? 一個浩大的仙俠世界,光怪陸離,神秘無盡。熱血似火山沸騰,激情若瀚海洶涌,欲望如深淵無止境…… 登天路,踏歌行,彈指遮天。', 'true');二、Spring boot配置
2.1 application.yml
根據個人喜好選擇配置文件的類型,在這里我選擇配置application.yml,主要對datasource與jpa進行一些配置說明。
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/spring_boot_study?allowMultiQueries=true&serverTimezone=GMT%2B8username: rootpassword: rootjpa:hibernate:ddl-auto: update # 第一次建表用create,之后用update,show-sql: true # 在控制臺打印出sql語句 server:port: 8081servlet:context-path: /spring-boot-study**注意:**如果通過jpa在數據庫中建表,將spring.jpa.hibernate,ddl-auto改為create,建完表之后,再改為update,要不然每次重啟工程會刪除表并新建。
2.2 pom.xml
至少引入下面四個依賴:
<!--引入JDBC的依賴--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--引入mysql連接--> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope> </dependency> <!--引入web依賴,可以使用@RequestMapping,@RestController等注解--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId> </dependency> <!--引入jpa依賴--> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>三、具體編碼
概括,本篇文章實現的功能有:
- 查詢表中所有數據
- 查詢表中所有數據的條數
- 通過小說作者來查詢數據
- 向表中插入或更新一條數據
- 根據小說id來判斷數據是否存在
- 根據小說id來刪除數據
- 根據小說名稱來刪除數據
3.1 實體(Entity)層
package com.study.spring.entity;import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table;@Entity @Table(name="novel_type") public class NovelEntity {@Id@Column(name = "id")private Long id;@Column(name = "novelname")private String novelName;@Column(name = "novelauthor")private String novelAuthor;@Column(name = "type")private String type;@Column(name = "introduce")private String introduce;@Column(name = "download")private String download;public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getNovelName() {return novelName;}public void setNovelName(String novelName) {this.novelName = novelName;}public String getNovelAuthor() {return novelAuthor;}public void setNovelAuthor(String novelAuthor) {this.novelAuthor = novelAuthor;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getIntroduce() {return introduce;}public void setIntroduce(String introduce) {this.introduce = introduce;}public String getDownload() {return download;}public void setDownload(String download) {this.download = download;}@Overridepublic String toString() {return "NovelEntity{" +"id=" + id +", novelName='" + novelName + '\'' +", novelAuthor='" + novelAuthor + '\'' +", type='" + type + '\'' +", introduce='" + introduce + '\'' +", download='" + download + '\'' +'}';} }3.2 DAO層
數據訪問層,通過編寫一個繼承自JpaRepository的接口就能完成數據訪問,其中包含了基本的單表查詢的方法,非常的方便。
package com.study.spring.jpa;import com.study.spring.entity.NovelEntity; import org.apache.ibatis.annotations.Param; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaSpecificationExecutor; import org.springframework.data.jpa.repository.Modifying; import org.springframework.data.jpa.repository.Query;import javax.transaction.Transactional; import java.io.Serializable; import java.util.List;/*** @description: 創建Novel JPA接口,繼承SpringDataJPA內的接口作為父類。* 繼承JpaRepository接口(SpringDataJPA提供的簡單數據操作接口)、* JpaSpecificationExecutor(SpringDataJPA提供的復雜查詢接口)、* 其中本篇文章僅使用了JpaRepository接口。*/ public interface INovelDAO extends JpaRepository<NovelEntity, Long>,JpaSpecificationExecutor<NovelEntity> {/*** @description: 通過小說作者來查詢數據* @param: author(小說作者)* @param: type(小說類型)* @return: java.util.List<com.study.spring.entity.NovelEntity>*/@Query("select nt from NovelEntity nt where nt.novelAuthor = ?1 and nt.type = ?2")List<NovelEntity> findByAuthorAndType(String author, String type);/*** @description: 根據小說名稱來刪除數據* @param: novelName(小說名稱)* @return: void*/@Transactional@Modifying@Query("delete from NovelEntity nt where nt.novelName = ?1")void deleteByNovelName(String novelName);}說明:
- 接口類繼承JpaRepository后,該接口類就可以直接使用自帶的findAll(),count(),save(),deleteById()等方法。方法功能可以通過方法名稱了解。
- 如果需要一些自定義操作或者復雜查詢的話,需要在繼承JpaRepository的接口里面編寫JPQL語句,查詢語句需要在方法上加注解@Query,增加/修改/刪除語句需要在方法上加注解@Transactional、@Modifying、@Query。
- JPQL語句與SQL語句略有不同,JPQL語句是對實體進行操作,屬性也是實體類里面的屬性,而非表字段。
3.3 Service層
由接口類與實現類組成:
接口類:
package com.study.spring.service;import com.study.spring.entity.NovelEntity;import java.util.List;public interface INovelService {/*** @description: 獲取表中所有信息* @return: java.util.List<com.study.spring.entity.NovelEntity>*/List<NovelEntity> findAll();/*** @description: 通過小說作者和小說類型來查詢數據* @param: author(小說作者)* @param: type(小說類型)* @return: java.util.List<com.study.spring.entity.NovelEntity>*/List<NovelEntity> findByAuthorAndType(String author, String type);/*** @description: 獲取表中所有數據的個數* @return: long*/long count();/*** @description: 向表中插入或更新一條數據* @param: novelEntity* @return: void*/void saveNovel(NovelEntity novelEntity);/*** @description: 根據id判斷數據是否存在* @param: id* @return: boolean*/boolean exists(Long id);/*** @description: 根據表的id來刪除數據* @param: id* @return: void*/void deleteById(Long id);/*** @description: 根據小說名稱來刪除數據* @param: novelName(小說名稱)* @return: void*/void deleteByNovelName(String novelName);}實現類:
package com.study.spring.service;import com.study.spring.entity.NovelEntity; import com.study.spring.jpa.INovelDAO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.util.List;@Service public class NovelServiceImpl implements INovelService {@Autowiredprivate INovelDAO inovelDAO;@Overridepublic List<NovelEntity> findAll() {return inovelDAO.findAll();}@Overridepublic List<NovelEntity> findByAuthorAndType(String author, String type) {return inovelDAO.findByAuthorAndType(author, type);}@Overridepublic long count() {return inovelDAO.count();}@Overridepublic void saveNovel(NovelEntity novelEntity) {inovelDAO.save(novelEntity);}@Overridepublic boolean exists(Long id) {return inovelDAO.existsById(id);}@Overridepublic void deleteById(Long id) {inovelDAO.deleteById(id);}@Overridepublic void deleteByNovelName(String novelName) {inovelDAO.deleteByNovelName(novelName);} }說明:
- 需要在Serivice層的實現類里面加入注解@Service
- 通過注解@Autowired來引用DAO層的接口INovelDAO
3.4 Controller
package com.study.spring.controller;import com.study.spring.entity.NovelEntity; import com.study.spring.service.INovelService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*;import java.util.HashMap; import java.util.List; import java.util.Map;@RestController @RequestMapping("novel") public class NovelController {@Autowiredprivate INovelService iNovelService;/*** @description: 獲取表中所有信息* @return: java.util.List<com.study.spring.entity.NovelEntity>*/@RequestMapping("list")public List<NovelEntity> findAll() {return iNovelService.findAll();}/*** @description: 獲取表中所有數據的個數* @return: long*/@RequestMapping("count")public long count() {return iNovelService.count();}/*** @description: 向表中插入或更新一條數據* @param: novelEntity* @return: java.util.Map<java.lang.String,java.lang.Boolean>*/@RequestMapping(value = "save", method = RequestMethod.POST)public Map<String, Boolean> saveNovel(NovelEntity novelEntity) {Map<String, Boolean> map = new HashMap<>();try {iNovelService.saveNovel(novelEntity);map.put("status", true);} catch (Exception e) {e.printStackTrace();map.put("status", false);}return map;}/*** @description: 通過小說作者和小說類型來查詢數據* @param: author(小說作者),在url中可不指明author參數,默認值為“天蠶土豆”* @param: type(小說類型),在url中必須指明type參數* @return: java.util.List<com.study.spring.entity.NovelEntity>*/@RequestMapping(value = "findByAuthorAndType", method = RequestMethod.GET)public List<NovelEntity> findByAuthorAndType(@RequestParam(value = "author", required = false, defaultValue = "天蠶土豆") String author,@RequestParam(value = "type") String type) {List<NovelEntity> neList;neList = iNovelService.findByAuthorAndType(author, type);return neList;}/*** @description: 根據表的id來刪除數據* @param: id* @return: java.util.Map<java.lang.String,java.lang.Boolean>*/@RequestMapping(value = "id/{id}", method = RequestMethod.DELETE)public Map<String, Boolean> deleteById(@PathVariable("id") Long id) {Map<String, Boolean> map = new HashMap<>();// 根據id判斷數據是否存在boolean exists = iNovelService.exists(id);try {if (exists) {// 如果數據存在,則刪除該數據。iNovelService.deleteById(id);map.put("status", true);} else {map.put("status", false);}} catch (Exception e) {e.printStackTrace();map.put("status", false);}return map;}/*** @description: 根據小說名稱來刪除數據* @param: novelName* @return: java.util.Map<java.lang.String,java.lang.Boolean>*/@RequestMapping(value = "deleteByNovelName", method = RequestMethod.DELETE)public Map<String, Boolean> deleteByNovelName(@RequestParam(value = "novelName", required = false) String novelName) {Map<String, Boolean> map = new HashMap<>();try {iNovelService.deleteByNovelName(novelName);map.put("status", true);} catch (Exception e) {e.printStackTrace();map.put("status", false);}return map;} }說明:
- 需要在Controller層的類上面加入注解@RestController與@RequestMapping(“xxx”)
- 通過注解@Autowired來引用Service層的接口INovelService
- 前后端參數交互使用@RequestParam,默認必須在url中指明參數,如果不需要指明該參數,可以使用@required = false,詳情可參考上述代碼中的findByAuthorAndType()。
- url參數使用還可使用@PathVariable,該注解的參數僅限于url傳參,具體使用可參考上述代碼的deleteById()。
四、功能測試
通過Jrebel v2018.2.2來啟動spring boot程序,可以實現熱部署(代碼修改即時生效)。
查詢所有數據
瀏覽器訪問http://localhost:8081/spring-boot-study/novel/list查詢所有數據,如下圖所示:
獲取表中所有數據的個數
瀏覽器訪問http://localhost:8081/spring-boot-study/novel/count,獲取表中數據個數,如下圖所示:
插入或更新數據
通過小說作者和小說類型來查詢數據
瀏覽器訪問http://localhost:8081/spring-boot-study/novel/findByAuthorAndType?author=天蠶土豆&type=已完結,如下圖所示:
根據表的id來刪除數據
根據小說名稱來刪除數據
五、注解概述
1. @Entity:對實體注釋
2. @Table:聲明此對象映射到數據庫的數據表
3. @Id:聲明此屬性為主鍵
4. @Column:聲明該屬性與數據庫字段的映射關系。
5. @Service注解:用于標注Service層組件,標注在實現類上。
6. @Autowired
這是一個非常常見的注解。
比如在上述代碼示例中所示:在Controller層,需要使用@Autowired來調用Service層;在Service層,需要使用@Autowired來調用DAO層;在DAO層實現類中,通過@Autowired來調用JdbcTemplate。
7. @RestController
Spring4之后新加入的注解,原來返回json需要@ResponseBody和@Controller配合。即@RestController是@ResponseBody和@Controller的組合注解。
8. @RequestMapping :配置url映射
9. @PathVariable:url參數化
當使用@RequestMapping URI template樣式映射時, 即someUrl/{paramId},這時的paramId可通過 @Pathvariable注解綁定它傳過來的值到方法的參數上。具體可見上述實例的刪除代碼邏輯。
10. @RequestParam
@RequestParam來映射請求參數,required表示是否必須,默認為true,defaultValue可設置請求參數的默認值,value為接收前臺參數的參數名。
11. @Query
可在該注解上編寫JPQL語句,例如:@Query("select nt from NovelEntity nt where nt.novelAuthor = ?1 and nt.type = ?2")
12. @Modifying
與注解@Query一起使用,@Modifying一般適用于增加/修改/刪除的JPQL語句,例如:@Query("delete from NovelEntity nt where nt.novelName = ?1")
13. @Transactional
事務注解。在本篇文章中,@Query("delete from NovelEntity nt where nt.novelName = ?1")之上需要添加注解@Modifying和@Transactional,否則會報錯。
六、總結
前面寫了這么多,可算到總結了。現在用幾句話來概括一下:
- 首先需要創建數據庫,數據表
- 修改yml配置文件,配置datasource與jpa
- 在pom文件中引入相關依賴
- 具體編碼。編寫Entity類,然后通過繼承JpaRepository接口來操作Mysql,也可以自定義編寫JPQL語句,最后在Service層實現業務邏輯,在Controller層制作api展示數據。
- 會使用基礎注解
源碼已上傳至https://github.com/841809077/spring-boot-study,歡迎Star。
總結
以上是生活随笔為你收集整理的spring boot通过JPA访问Mysql的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: DOM2和DOM3
- 下一篇: DIV Scroll属性