成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

[Java][數(shù)據(jù)庫工具][坑] Juice README

CoXie / 1807人閱讀

摘要:注意供應(yīng)器只會在倉庫工廠第一次創(chuàng)建工廠時調(diào)用,而參數(shù)處理器和結(jié)果解析器將在每次倉庫方法被調(diào)用時調(diào)用。解析器接收一個語句表模型的類聲明觸發(fā)解析器的倉庫方法聲明。因此當(dāng)您配置了一個結(jié)果解析器,語句的執(zhí)行時機將推遲到這里。

Juice

這是我自己做的一個小項目,也可能會棄坑... 留作紀(jì)念吧。GitHub 地址

簡介

Juice 是一個簡易的、尚不完善的基于 JavaSQL數(shù)據(jù)庫工具,它提供了對SQL語句最大程度的控制,和一點簡單的擴展能力。

這些是開發(fā)時的一點筆記:
做個數(shù)據(jù)庫幫助庫雛形
做個數(shù)據(jù)庫幫助庫雛形2

使用效果
RepositoryFactory factory = RepositoryFactory.configure(ConnectionConfiguration.builder()
                .driverClass("com.mysql.jdbc.Driver")
                .connectionURL("jdbc:mysql://localhost:3306/hsc")
                .username("gdpi")
                .password("gdpi")
                .build());

StudentRepository repository = factory.get(StudentRepository.class);

List studentList = repository.findAll();
// LinkedList size: 56

Student student = repository.getNameById("20152203300");
// {name: "krun", id: null, college: null, ...}

int count = repository.updateGenderById("20152203300", "男");
// 1

Student student2 = repository.findById("20152203300");
// {name: "krun", id: "20152203300", gender: "男",  major: "軟件技術(shù)", ...}
功能與使用

使用 Juice 只需要簡單的幾步:

注: 本示例使用 lombokmysql-connector(5.1.44)

數(shù)據(jù)庫連接配置: ConnectionConfiguration

當(dāng)前版本的 Juice 只需要以下幾個參數(shù)用以連接數(shù)據(jù)庫:

driverClass:這個參數(shù)用于向驅(qū)動管理器注冊一個數(shù)據(jù)庫連接驅(qū)動。(本示例將使用 com.mysql.jdbc.Driver)

connectionURL: 這個參數(shù)用于向驅(qū)動管理器獲取一個數(shù)據(jù)庫連接,常用的如:jdbc:mysql://localhost:3306/juice,您可以附帶任何連接語句中允許附加的參數(shù),如字符編碼設(shè)置等等。

username: 這個參數(shù)是獲取數(shù)據(jù)庫連接時所需要的數(shù)據(jù)庫賬戶名

password: 這個參數(shù)是獲取數(shù)據(jù)庫連接時所需要的數(shù)據(jù)庫密碼

不建議直接在 connectionURL中配置連接所需的數(shù)據(jù)庫賬戶及密碼。

在未來的版本中,Juice會嘗試加入對 *.properties文件的支持,如此一來,您可以直接在 *.properties文件中設(shè)置連接的詳細(xì)參數(shù)。對MySQL適用的 properties選項請參見這里。

在 Java SE 環(huán)境中,您可以通過 ConnectionConfiguration.builder()構(gòu)造器來構(gòu)造一個配置:

ConnecetionConfiguration conf = ConnectionConfiguration.builder()
                                      .driverClass("com.mysql.jdbc.Driver")
                                      .connectionURL("jdbc:mysql://localhost:3306/juice")
                                      .username("gdpi")
                                      .password("gdpi")
                                      .build();

如果是類似 Spring 這樣可以配置 Bean實例的環(huán)境中,您可以使用類似如下的方式來以Bean的方式創(chuàng)建一個配置:

 
     
     
     
     
倉庫工廠: RepositoryFactory

倉庫工廠是創(chuàng)建、管理倉庫的地方。Juice 允許在一個 Java Application 中存在多個倉庫工廠的實例,但由于每個倉庫工廠都會持有一個 數(shù)據(jù)庫連接供應(yīng)器(ConnectionProvider) ,因此建議使用默認(rèn)全局工廠。

每個工廠都由一個自己的名字,默認(rèn)全局工廠的名字為: global, 這并不是一個常量值,為了避免某些情況下發(fā)生沖突,Juice 允許你在創(chuàng)建前修改 RepositoryFactory.FACTORY_GLOBAL 的值來更改默認(rèn)全局工廠的名字。請注意,如果您在創(chuàng)建全局工廠后修改了該值,那么再次使用 不指定名稱的工廠獲取方法(RepositoryFactory.get())將導(dǎo)致重新創(chuàng)建一個以新值命名的全局工廠。

