日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jdbc查询序列_JDBC –模拟序列

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jdbc查询序列_JDBC –模拟序列 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

jdbc查詢序列

也許我們每個人在程序員的生活中至少遇到過一次這個問題- 如何模擬數據庫序列? 在下面,您可能會發現我對該問題解決方案的各種了解。

假設我們有一個接口定義了所需的API,用于返回整數序列:

public interface Sequences { int nextValue(String sequenceName) throws SQLException; }

并以以下形式實現此API:

class SequencesService implements Sequences { private static final String SQL_QUERY = "SELECT SEQ_NAME, SEQ_VALUE FROM SEQUENCE WHERE SEQ_NAME = ? FOR UPDATE" ; private final DataSource dataSource; SequencesService( final DataSource dataSource) { this .dataSource = dataSource; } @Override public int nextValue( final String sequenceName) throws SQLException { final long threadId = Thread.currentThread().getId(); try ( final Connection connection = dataSource.getConnection()) { connection.setAutoCommit( false ); try ( final PreparedStatement statement = connection.prepareStatement( SQL_QUERY, TYPE_SCROLL_SENSITIVE, CONCUR_UPDATABLE)) { statement.setString( 1 , sequenceName); try ( final ResultSet resultSet = statement.executeQuery()) { System.out.println( String.format( "[%d] - select for update" , threadId)); int nextValue = 1 ; if (resultSet.next()) { nextValue = 1 + resultSet.getInt( 2 ); resultSet.updateInt( 2 , nextValue); resultSet.updateRow(); } else { resultSet.moveToInsertRow(); resultSet.updateString( 1 , sequenceName); resultSet.updateInt( 2 , nextValue); resultSet.insertRow(); } System.out.println( String.format( "[%d] - next val: %d" , threadId, nextValue)); return nextValue; } } finally { System.out.println(String.format( "[%d] - commit" , threadId)); "[%d] - commit" , threadId)); connection.commit(); } } } }

您必須原諒我兩件事:) –我添加println的用法是為了生成一些視覺反饋;)并且缺少詳細的解釋說明此解決方案的工作原理;)我只想提一下線索是準備好的語句的處理方式創建并處理結果集:updateRow / moveToInsertRow / insertRow用法;)(有關詳細信息,請參見本文底部的鏈接)。

我編寫了簡單的測試用例來觀察和驗證此代碼,例如:

@Autowired private Sequences sequences; private Callable<Integer> callable() { return () -> { System.out.println(String.format( "[%d] - starting" , Thread.currentThread().getId())); "[%d] - starting" , Thread.currentThread().getId())); return sequences.nextValue( "My Sequence" ); }; } @Test public void test() throws Exception { final ExecutorService executor = Executors.newFixedThreadPool( 3 ); final CompletionService<Integer> completion = new ExecutorCompletionService<>(executor); for ( int i = 0 ; i < 3 ; i++) { completion.submit(callable()); } ????for ( int completed = 1 ; completed <= 3 ; completed++) { final Future<Integer> result = completion.take(); System.out.println(String.format( "Result %d - %d" , completed, result.get())); assertEquals(Integer.valueOf(completed), result.get()); } }

運行上述代碼時,輸??出將如下所示(括號中為線程的ID):

[16] –開始 [18] –開始 [17] –開始 [17] –選擇要更新 [17] –下一個值:1 [17] –提交 [18] –選擇要更新 結果1-1 [18] –下一個值:2 [18] –提交 [16] –選擇要更新 [16] –下一個值:3 [16] –提交 結果2 – 2 結果3 – 3

這段代碼僅用于演示目的:) –如果您想在項目中做類似的事情,則可能更愿意將其用于ex。 Spring Framework的@Transactional批注,而不是手動的事務處理,甚至JPA都將這項工作委托給JDBC。 例如,在Hibernate中,您可以這樣進行操作:

import org.hibernate.Session; ... entityManager.unwrap(Session. class ) .doReturningWork(connection -> { ... code derived from my example ... });

甜點的幾個鏈接:

  • 更新ResultSet對象(JDBC)中的行
  • 在ResultSet對象(JDBC)中插入行
  • 聲明式事務管理和使用@Transactional (Spring Framework)
  • ReturningWork(JPA,Hibernate)

…,我差點忘了;)– GitHub存儲庫保存了我所有的這篇文章的代碼經驗

翻譯自: https://www.javacodegeeks.com/2019/08/jdbc-emulating-sequence.html

jdbc查詢序列

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的jdbc查询序列_JDBC –模拟序列的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。