springboot jpaRepository為何一定要對(duì)Entity序列化
springboot jpaRepository對(duì)Entity序列化
1. 問(wèn)題
一開(kāi)始,我沒(méi)有對(duì)實(shí)體類(lèi)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)闆](méi)有序列化,導(dǎo)致表結(jié)構(gòu)變成
inventory(id, comment,name, quantity, type )
所以后面JPA處理失敗。
2. 寫(xiě)個(gè)基本的JpaRepository的使用
順便記錄一下寫(xiě)spring cloud 基于和H2 database的jpa簡(jiǎn)單restful 程序。
實(shí)體類(lèi)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)化開(kāi)發(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)類(lèi)里面,這又是一個(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í)體類(lèi)必須用下面兩個(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è)詞之間用“_”隔開(kāi),而不是駝峰定義表字段。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Servlet第一個(gè)項(xiàng)目的發(fā)布(入門(mén))
這篇文章主要介紹了Servlet第一個(gè)項(xiàng)目的發(fā)布,下面是用servlet實(shí)現(xiàn)的一個(gè)簡(jiǎn)單的web項(xiàng)目,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
Java如何實(shí)現(xiàn)驗(yàn)證碼驗(yàn)證功能
這篇文章主要教大家如何實(shí)現(xiàn)Java驗(yàn)證碼驗(yàn)證功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
30分鐘入門(mén)Java8之方法引用學(xué)習(xí)
在Java8中,我們可以直接通過(guò)方法引用來(lái)簡(jiǎn)寫(xiě)lambda表達(dá)式中已經(jīng)存在的方法,這篇文章主要介紹了30分鐘入門(mén)Java8之方法引用學(xué)習(xí),有興趣可以了解一下。2017-04-04
SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢(xún)結(jié)果為空
SpringBoot整合Mybatis-plus使用關(guān)鍵詞模糊查詢(xún)的時(shí)候,數(shù)據(jù)庫(kù)中有數(shù)據(jù),但是無(wú)法查找出來(lái),本文就來(lái)介紹一下SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢(xún)結(jié)果為空的解決方法2025-04-04
J2SE基礎(chǔ)之下載eclipse并創(chuàng)建項(xiàng)目
本文給大家介紹的是最流行的java 集成開(kāi)發(fā)環(huán)境IDE eclipse的使用方法,非常的簡(jiǎn)單,有需要的小伙伴可以參考下2016-05-05

