springboot jpaRepository為何一定要對(duì)Entity序列化
springboot jpaRepository對(duì)Entity序列化
1. 問(wèn)題
一開始,我沒有對(duì)實(shí)體類Inventory序列化,導(dǎo)致在使用內(nèi)嵌數(shù)據(jù)庫(kù)H2的JPA時(shí),它直接安裝字母序列把表Inventory的字段生成。
舉例,原來(lái)我按照
inventory(id, name, quantity, type, comment)
順序?qū)懙臄?shù)據(jù)庫(kù)導(dǎo)入表,但是因?yàn)闆]有序列化,導(dǎo)致表結(jié)構(gòu)變成
inventory(id, comment,name, quantity, type )
所以后面JPA處理失敗。
2. 寫個(gè)基本的JpaRepository的使用
順便記錄一下寫spring cloud 基于和H2 database的jpa簡(jiǎn)單restful 程序。
實(shí)體類Inventory
package com.example.demo; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.SequenceGenerator; @Entity public class Inventory implements Serializable{ private static final long serialVersionUID = 1L; @Id @SequenceGenerator(name="inventory_generator", sequenceName="inventory_sequence", initialValue = 2) @GeneratedValue(generator = "inventory_generator") private Integer id; @Column(nullable = false) private String name; @Column(nullable = false) private Integer quantity; @Column(nullable = false) private Integer type; @Column(nullable = false) private String comment; public Inventory(Integer id, String name, Integer quantity, Integer type, String comment) { super(); this.id = id; this.name = name; this.quantity = quantity; this.type = type; this.comment = comment; } public Inventory() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getQuantity() { return quantity; } public void setQuantity(Integer quantity) { this.quantity = quantity; } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public String getComment() { return comment; } public void setComment(String comment) { this.comment = comment; } @Override public String toString() { return "Inventory [id=" + id + ", name=" + name + ", quantity=" + quantity + ", type=" + type + ", comment=" + comment + "]"; } }
下面使用JpaRepository簡(jiǎn)化開發(fā)流程,非常舒服地定義簡(jiǎn)單的service 接口即可,會(huì)自動(dòng)實(shí)現(xiàn),大贊。
package com.example.demo; import org.springframework.data.jpa.repository.JpaRepository; public interface InventoryRepository extends JpaRepository<Inventory, Integer> { Inventory findById(Integer id); }
我把controller方法放到了springboot啟動(dòng)類里面,這又是一個(gè)大問(wèn)題,因?yàn)槲业捻?xiàng)目只有放在這才能被dispatcher轉(zhuǎn)發(fā),簡(jiǎn)直了。
這里的@EnableDiscoveryClient 是因?yàn)槲以谧鰏pring cloud的eureka 服務(wù)發(fā)現(xiàn),需要這個(gè)注解讓注冊(cè)中心發(fā)現(xiàn)這個(gè)服務(wù)。
package com.example.demo; import java.time.LocalTime; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @SpringBootApplication @EnableDiscoveryClient @RestController public class InventoryApplication { public static void main(String[] args) { SpringApplication.run(InventoryApplication.class, args); } @Autowired private InventoryRepository inventoryRepository; @Value("${server.port}") private Integer port; @RequestMapping("/info") public String info(){ inventoryRepository.save(new Inventory(1, "火鍋底料", 10000, 1, "你吃火鍋,我吃底料")); inventoryRepository.save(new Inventory(2, "微服務(wù)架構(gòu)", 100, 2, "微服務(wù)還是要考慮 一波")); return "{Inventory[port:"+port+", info:庫(kù)存微服務(wù)"+"]}"; } @GetMapping("/get/{id}") @ResponseBody @Transactional public String getById(@PathVariable("id")Integer id){ return inventoryRepository.findById(id).toString(); } @GetMapping("/") @ResponseBody @Transactional public String re(){ return inventoryRepository.findAll().toString(); } @GetMapping("/delete/{id}") @ResponseBody @Transactional public String delete(@PathVariable("id")Integer id){ inventoryRepository.delete(id); return "delete successfully"; } @GetMapping("/save/id={id}&name={name}&quantity={quantity}&type={type}&comment={comment}") /* @ResponseBody @Transactional*/ public String save(@PathVariable("id")Integer id,@PathVariable("name")String name, @PathVariable("quantity")Integer quantity,@PathVariable("type")Integer type, @PathVariable("comment")String comment){ inventoryRepository.save(new Inventory(id,name,quantity,type,comment)); System.out.println(new Inventory(id,name,quantity,type,comment)); //強(qiáng)調(diào)一下identity和auto return "save successfully"; } @GetMapping("/update/id={id}&name={name}&quantity={quantity}&type={type}&comment={comment}") @ResponseBody @Transactional public String update(@PathVariable("id")Integer id,@PathVariable("name")String name, @PathVariable("quantity")Integer quantity,@PathVariable("type")Integer type, @PathVariable("comment")String comment){ Inventory inventory=inventoryRepository.findById(id); if(inventory.getComment().length()<LocalTime.now().toString().length()){ inventory.setComment(inventory.getComment()+LocalTime.now()); }else{ inventory.setComment(inventory.getComment().substring(0,inventory.getComment().length()- LocalTime.now().toString().length())+LocalTime.now()); } inventoryRepository.save(inventory); inventoryRepository.flush(); return "update successfully"; } }
application.properties的配置很關(guān)鍵,搜了不少教程。
spring.jpa.show-sql=true logging.pattern.level=trace server.port=8765 spring.application.name=inventory server.tomcat.max-threads=1000 eureka.instance.leaseRenewalIntervalInSeconds= 10 eureka.client.registryFetchIntervalSeconds= 5 eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka #eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.instance.server.port}/eureka #spring.thymeleaf.prefix=classpath:/templates/ #spring.thymeleaf.suffix=.html #spring.thymeleaf.mode=HTML5 #spring.thymeleaf.encoding=UTF-8 # ;charset=<encoding> is added #spring.thymeleaf.content-type=text/html # set to false for hot refresh spring.h2.console.enabled=true spring.thymeleaf.cache=false spring.jpa.hibernate.ddl-auto=update #這里是把h2持久化到本地文件夾,這可以保持?jǐn)?shù)據(jù) spring.datasource.url=jdbc:h2:file:C\:/h2/h2cache;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1 logging.file=c\:/h2/logging.log logging.level.org.hibernate=debug #spring.datasource.data=classpath:import.sql
數(shù)據(jù)庫(kù)是自動(dòng)導(dǎo)入的,只要命名方式是import.sql, 放在src/main/resources下面就可以
insert into inventory(id, name, quantity, type, comment) values (1, "火鍋底料", 10000, 1, "你吃火鍋,我吃底料") insert into inventory(id, name, quantity, type, comment) values (2, "微服務(wù)架構(gòu)", 100, 2, "微服務(wù)還是要考慮 一波")
最后一個(gè)簡(jiǎn)單的測(cè)試
junit測(cè)試一波
package com.example.demo; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; @RunWith(SpringRunner.class) @SpringBootTest public class InventoryApplicationTests { @Autowired private InventoryRepository inventoriRepository; @Test public void test2() { System.out.println(inventoriRepository.findAll()); } }
上圖是項(xiàng)目結(jié)構(gòu)圖
springboot 使用JpaRepository
在對(duì)數(shù)據(jù)庫(kù)操作時(shí)使用 MissionInfoRepository,對(duì)應(yīng)的實(shí)體類必須用下面兩個(gè)注解修飾
@Entity @Table(name = "mission_info")
主鍵用下面修飾
@Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", nullable = false)
屬性命名如果使用駝峰,例如missionId,表中字段對(duì)應(yīng)mission_id,否則對(duì)數(shù)據(jù)庫(kù)操作的時(shí)候會(huì)報(bào)錯(cuò),所以在表字段定義的時(shí)候,方便代碼里使用JPA的話,表字段定義多個(gè)詞之間用“_”隔開,而不是駝峰定義表字段。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Apache?Maven3.6.0的下載安裝和環(huán)境配置(圖文教程)
本文主要介紹了Apache?Maven3.6.0的下載安裝和環(huán)境配置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07一個(gè)Java中BigDecimal的問(wèn)題記錄
這篇文章主要給大家介紹了關(guān)于Java中一個(gè)BigDecimal問(wèn)題的相關(guān)資料,通過(guò)文中介紹的方法可以很方便的解決BigDecimal進(jìn)行計(jì)算的時(shí)候不管怎么計(jì)算,最后得到的值都沒有變化的問(wèn)題,需要的朋友可以參考下2021-11-11SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過(guò)程
分布式追蹤系統(tǒng)是一個(gè)最終的解決方案,如果您的公司已經(jīng)上了分布式追蹤系統(tǒng),這篇文章主要介紹了SpringBoot?2.5.5整合輕量級(jí)的分布式日志標(biāo)記追蹤神器TLog,需要的朋友可以參考下2022-10-10解決springboot引入swagger2不生效問(wèn)題
這篇文章主要為大家介紹了解決springboot引入swagger2不生效問(wèn)題的方案,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05