前言
PostgreSQL 可以直接存盤二進制欄位,而上周我學習了通過Protobuf來做grpc通信格式,當然也是可以序列化為二進制存入資料庫的,需要的時候從資料庫查詢出來,通過protobuf來轉成對應的Java物件,本文就是來嘗試一下這個思路,
PostgreSQL 安裝
使用docker來安裝PostgreSQL, 參照網站https://hub.docker.com/_/postgres
命令如下
docker run --name my-postgres -p 5432:5432 -e POSTGRES_PASSWORD=kentest123$# -d postgres
以上命令會去下載postgresql的image,并運行起來, 如果需要我們程式訪問,-p一定要加上,把埠打開,不然程式不能連過去,
docker啟動后,可以使用如下命令,同時sh來查看資料庫資源
docker exec -it my-postgres sh
再執行psql可以輸入select陳述句
psql -U postgres
\l 是顯示所有資料庫
\c 資料庫名; 切換到某個資料庫,我們使用用戶postgres,默認會進入名為postgre的資料庫
\d 是查看資料庫中所有表
\d 表名是查看表的定義,
查看表的大小
select pg_size_pretty(pg_relation_size('customer')) as size;
代碼撰寫
這里直接用JPA來完成資料對資料庫的訪問
定義一個物體
@Entity
@Table(name = "market_price_byte")
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class MarketPriceByte implements Serializable {
@Id
private String id;
@Column(name = "values", nullable = false)
private byte[] values;
}
MarketPriceByte 對應資料庫market_price_byte, 兩個欄位一個是id, 一個是byte陣列,后面用來存我們的protobuf,
定義protobuf檔案
定義一個proto檔案pricevalue.proto
syntax = "proto3";
option java_multiple_files = true;
option java_package = "ken.postgresql.proto";
option java_outer_classname = "PriceValueProto";
option objc_class_prefix = "HLW";
package proto;
message PriceValue {
sint32 date = 1;
double open = 2;
double high = 3;
double low = 4;
double close = 5;
}
message PriceValues {
repeated PriceValue price_value = https://www.cnblogs.com/dk168/archive/2023/02/12/1;
}
PriceValue表示一天的股票價格, PriceValues是歷史價格,我們就是把它序列化后存入到ProgresSQL里面,
使用上篇用到的maven插件生成對應的Java類
撰寫代碼
首先我們定義一個JpaRepository用來存取資料庫記錄
public interface MarketPriceByteRepository extends JpaRepository<MarketPriceByte, String> {
}
在組態檔中設定資料庫配置
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=kentest123$#
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.hibernate.ddl-auto 設定成 update,是代碼有更新的時候,同步更新資料庫表
撰寫一個Service用來存資料到資料庫和從資料庫取資料
@Service
@Slf4j
public class MarketPriceService {
@Autowired
private MarketPriceByteRepository repository;
public void createMarketPrice() {
MarketPriceByte newMarketPrice = new MarketPriceByte();
newMarketPrice.setId("0000000001");
PriceValue priceValue = https://www.cnblogs.com/dk168/archive/2023/02/12/PriceValue.newBuilder()
.setDate(100)
.setOpen(1.01)
.setHigh(1.12)
.setLow(1.00)
.setClose(1.11).build();
PriceValue priceValue2 = PriceValue.newBuilder()
.setDate(101)
.setOpen(2.01)
.setHigh(2.12)
.setLow(2.00)
.setClose(2.11).build();
PriceValues priceValues = PriceValues.newBuilder()
.addPriceValue(priceValue)
.addPriceValue(priceValue2)
.build();
newMarketPrice.setValues(priceValues.toByteArray());
log.info("Saving new MarketPrice...");
this.repository.save(newMarketPrice);
}
public void queryAllMarketPrices() {
List<MarketPriceByte> allMarketPrices = this.repository.findAll();
log.info("Number of MarketPrices: " + allMarketPrices.size());
if(allMarketPrices.size() > 0)
{
MarketPriceByte marketPriceByte = allMarketPrices.get(0);
log.info(marketPriceByte.getId());
byte[] values = marketPriceByte.getValues();
try {
PriceValues priceValues = PriceValues.parseFrom(values);
PriceValue priceValue1 = priceValues.getPriceValue(0);
PriceValue priceValue2 = priceValues.getPriceValue(1);
log.info(priceValue1.toString());
log.info(priceValue2.toString());
} catch (InvalidProtocolBufferException e) {
throw new RuntimeException(e);
}
}
}
}
createMarketPrice 我們hardcode了一個MarketPriceByte物件,Java物件序列化為protobuf
priceValues.toByteArray()
然后通過MarketPriceByteRepository存入資料庫
queryAllMarketPrices 將我們存入的資料查詢出來,完成從byte[] 轉成 Java物件 “PriceValues.parseFrom(values)”
呼叫代碼:
marketPriceService.createMarketPrice();
marketPriceService.queryAllMarketPrices();
呼叫后,我們到資料庫查詢,可以看到我們hardcode的那條記錄

這樣就完成了把protobuf物件存入到progresql資料庫,
總結
上面的代碼比較簡單,但對于第一次接觸的同學還是有些作業在這里面, 比如docker里面運行postgresql, JPA是否支持postgresql定義的二進制欄位, Protobuf生成的物件怎么轉成byte[]
這些東西雖然簡單,但是也只有自己動手寫一寫,才印象比較深刻,才更好的理解,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/543656.html
標籤:其他
下一篇:11-verilog-有限狀態機
