目次
序文
初心者のウェブ開発の簡単な要約でXiaobai(8) -データベースHSQLDBインスタンスこの例で、それだけで、簡単にできるようにするには、データベースの接続および解放に多くの注意を払っていなかったので、Webアプリケーション開発のプロセスを理解しています。今回は、この部分について具体的に要約します。
次のコードは、Xiaobai(8)での初心者のWeb開発の簡単な要約です。この例のデータベースHSQLDBインスタンスは、データベースに接続するためのコードです。
public Statement createStatement() {
try {
Class.forName("org.hsqldb.jdbcDriver");
} catch (ClassNotFoundException e) {
System.out.println("jdbcDriver not found!!!");
return null;
}
try {
//JDBC不支持自增,创建或连接数据库
connection = DriverManager.getConnection(jdbcUrl, jdbcUser, jdbcPassword);
if (connection == null) {
return null;
}
//创建里面的表
Statement statement = connection.createStatement();
return statement;
} catch (SQLException throwables) {
throwables.printStackTrace();
}
return null;
}
ここで使用されるのは、データベースとの接続を確立するためのDriverManangerのgetConnection()ですが、データベースとの接続は元々非常にリソースを消費する操作であり、多くのシステムオーバーヘッドが発生します。したがって、データベース用の接続プールがあります。これは、Javaのスレッドとスレッドプールの概念と同じだと思います。スレッドプールは、スレッドの頻繁な作成と破棄を減らすために生まれました。次に、データベース接続プールは、データベースの頻繁な作成と切断を減らすことです。作成した。
データソースとは
Webアプリケーションがデータベースにアクセスする場合、データベースに直接アクセスするのではなく、データベースの製造元から一般的に提供されているデータベースドライバーを介してデータベースにアクセスします。したがって、データベースのドライバにアクセスするためのJDBCインターフェイスがJava EEに提供され、それによってデータベースにアクセスします。
DataSourceは、作成されたデータベースの接続を管理するデータベース接続コンテナーです。Webアプリケーションがデータベースにアクセスしている場合、DriverManagerを介してデータベースに接続する必要はありませんが、DataSourceから直接Connectionオブジェクトを取得します。次に、データベースに接続します。
データベースドライバと一緒に使用する必要があります。通常、3つの実装形式があります。
- (1)基本的な実装:標準のConnectionオブジェクトを生成するだけで、アクセスすると、接続プールと分散をサポートしない新しいConnectionが生成されます。
- (2)データベース接続プールの実装:接続プールに自動的に参加し、接続プール接続をサポートするが、分散をサポートしない接続オブジェクトを生成します。
- (3)分散実装:分散トランザクションに使用できるConnectionオブジェクトを生成します。このオブジェクトのほとんどは、接続プール接続に参加します。
データソースの種類に関係なく、基本構成、キー構成、パフォーマンス構成など、いくつかの構成を行う必要があります。
基本構成には、主に、データベースにアクセスするためのURL、ユーザー名、パスワード、およびdriverClassが含まれます。
キー構成には、主に、最小接続数、初期接続数、最大接続数、および最大待機時間が含まれます(最初の実装方法では不要)。
パフォーマンス構成には、主にプリキャッシュ設定、接続の有効性の検出、タイムアウト接続の閉鎖設定などが含まれます。
2つの一般的な3つの実装方法
以下は、各アプリケーションの簡単な要約であり、初心者のWeb開発(8)データベースHSQLDBインスタンスの簡単な要約で述べた例に基づいて最適化されています。
1.基本的な実現
Spring自体はorg.springframework.jdbc.datasource.DriverManagerDataSourceを提供します。これは、単純なデータベース接続接続オブジェクトを提供できます。getConnection()が呼び出されるたびに、新しい接続が生成されます。単体テストまたは単純なスタンドアロンアプリケーションに適しています。
- DriverManagerDataSource自体にspringframeworkが付属しているため、pom.xmlに依存関係を追加する必要があります
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
- 次のように、データベースHSQLDBインスタンスでXiaobai初心者のWeb開発(8) -jdbc.propertiesを使用して、データベースのURL、ユーザー、パスワードなどを構成する簡単な要約:
#hsqldb的相关配置
#最后会在apache/bin的目录下生成该数据库
jdbc.url = jdbc:hsqldb:file:db/hsqldb/xbook
jdbc.user = SA
jdbc.password =
jdbc.table = book
jdbc.driverClass=org.hsqldb.jdbcDriver
- resources / configの下にapplication-context-db.xmlファイルを追加して、DriverManagerDataSourceJavaBeanを構成します。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--增加数据库配置的配置文件-->
<context:property-placeholder location="classpath:config/jdbc.properties"/>
<!--简单的一个连接,每次都会新建-->
<bean id="driverManagerDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
</bean>
</beans>
このDriverManagerDataSourceは毎回新しい接続を作成するため、データベース接続プールではないため、データベース接続プールに関連するパラメーターを構成する必要はありません。具体的には、パフォーマンスなどを向上させるためにプロジェクトでどの重要なパラメータを設定する必要があるかについては、今後検討する予定です。
- JdbcDataSourceを増やして、これらのDataSourceインスタンスを取得します
@Component
public class JdbcDataSource {
private DriverManagerDataSource driverManagerDataSource;
public void setDriverManagerDataSource(DriverManagerDataSource driverManagerDataSource{
this.driverManagerDataSource = driverManagerDataSource;
}
@PostConstruct
public void init() {
System.out.println("JdbcTemplate init 。。。。。。 ");
}
public DataSource createDriverManagerDataSource() {
return driverManagerDataSource;
}
}
- 次に、application-context-db.xmlファイルでDriverManagerDataSourceとJdbcDataSourceの間の依存関係も増やします。
<!--处理数据库连接的bean-->
<bean id="jdbcConfiguration" class="com.wj.hsqldb.datasource.JdbcDataSource">
<property name="driverManagerDataSource" ref="driverManagerDataSource"/>
</bean>
残りの質問:構成の依存関係を完了するためにsetDriverManagerDataSource()メソッドを追加する必要があるのはなぜですか( リフレクション関係のため、確率は依存関係のバインディングに関連していると思います。リフレクションプロセスは、setxxxメソッドを介して対応する依存関係を見つけることです。関係の属性)。
- 最後に、Springプロジェクトのweb.xmlファイルにあるapplication-context-db.xmlを読み取り、SpringIoCコンテナーにこれらのJavaBeansをロードさせる必要があります。
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:config/application-context*.xml</param-value>
</context-param>
これらの手順の後、プロジェクトでdriverManagerDataSourceDataSourceインスタンスを直接使用できます。次に、以前のcom.wj.hsqldb.db.JdbcConfigurationをDriverManager.getConnection()を介してdriverManagerDataSource.getConnection()に置き換えます。
2.データベース接続プールの実装
Webアプリケーションが起動すると、データベース接続プールは特定の数のデータベース接続を作成し、最大数以上の接続を維持します。Webアプリケーションがデータベースにアクセスしているとき、データベース接続プールから未使用のデータベース接続を検出し、接続をビジーとしてマークします。空き接続がない場合、新しいデータベース接続が作成されます。使用中の場合データベース接続後が使い果たされると、データベースの接続プールは接続を空きとしてマークし、アクセスされたときにWebアプリケーションが再び使用可能になります。
このプロセスから、スレッドプールの動作メカニズムは実際にはJavaの動作メカニズムと同じであることがわかります。したがって、この場所を理解することは難しくありません。したがって、DataSourceの利点は次のとおりです。
- 1)データベースの接続と切断を頻繁に確立する必要がないため、リソースと時間を節約できます。
- 2)データベースに接続するためにユーザー名とパスワードを頻繁に入力する必要がないため、メモリとCPUのオーバーヘッドを節約できます。
Javaで一般的に使用されるオープンソースデータベース接続プールは次のとおりです。
(1)DBCP
Jakartacommons-poolオブジェクトプールメカニズムに依存するデータベース接続プール。Webアプリケーションで直接使用できます。DBCPはTomcatで使用されます。対応する実装クラスはorg.apache.commons.dbcp.BasicDataSourceです。
DriverManagerDataSourceと同様に、Springプロジェクトを使用するプロセスでは、依存関係を導入し、構成ファイルを順番に追加してから、プロジェクトで直接使用する必要があります。
- 1)BasicDataSourceの依存関係を追加します
<!--DBCP数据源的配置-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
- 2)BasicDataSourceのJavaBeanを(1)Basic Implementationのapplication-context-db.xmlに追加し、それをJdbcDataSource依存関係に追加するだけです。
<!--配置DBCP数据源-->
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="maxActive" value="6"/>
<property name="maxIdle" value="3"/>
</bean>
<!--处理数据库连接的bean-->
<bean id="jdbcConfiguration" class="com.wj.hsqldb.datasource.JdbcDataSource">
<property name="dbcpDataSource" ref="dbcpDataSource"/>
<property name="driverManagerDataSource" ref="driverManagerDataSource"/>
</bean>
BasicDataSourceによって作成されたデータベースの接続プールのため、プロジェクトは徐々に理解するため、ここで調査しないように、最小接続数、初期接続数などのいくつかの重要なパラメーターを構成する必要があります。データベースにアクセスするWebアプリケーションのパフォーマンスに対するこれらのパラメーターの構成は影響します。
さらに、BasicDataSourceのこの属性をJdbcDataSourceに追加する場合は、(1)基本実装で追加されたJdbcDataSourceで2つの間の依存関係を追加する必要があります 。そうしないと、ここにJdbcDataSourceの2つのインスタンスがあり、別のインスタンスでは定義されていない属性を使用することはできません。
- 3)対応するインスタンスBasicDataSourceをJdbcDataSourceに追加します
@Component
public class JdbcDataSource {
private BasicDataSource dbcpDataSource;
private DriverManagerDataSource driverManagerDataSource;
public void setDbcpDataSource(BasicDataSource dbcpDataSource) {
this.dbcpDataSource = dbcpDataSource;
}
public void setDriverManagerDataSource(DriverManagerDataSource driverManagerDataSource{
this.driverManagerDataSource = driverManagerDataSource;
}
@PostConstruct
public void init() {
System.out.println("JdbcTemplate init 。。。。。。 ");
}
public DataSource createBasicDataSource() {
return dbcpDataSource;
}
public DataSource createDriverManagerDataSource() {
return driverManagerDataSource;
}
}
これらの手順の後、プロジェクトでdbcpDataSourceのDataSourceインスタンスを直接使用できます。次に、以前のcom.wj.hsqldb.db.JdbcConfigurationをDriverManager.getConnection()を介してdbcpDataSource.getConnection()に置き換え、データベース接続プールを使用して接続を作成します。
(2)C3P0
DBCPよりも豊富な構成であり、対応する実装クラスはcom.mchange.v2.c3p0.ComboPooledDataSourceです。具体的な使用法は上記と同じです。プロジェクトのapplication-context-db.xmlとJdbcDataSourceの関連コードを参照してください。
(3)HikariCP
速度はC3P0よりも速く、バイトコードはより簡潔で、より多くのコードをキャッシュにロードでき、ロックフリーのコレクションタイプを実現できます。SpringBoot2でデフォルトで使用されるデータベース接続プール。
(4)ドルイド
アリババ製品のTaobaoおよびAlipay専用データベース接続プールは、Oracle、MySql、Postgresqlなど、対応する実装クラスcom.alibaba.druid.pool.DruidDataSourceを含むすべてのJDBC互換データベースをサポートします。DBCPとC3P0を置き換えることで、効率的で強力かつスケーラブルなデータベース接続プールを提供します。
これには3つの部分が含まれます。
- DruidDriver:エージェントドライバー。データベースのアクセスパフォーマンスを監視できます。
- DruidDataSource:効率的で管理しやすいデータベース接続プール
- SQLParse:SQL実行ログを取得します。
具体的な使用法は上記と同じです。プロジェクトのapplication-context-db.xmlおよびJdbcDataSourceの関連コードを参照してください。
次に、上記の4つのデータソースを構成した後、最後に変更されたファイルのコードは次のようになります。
- 1)pom.xmlによって追加された依存関係は次のとおりです。
<!--jdbc接口 Spring对JDBC的封装-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- === 配置数据源 ==== -->
<!--c3p0数据源-->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!--DBCP数据源的配置-->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<!--druid-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.5</version>
</dependency>
- 2)application-context-db.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
<!--增加数据库配置的配置文件-->
<context:property-placeholder location="classpath:config/jdbc.properties"/>
<!--简单的一个连接,每次都会新建-->
<bean id="driverManagerDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
</bean>
<!--数据库连接池-->
<!--配置C3P0数据源-->
<bean id="c3p0DataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="user" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="driverClass" value="${jdbc.driverClass}"/>
<property name="initialPoolSize" value="3"/>
<property name="maxPoolSize" value="6"/>
</bean>
<!--配置DBCP数据源-->
<bean id="dbcpDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="maxActive" value="6"/>
<property name="maxIdle" value="3"/>
</bean>
<!--阿里的-->
<bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
<property name="url" value="${jdbc.url}"/>
<property name="driverClassName" value="${jdbc.driverClass}"/>
</bean>
<!--处理数据库连接的bean-->
<bean id="jdbcConfiguration" class="com.wj.hsqldb.datasource.JdbcDataSource">
<property name="c3p0DataSource" ref="c3p0DataSource"/>
<property name="dbcpDataSource" ref="dbcpDataSource"/>
<property name="driverManagerDataSource" ref="driverManagerDataSource"/>
<property name="druidDataSource" ref="druidDataSource"/>
</bean>
</beans>
- 3)JdbcDataSource
@Component
public class JdbcDataSource {
private ComboPooledDataSource c3p0DataSource;
private BasicDataSource dbcpDataSource;
private DriverManagerDataSource driverManagerDataSource;
private DruidDataSource druidDataSource;
public void setC3p0DataSource(ComboPooledDataSource c3p0DataSource) {
this.c3p0DataSource = c3p0DataSource;
}
public void setDbcpDataSource(BasicDataSource dbcpDataSource) {
this.dbcpDataSource = dbcpDataSource;
}
public void setDriverManagerDataSource(DriverManagerDataSource driverManagerDataSource{
this.driverManagerDataSource = driverManagerDataSource;
}
public void setDruidDataSource(DruidDataSource druidDataSource) {
this.druidDataSource = druidDataSource;
}
@PostConstruct
public void init() {
System.out.println("JdbcTemplate init 。。。。。。 ");
}
public DataSource createComboPoolDataSource() {
return c3p0DataSource;
}
public DataSource createBasicDataSource() {
return dbcpDataSource;
}
public DataSource createDriverManagerDataSource() {
return driverManagerDataSource;
}
public DataSource createDruidDataSource() {
return druidDataSource;
}
}
関連するコードがgithubにアップロードされました:https://github.com/wenjing-bonnie/sql-web.git対応するタグはexample11の関連コードです(プロジェクトは常に更新されるため、このコードはタグ付けによってマークされます) )。
3.分散実装
一部の複雑なWebアプリケーション開発では、アプリケーションに複数のデータベース、つまり複数のデータソースへの接続が含まれる場合があります。一般的に使用される一般的なシナリオを2つ挙げてください。
- 1)読み取り/書き込み分離データベース:読み取りデータベースはさまざまなクエリ操作のみを担当し、書き込みデータベースは追加、削除、および変更を担当します。
- 2)複雑なビジネス:ビジネスプロセスでは、2つのデータベースのデータを同時に読み取ったり変更したりする必要がある場合があります
この種のマルチデータソースアプリケーションは、典型的な分散シナリオです。Springプロジェクトでは、spring-jdbcはorg.springframework.jdbc.datasource.lookup.AbstractRoutingDataSourceを提供します。これには、開発者が定義したルールに従って実行時に現在のデータソースに動的にアクセスできる複数のデータソースを含めることができます。
このAbstractRoutingDataSourceをプロジェクトで使用する方法は、プロジェクトに応じて検討すると思います。これで複数のデータソースをロードできることがわかりましたが、プロジェクトで使用する方法については、プロジェクトで学習する必要があります。
残りの質問:プロジェクトで複数のデータソースを使用するにはどうすればよいですか??
3つの要約
コード例を作成する過程で発生した問題の要約:
1.Springおよびxml構成JavaBeanでのアノテーションの混合使用
Webアプリケーション開発では、一部のJavaBeanがアノテーションを介してインスタンス化され、一部のJavaBeanがxmlを介して構成されることを回避することは困難です。その後、@ Componentによってアノテーションが付けられたクラスに表示されます。xmlで構成されたインスタンスを参照するにはどうすればよいですか? ?
@AutoWritedはタイプに応じて自動的に挿入され、次に@Resourceは名前に応じて自動的に挿入されます。名前とタイプの2つの重要な属性があります。これらの2つの属性が指定されていない場合、デフォルトで名前で検索されます。
@Resourceでは、名前は構成されたxmlファイルの<bean name = "" />と一致し、<bean id = "" />と一致しません。一致するBeanが見つからない場合は、プリミティブ型にフォールバックします。検索; type属性に従って検索すると、注入に一致するタイプを持つ唯一のBeanが見つかります。見つからないか、複数ある場合は、例外がスローされます。両方が一致する場合、唯一のBeanが見つかります。一致します。見つからない場合は例外をスローします。
@Resourceは@Autowiredと同等ですが、@ AutowiredはbyTypeに従って自動的に挿入され、@ ResourceはデフォルトでbyNameに従って自動的に挿入される点が異なります。@Autowiredと@Resourceの両方を使用してBeanをアセンブルでき、どちらもフィールドまたはセッターメソッドに書き込むことができます。
たとえば、BookManagerJdbcService.javaのxmlで構成されたJdbcDataSourceを使用する場合は、次のコードがあります。
@Configuration
public class BookManagerJdbcService {
@Resource(type = JdbcDataSource.class, name = "jdbcDataSource")
private JdbcDataSource jdbcDataSource;
}
application-context-db.xmlのコードは次のとおりです。
<!--处理数据库连接的bean-->
<bean id="jdbcDataSource" class="com.wj.hsqldb.datasource.JdbcDataSource" name="jdbcDataSource">
<property name="c3p0DataSource" ref="c3p0DataSource"/>
<property name="dbcpDataSource" ref="dbcpDataSource"/>
<property name="driverManagerDataSource" ref="driverManagerDataSource"/>
<property name="druidDataSource" ref="druidDataSource"/>
</bean>
このようにして、BookManagerJdbcService.javaのjdbcDataSourceインスタンスを直接使用できます。
2. Webアプリケーションはデータベースに直接アクセスしませんが、JDBCインターフェイスを介してデータベースドライバにアクセスし、それによってデータベースにアクセスします。
3.データベースドライバは通常、データベースの製造元によって提供されます。これには、データベースにアクセスするロジックだけでなく、基盤となるネットワーク通信も含まれます。
4. DataSourceは、データベースに接続するためのデータベース接続を提供するデータソースです。
5.データソースは3つのタイプに分けられます。1つは一度に1つの接続のみを提供すること、2つ目はデータベース接続プール(スレッドプールの概念と同様)、3つ目は分散データソースです。
6.通常、データソースは、データベースのURL、ユーザー名、パスワード、driverClassの基本構成、およびいくつかのパフォーマンス構成と主要な構成を構成する必要があります。
もちろん、後で徐々に理解する必要があるいくつかの残りの問題があります
1.構成の依存関係を完了するためにsetDriverManagerDataSource()メソッドを追加する必要があるのはなぜですか?
2.プロジェクトで複数のデータソースを使用するにはどうすればよいですか??
次の記事は、Xiaobai(12)関連のデータベース接続の最適化(トランザクション管理)の初心者のWeb開発の簡単な要約を要約することです。