在使用倉庫工廠前,需要傳入一個 ConnectionConfiguration實例,使倉庫工廠得以初始化內(nèi)部的數(shù)據(jù)庫連接供應(yīng)器。

在 Java SE 環(huán)境中,您可以通過下面的方式來配置倉庫工廠:

//這里的 conf 即為前一節(jié)所創(chuàng)建的數(shù)據(jù)庫連接配置

// 配置全局倉庫工廠
RepositoryFactory globalFactory = RepositoryFactory.configure(conf);

// 配置指定名稱的倉庫工廠
RepositoryFactory fooFactory = RepositoryFactory.configure("foo", conf);

// 請注意,使用第二種方式配置工廠時,使用默認(rèn)全局工廠名稱將拋出錯誤,因為這會破壞 API 所劃分的全局、特定工廠的界限
RepositoryFactory wrongFactory = RepositoyFactory.configure(RepositoryFactory.FACTORY_GLOBAL, conf);
// > RuntimeException

如果是類似 Spring 這樣可以配置 Bean實例的環(huán)境中,您可以使用類似如下的方式來以Bean的方式創(chuàng)建倉庫工廠:

 
     


 
      
     

在配置倉庫工廠后,您可以通過 RepositoryFactory.get()RepositoyFactory.get(name)來獲取全局或給定名稱的倉庫工廠。

表模型

Juice 可以將您給定的一個 Java 類視為一個表模型,就像下面這樣:

@Data
@Entity("student")
public class Student {

   private String id;

   @Column("class")
   private String clazz;

   private int code;
   private String college;
   private String gender;
   private int grade;
   private String major;
   private String name;

}

@Data 注解來自 lombok

@Entity 注解是一個可選項,它只有一個必填屬性: value。當(dāng)配置該注解時,Juice將使用該值作為表名;如果您指定了這個類是個表模型,Juice 卻找不到該注解時,將使用類名的全小寫形式作為表名。

@Column注解同樣是一個可選項,它只有一個必填屬性: value。當(dāng)配置該注解時,Juice將使用該值作為數(shù)據(jù)庫中此表的字段名,否則使用 Java 類字段名作為數(shù)據(jù)庫中此表的字段名。

倉庫: Repository

Repository 是一個注解,它實際上只是一個用于表明某個接口是一個倉庫的標(biāo)記。就像下面這樣:

public interface StudentRepository extends Repository {

    @Query (value = "SELECT * FROM %s")
    List findAll();

    @Query (value = "SELECT * FROM %s WHERE id = ?")
    Student findById(String id);

     @Query (value = "UPDATE %s SET gender = ? WHERE id = ?",
            processor = StudentChain.class,
            processMethod = "replaceParameterLocation")
     Integer updateGenderById(String id, String gender);

     @Query ("SELECT name FROM %s WHERE id = ?")
     Student getNameById(String id);

}

Repository需要填入兩個泛型信息,第一個是該倉庫所操作的表模型,第二個是該表模型的主鍵類型。

注: 事實上到目前為止,Juice 并不區(qū)分主鍵和其他字段,只是為了以后完善留下空間。

@Query 注解

由于到目前為止,Juice 短期內(nèi)不會實現(xiàn) 解析方法名并映射為一個SQL操作 這個 feature, 因此需要 @Query 注解來標(biāo)記一個方法,并以此提供一些信息,Juice 提供的擴展能力也在這里體現(xiàn):

@Query注解具有以下七個屬性:

String value: 這個屬性指定了方法所映射的 SQL操作,其中有著一些約定:%s占位符用于 Juice 填充表名,而 ? 占位符是 PreparedStatement 所使用的參數(shù)占位符。由于 Juice 提供簡單的默認(rèn)實現(xiàn),這些默認(rèn)實現(xiàn)使用的就是 PreparedStatement,因此如果您使用了不一樣的Statement實現(xiàn),您可以使用任何與之配合的占位符。注意:如果您選擇了使用 %*系列作為占位符,那么請記得第一個 %s將會被 Juice 用來填充表名。

Class provider: 這個屬性指定了語句供應(yīng)器所處的類,您可以指定任何實現(xiàn)了RepositoryStatementProvider接口的類,默認(rèn)值為 Juiec 提供的DefaultPreparedStatementProvider,詳細(xì)信息請參見下文。

String provideMethod: 這個屬性指定了注解所在方法所使用的語句供應(yīng)器,當(dāng)provider 屬性使用默認(rèn)值時,此屬性無效;默認(rèn)值為注解所在方法的名字或provide。

