Javaデータベースの一般的な操作


一、JDBC駆動
JDBCドライバのロード:
1.コンテナによるロード:
コンテナのあるJavaアプリケーションでは、対応するドライバjarパッケージをコンテナのlibディレクトリの下に直接置くことができます.例えば、Tomcatがコンテナを作るwebアプリケーションでは、tomcatのlibサブディレクトリの下にドライバをコピーします.
2、実行時ロードを適用する:
適切なドライバを自動的にロードするには、mavenがjar/warパッケージを適用するときにドライバjarを検索するclasspathを指定する必要がある場合は、次のを参照してください.
https://maven.apache.org/shared/maven-archiver/examples/classpath.html
https://www.cnblogs.com/snaildev/p/8341610.html
例1(実行可能jarパケットの下にlibディレクトリがあり、依存jarパケットが格納されている):

        image
        
            
                org.apache.maven.plugins
                maven-jar-plugin
                2.4
                
                    
                        
                            true
                            lib/
                            some.package.MainClass
                        
                    
                
            
        
    

業務が自らJDBCドライバをロードする場合、JDBCを適用する前に、以下の操作を実行する必要がある.
Class.forName("com.mysql.jdbc.Driver");
// Then the following begin to use jdbc

二、接続プール(DataSourceの一種)を通じてデータベースとの接続を管理する
現在よく使われている接続プールはDruidまたはHikariで、それぞれ次のように説明されています.
1、Druid接続プール:
maven依存:

    com.alibaba
    druid
    1.1.11

サンプルコード:
DruidDataSource createSource(String name, String jdbcUrl, String userName, String password,
        maxActive, minIdle, maxWait, scanInterval, minActiveTime) {
    DruidDataSource src = DruidDataSource();
    src.setName(name);
    src.setUrl(jdbcUrl);
    src.setUsername(userName);
    src.setPassword(password);
    src.setDriverClassName(); 
    src.setInitialSize(minIdle);
    src.setMaxActive(maxActive);
    src.setMinIdle(minIdle);
    src.setMaxWait(maxWait); 
    src.setTimeBetweenEvictionRunsMillis(scanInterval); 
    src.setMinEvictableIdleTimeMillis(minActiveTime);   
    src.setTestWhileIdle(); 
    src.setTestOnBorrow();  
    src.setTestOnReturn();
    src.setPoolPreparedStatements(); 
    src.setMaxPoolPreparedStatementPerConnectionSize(); 
    src.setValidationQuery(); 
    src.setRemoveAbandoned(); 
    src.setRemoveAbandonedTimeout(); 
    src.setKeepAlive(); 
    if(!isDataSourceOk(src)){
        LOGGER.error("Data source "+ name + "test failed");
    }
    return src;
}
private static boolean isDataSourceOk(DataSource source){
    try (Connection connection = source.getConnection();
         PreparedStatement stmt = connection.prepareStatement("select 1");
         ResultSet resultSet = stmt.executeQuery()){
        resultSet.next();
        return true;
    }catch (Throwable e){
        return false;
    }
}

2、Hikari接続池
maven依存:

    com.zaxxer
    HikariCP
    3.2.0

サンプルコード:
HikariDataSource createSource(String name, String jdbcUrl, String userName, String password,
        connectionTimeout, idleTimeout, maxLifeTime, poolSize) {
    HikariDataSource src = HikariDataSource();
    src.setPoolName(name);
    src.setJdbcUrl(jdbcUrl);
    src.setUsername(userName);
    src.setPassword(password);
    src.setDriverClassName(); 
    src.setConnectionTimeout(connectionTimeout);
    src.setIdleTimeout(idleTimeout); 
    src.setMaxLifetime(maxLifeTime); 
    src.setMaximumPoolSize(poolSize);
    if(!isDataSourceOk(src)){
        LOGGER.error("Data source "+ name + "test failed");
    }
    return src;
}

三、処理接続
1、まず接続プールを通して接続を取得する.例えば:
try(Connection getConnection() SQLException {
    assert DataSourceManager.getDataSource() != null;
    return DataSourceManager.getDataSource().getConnection();
}

2、接続されたSQL要求の提出方式
接続プール(ラウンドDruidDataSourceかHirakiDataSourceか)からConnectionオブジェクトに申請すると、デフォルトのコミット方式は自動コミット、すなわちconnectionが呼び出されます.getAutoCommit()はtrueを返します.
Connectionオブジェクトが接続プールを返却した後、次回接続プールから接続を申請しますが、デフォルトのコミット方式は自動的にコミットされます.いつ自動提出するのか、いつ手作業で提出するのに適しているのかを明らかにする必要があります.
要約すると、Connectionオブジェクトを申請してからConnectionオブジェクトを返却するまでの間、同じConnectionオブジェクトを使用してどのような操作をしましたか.
(1)読み取り操作のみ、書き込み操作なし:自動コミット;
(2)単一テーブルの単一レコードに対して1回だけ書き込み操作がある:自動コミットで;
自動コミットのコード例は次のとおりです.
try(Connection connection = ()) {
    block.apply(connection); // Do all query or only one update for only one record
}

(3)同じテーブルの複数のレコードに対して書き込み操作を行ったか、または異なるテーブルのレコードに対してそれぞれ書き込み操作を行った:ロールバックが必要かどうか、性能要求に基づいて、トランザクションをサポートする必要があるかどうかを確定する;物事性をサポートするには、手動で提出する必要があります.
手動コミットの例:
try(Connection connection = ()) {
    boolean success = false;
    try{
        T t = block.apply(connection); // Use this connection process one transaction
        doCommit(connection);
        success = true;
        return t;
    }finally{
        if(!success) {
            doRollback(connection); // If possible, support rollback when failed
        }
    }
}

       block    connection          ,          ,  doCommit() doRollback()     :

public static void doCommit(Connection connection) throws SQLException {
    if (!connection.getAutoCommit()) {
        connection.commit();
    }
}
private static void doRollback(Connection connection) throws SQLException {
    if (SUPPORT_ROLLBACK && !connection.getAutoCommit()) {
        connection.rollback();
    }
}

(4)時間のかかる操作で、データ量が比較的大きい場合、データベースに依存する事物性とロールバックはもう達成できない.この場合、複数回に分けてコミットし、アプリケーション層がロールバックを提供する必要があります.
例は次のとおりです.
try(Connection connection = ()) {
    boolean success = false;
    try{
        block1.accept(connection);
        doCommit(connection);
        block2.accept(connection);
        doCommit(connection);
        success = true;
    }finally{
        if(!success) {
            block2.clear(connection);
            block1.clear(connection);
        }
    }
}