springboot jpaRepository為何一定要對Entity序列化
springboot jpaRepository對Entity序列化
1. 問題
一開始,我沒有對實體類Inventory序列化,導(dǎo)致在使用內(nèi)嵌數(shù)據(jù)庫H2的JPA時,它直接安裝字母序列把表Inventory的字段生成。
舉例,原來我按照
inventory(id, name, quantity, type, comment)
順序?qū)懙臄?shù)據(jù)庫導(dǎo)入表,但是因為沒有序列化,導(dǎo)致表結(jié)構(gòu)變成
inventory(id, comment,name, quantity, type )
所以后面JPA處理失敗。
2. 寫個基本的JpaRepository的使用
順便記錄一下寫spring cloud 基于和H2 database的jpa簡單restful 程序。
實體類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簡化開發(fā)流程,非常舒服地定義簡單的service 接口即可,會自動實現(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啟動類里面,這又是一個大問題,因為我的項目只有放在這才能被dispatcher轉(zhuǎn)發(fā),簡直了。
這里的@EnableDiscoveryClient 是因為我在做spring cloud的eureka 服務(wù)發(fā)現(xiàn),需要這個注解讓注冊中心發(fā)現(xiàn)這個服務(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:庫存微服務(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ù)庫是自動導(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ù)還是要考慮 一波")
最后一個簡單的測試
junit測試一波
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()); } }
上圖是項目結(jié)構(gòu)圖
springboot 使用JpaRepository
在對數(shù)據(jù)庫操作時使用 MissionInfoRepository,對應(yīng)的實體類必須用下面兩個注解修飾
@Entity @Table(name = "mission_info")
主鍵用下面修飾
@Id @GeneratedValue(strategy = IDENTITY) @Column(name = "id", nullable = false)
屬性命名如果使用駝峰,例如missionId,表中字段對應(yīng)mission_id,否則對數(shù)據(jù)庫操作的時候會報錯,所以在表字段定義的時候,方便代碼里使用JPA的話,表字段定義多個詞之間用“_”隔開,而不是駝峰定義表字段。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Apache?Maven3.6.0的下載安裝和環(huán)境配置(圖文教程)
本文主要介紹了Apache?Maven3.6.0的下載安裝和環(huán)境配置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07SpringBoot?2.5.5整合輕量級的分布式日志標(biāo)記追蹤神器TLog的詳細(xì)過程
分布式追蹤系統(tǒng)是一個最終的解決方案,如果您的公司已經(jīng)上了分布式追蹤系統(tǒng),這篇文章主要介紹了SpringBoot?2.5.5整合輕量級的分布式日志標(biāo)記追蹤神器TLog,需要的朋友可以參考下2022-10-10