Class processor: 這個屬性指定了參數(shù)處理器所處的類,您可以指定任何實現(xiàn)了 RepositoryParameterProcessor接口的類,默認(rèn)值為 Juiec 提供的默認(rèn)參數(shù)處理器 DefaultParameterProcessor,詳細(xì)信息請參見下文。

String processMethod: 這個屬性指定了注解所在方法所使用的參數(shù)處理器,當(dāng)processor屬性使用默認(rèn)值時,此屬性無效;默認(rèn)值為注解所在方法的名字或 process。

Class resolver: 這個屬性指定了結(jié)果解析器所處的類,您可以指定任何實現(xiàn)了 RepositoryResultResolver接口的類,默認(rèn)值為 Juiec 提供的 DefaultResultResolver,詳細(xì)信息請參見下文。

String resolveMethod: 這個屬性指定了注解所在方法所使用的結(jié)果解析器,當(dāng)resolver屬性使用默認(rèn)值時,此屬性無效;默認(rèn)值為注解所在方法的名字或 resolve。

注意

您所指定的 provideMethod、processMethod、resolveMethod都必須是靜態(tài)方法,這并無太多考量,只是為了減輕 Juice 的對象管理成本。

語句供應(yīng)器 RepositoryStatementProvider

一個語句供應(yīng)器的方法簽名應(yīng)該如下:

public static Statement provideMethodName(Connection connection, String sql)

供應(yīng)器所在的類是 @Query.provider 的值,方法名是 @Query.provideMethod 的值。

供應(yīng)器接收一個 java.sql.connection@Query.value值,并返回一個 java.sql.statement。

這里的 sql 已經(jīng)填充了表名

這里的Connection可以不關(guān)閉,它會由倉庫工廠進行復(fù)用。

注意:供應(yīng)器只會在倉庫工廠第一次創(chuàng)建工廠時調(diào)用,而參數(shù)處理器和結(jié)果解析器將在每次倉庫方法被調(diào)用時調(diào)用。

如果您希望使用項目所特定的、實現(xiàn)了裝飾器模式的、特殊的Statement實例,可以為方法定義一個、或創(chuàng)建一個全局的語句供應(yīng)器,并為所有方法指定。

也許后期會在 factory 中加入替換默認(rèn)語句供應(yīng)器、參數(shù)處理器、結(jié)果解析器的接口。

默認(rèn)的語句供應(yīng)器 DefaultPreparedStatementProvider.provide將根據(jù)給定 sql創(chuàng)建一個 com.mysql.jdbc.PreparedStatement實例。

參數(shù)處理器 RepositoryParameterProcessor

一個參數(shù)處理器的方法簽名應(yīng)該類似下面這樣(這里對應(yīng)的是 StudentRepository.findById):

public static Statement findById (Statement statement, String id)

處理器所在的類是 @Query.processor的值,方法名是 @Query.processMethod 的值。

處理器接收一個java.sql.statement和具體的參數(shù)列表,并返回一個java.sql.statement

如果您希望在每次方法調(diào)用時都有個地方可以記錄日志、進行參數(shù)檢查,可以為其配置一個參數(shù)處理器。

在當(dāng)前版本的 Juice 中,如果您希望處理類似下面這種情況:

public StudentRepository extends Repository {
  
  @Query("INSERT INTO %s (%s) VALUES (%s)")
  Integer insert(Student student);
  
}

您需要為其配置一個語句供應(yīng)器:

public static Statement insert(Connection connection, String sql) {
    return connection.prepareStatement(
      String.format(sql,
        StringUtils.convertObjectFields2StringList(Student.class)));
}

和一個參數(shù)處理器:

public static Statement insert(Statement statement, Student student) {
    PreparedStatement ps = (PreparedStatement) statement;
      for (Field field : student.getClass().getDeclaringFields()) {
      field.setAccessable(true);
      ps.setObject(index, field.get(student));
    }
}

以上均為偽代碼

Juice 所提供的默認(rèn)參數(shù)處理器 DefaultParameterProcessor,只是簡單得把參數(shù)按順序填充入SQL語句中并返回。因此,類似下面這種情況可能會發(fā)生錯誤:

public StudentRepository extends Repository {
    
  @Query("UPDATE %s SET gender = ? WHERE id = ?")
  Integer setGenderById(String id, String gender);
  
}

setGenderById的參數(shù)列表中,id在前,gender·在后,這會使得DefaultParameter.process輸出:

UPDATE student SET gender = {id} WHERE id = {gender}

顯然這是錯誤的。如果要避免這種情況,可以直接把方法的參數(shù)列表按 SQL語句中的參數(shù)順序排放;也可以為其指定一個參數(shù)處理器用以調(diào)整參數(shù)填充順序。

