Ribbon 是Netflix公司提供的負載均衡客戶端,一般應用於服務的消費方法;Ribbon 可以解決基於負載均衡策略進行服務調用, 所有策略都會實現IRule介面;Ribbon 內置的負載策略有8種,可以通過查看IRule介面的實現類進行分析;@LoadBalanced的作用是描述RestTem... ...
前言
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 = 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 = 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[]
這些東西雖然簡單,但是也只有自己動手寫一寫,才印象比較深刻,才更好的理解。