結(jié)果解析器 RepositoryResultResolver

一個結(jié)果解析器的方法簽名應(yīng)該類似下面這樣:

public static Object resolve(Statement statement, Class entityClass, Method method)

解析器所在的類是 @Query.resolver 的值,方法名是@Query.resolveMethod的值。

解析器接收一個java.sql.statement語句、Class表模型的類聲明、Method觸發(fā)解析器的倉庫方法聲明。

這里的 statement 尚未執(zhí)行,因為java.sql.statement.execute系列接口需要一些額外參數(shù),這導(dǎo)致 Juice無法確保一致的行為。因此當(dāng)您配置了一個結(jié)果解析器,語句的執(zhí)行時機將推遲到這里。

Juice 所提供的默認(rèn)解析器 DefaultResultResolver有著很多限制:

只支持解析倉庫所聲明的表模型類型和其List形式

對于 INSERT/UPDATE/DELETE操作,只會返回Integer數(shù)值用以表示該SQL操作影響的行數(shù)

不支持表模型字段含有其他非SQL types類型的遞歸、嵌套解析

因此,如果您希望能解析復(fù)雜的結(jié)果,例如將前一節(jié)中的 insert操作返回插入后的結(jié)果并映射為一個Student:

public StudentRepository extends Repository {
    
  @Query("UPDATE %s SET gender = ? WHERE id = ?")
  Student setGenderById(String id, String gender);
  
}

那么還需要配置一個結(jié)果解析器:

public static Student insert(Statement statement, Class entityClass, Method method) {
    // 解析邏輯...
}
結(jié)束

那么, Juice 的介紹、使用幫助就到此結(jié)束了,感謝您的觀看 : )

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/70572.html

相關(guān)文章

  • 如何寫好技術(shù)簡歷 —— 實例、模板及工具

    摘要:在線簡歷生成工具,可以導(dǎo)出。技巧目前寫簡歷的方式有兩種普遍被認(rèn)可,一種是一種是。培養(yǎng)新人和帶團隊其他項目項目該項目是,使用技術(shù),完成功能。閱讀原文點擊查看簡歷模板。 工欲善其事必先利其器,這是自古以來的道理,所以如果想找到一份好的工作,一定要先整理一份好的簡歷。 模板 寫簡歷首先要有一個好的模板,我們做技術(shù)的不同于 UX,UED,我們不需要那么花哨,但是也需要整潔干凈。好的模板能讓你的...

    sunnyxd 評論0 收藏0
  • ES6入門筆記(一)

    摘要:用聲明的常量無法在后面的代碼中改值。表達(dá)式里還有一個很方便的就是表達(dá)式,舉個例子運行結(jié)果為后聲明的里以數(shù)組的形式存放了函數(shù)的剩余參數(shù),是不是很方便。 ES6入門筆記(一) 安裝babel 由于瀏覽器對ES6的支持還不是很好,編寫ES6代碼前我們要安裝一個babel工具將ES6代碼編譯成ES5代碼,用如下命令安裝babel: npm install -g babel-core ...

    warkiz 評論0 收藏0
  • Java 8之stream實際應(yīng)用

    摘要:前言在前面的之介紹和使用和之進階中講了的使用方式和一些常用的方法,這篇文章就來演示一下的實際應(yīng)用。實際應(yīng)用先創(chuàng)建一個訂單類和商品類,每個訂單都有年份商品數(shù)量和商品對象屬性,而商品類里面則包含了名字和價格屬性。 前言: 在前面的 Java 8之stream介紹和使用 和 Java 8之stream進階 中講了stream的使用方式和一些常用的方法,這篇文章就來演示一下stream的實際應(yīng)...

    jonh_felix 評論0 收藏0
  • 設(shè)計模式(10)狀態(tài)模式(講解+應(yīng)用)

    摘要:狀態(tài)模式對于對象內(nèi)部的狀態(tài),允許其在不同的狀態(tài)下,擁有不同的行為,對狀態(tài)單獨封裝成類。通過什么來舉例子呢設(shè)計到多狀態(tài),不同狀態(tài)下各自具有不同行為的東西,而且理解起來相對容易的。下篇更新適配器模式 目錄 狀態(tài)模式 為什么使用狀態(tài)模式? 應(yīng)用實例 狀態(tài)模式 狀態(tài)模式,顧名思義,肯定是和狀態(tài)有關(guān),進一步思考,我們在討論的是設(shè)計模式,設(shè)計模式中的重要原則對變化的進行封裝,順著這個思路去想,...

    lakeside 評論0 收藏0

發(fā)表評論

0條評論

CoXie

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<