菜鳥学JDBC(二)
13336 ワード
前の記事(
http://blog.csdn.net/rowandjj/article/details/8883383)JDBCでmysqlデータベースに接続する方法について説明し、簡単なコード例で具体的な操作を示しました.ここでは、プロセスを簡単に振り返ってみましょう.
1.ロードドライバ(Class.forName()……);
2.DriverManagerクラスを介してデータベースと接続を確立する(Connection conn=DriverManager.getConnection()……);
3.sql文(Statementst=conn.createStatement()....)を作成します.
4.sql文(st.execute(String sql)...)を実行する.
5.クエリー結果の処理(selectなどのクエリー文の場合、ResultSet結果セットが返され、操作できます).
ここまでデータベースへの接続方法について初歩的な理解があると信じています.次に、前回のコードの最適化に着手します.
最適化内容は次のとおりです.
1.データベースを閉じる部分を最適化する(異常な処理);
2.クエリー・プロセスの最適化(StatementとPreparedStatement).
3.アーキテクチャを最適化する(JDBCツール類、カプセル化とデータベース接続、登録駆動、閉鎖接続などの繰り返し操作);
まずJDBCツールクラスを書きましょう.
注意:コードにインポートするConnectionなどのクラスはjavaです.sqlパッケージの中の、mysqlパッケージをインポートしないでください!
シナリオ1:
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class JDBCUtils
{
private JDBCUtils(){}// , new ( )
private static String driverName = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost/db_test";
private static String userName = "root";
private static String password = "sjjhong";
// , , ----->
static
{
try
{
Class.forName(driverName);
}
catch (ClassNotFoundException e)
{
// TODO catch
throw new ExceptionInInitializerError();//
}
}
public static Connection getConnection() throws SQLException
{
//
return DriverManager.getConnection(url,userName,password);
}
public static void free(ResultSet rs,Statement stat,Connection conn)
{
try
{
if(rs != null)//
rs.close();
rs = null;
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
try
{
if(stat != null)
stat.close();
stat = null;
}
catch (SQLException e)
{
// TODO catch
e.printStackTrace();
}
finally
{
try
{
if(conn != null)
conn.close();
conn = null;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}
上記のツールクラスでは、ロードドライバ、接続の確立、リソースのクローズなど、一般的な方法をカプセル化しています.これらの操作は出現頻度が高いため,添削改ざんなどの方法ではこれらの操作に関与し,パッケージ化後,コードの多重性が向上する.
また、データベースリソースを閉じる部分を最適化し、異常を処理しました.具体的には、コードを参考にして、なぜそうするのかを考えてみてください.
シナリオ2(単一の例で書かれたツールクラス):
package demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public final class SingDemo
{
private static String driverName = "com.mysql.jdbc.Driver";
private static String url = "jdbc:mysql://localhost/db_test";
private static String userName = "root";
private static String password = "sjjhong";
private SingDemo(){}
private static SingDemo sin = null;// ( , )
public static SingDemo getInstance()//
{
if(sin != null)
{
synchronized (SingDemo.class)// ,
{
if(sin != null)
{
sin = new SingDemo();
}
}
}
return sin;
}
static
{
try
{
Class.forName(driverName);
}
catch (ClassNotFoundException e)
{
throw new ExceptionInInitializerError();
}
}
public Connection getConnection() throws SQLException
{
return DriverManager.getConnection(url,userName,password);
}
public void free(ResultSet rs,Statement stat,Connection conn)
{
try
{
if(rs != null)//
rs.close();
rs = null;
}
catch (SQLException e)
{
e.printStackTrace();
}
finally
{
try
{
if(stat != null)
stat.close();
stat = null;
}
catch (SQLException e)
{
// TODO catch
e.printStackTrace();
}
finally
{
try
{
if(conn != null)
conn.close();
conn =null;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}
データベースまたはユーザー名のパスワードを変更した場合、ソースコードを変更する必要があります.不便ですが、この問題を解決するにはどうすればいいのでしょうか.プロファイルで解決できます!プロファイルに書き込むと、プロファイルを変更して接続するデータベースを直接変更できます.エラーの確率は小さくなります.
シナリオ3(ドライバ名、urlなどをプロファイルに書き込む):
package biogDemo;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DBUtils
{
private static String driverName = null;
private static String user = null;
private static String url = null;
private static String password = null;
private static DBUtils instance = null;
public static DBUtils getInstance()
{
if(instance == null)
{
synchronized (DBUtils.class)
{
if(instance == null)
{
instance = new DBUtils();
}
}
}
return instance;
}
private DBUtils()
{
try
{
Properties prop = new Properties();
prop.load(new FileInputStream(getPropertyFilePath()));//
//
driverName = prop.getProperty("driverName");
user = prop.getProperty("user");
url = prop.getProperty("url");
password = prop.getProperty("password");
Class.forName(driverName);
}
catch (ClassNotFoundException e)
{
// TODO catch
e.printStackTrace();
}
catch (FileNotFoundException e)
{
// TODO catch
e.printStackTrace();
}
catch (IOException e)
{
// TODO catch
e.printStackTrace();
}
}
public String getPropertyFilePath()
{
StringBuilder sb = new StringBuilder();
sb.append(System.getProperty("user.dir"));//
sb.append("\\src\\").append("biogDemo\\").append("db.properties");
return sb.toString();
}
public Connection getConnection() throws SQLException
{
return DriverManager.getConnection(url, user, password);
}
public static void free(Connection conn,Statement stat,ResultSet rs)
{
try
{
if(rs != null)
{
rs.close();
}
rs = null;
}
catch (SQLException e)
{
// TODO catch
e.printStackTrace();
}
finally
{
try
{
if(stat != null)
{
stat.close();
}
stat = null;
}
catch (SQLException e)
{
// TODO catch
e.printStackTrace();
}
finally
{
try
{
if(conn != null)
{
conn.close();
}
conn = null;
}
catch (SQLException e)
{
e.printStackTrace();
}
}
}
}
}
そのうちdb.propertiesファイルには、次の内容が書き込まれます.
driverName = com.mysql.jdbc.Driver
password = sjjhong
url = jdbc:mysql://localhost/test
user = root
はい、今回の最適化はここまでです.これはまだ十分ではありません.後のブログはさらに改善されます(接続プールなどと組み合わせて...)
次に、私たちのツールクラスを簡単に使いましょう.(使用案一)
package biogDemo;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import demo.JDBCUtils;
/**
* @author Rowand jj
*
*/
public class Main
{
public static void main(String[] args)
{
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
String sql = "select id,name,birthday,money from tb_9 where id> ?";
int ID = 2;
try
{
conn = JDBCUtils.getConnection();//
ps = conn.prepareStatement(sql);
ps.setInt(1,ID);// sql (?) ID
//ResultSetMetaData ResultSet
ResultSetMetaData rsmd = ps.getMetaData();
int COUNT = rsmd.getColumnCount();//
rs = ps.executeQuery(); //
while(rs.next())
{
for(int i = 1;i <= COUNT;i++)
{
System.out.print(rs.getObject(i) + " ");
}
System.out.println("
");
}
}
catch(SQLException e)
{
throw new RuntimeException(" !");
}
finally
{
// , 。 !
JDBCUtils.free(rs, ps, conn);
}
}
}
上記の例では、StatementではなくPreparedStatementに変更したことに気づきましたが、このクラスとStatementの違いは何でしょうか.
まず、PreparedStatementに関するドキュメントの説明を見てみましょう.
PreparedStatementはStatementを継承し、機能がより強力であることがわかります.最も明らかなのは、クエリー文を処理する柔軟性です.使えますか?クエリー条件の代わりに、setメソッドの置き換えを提供します.
違い:
Statement:(パラメータを持たない単純なSQL文を実行するために使用)
sql文を実行するたびに、
データベース#データベース#はいずれもsql文のコンパイルを実行し、PreparedStatementよりも効率的にクエリを1回だけ実行して結果を返す場合に使用するのが望ましい.
PreparedStatement:(INパラメータを持たないプリコンパイルSQL文の実行)
1.実行されるSQL文には、パラメータを使用できます.また、SQLの一括実行をサポートします.Cacheメカニズムを採用しているため、事前にコンパイルされた文はCacheに入れられ、次回同じSQL文を実行するとCacheから直接取り出すことができるため、同じ操作で一括データの効率が高い.
2.比較的安全で、sql注入を防止できる
ここではPreparedStatementを強くお勧めします.
さて、ここまでですが、次の記事では、基本的な添削変更操作と異なるデータ型の処理について説明します.お楽しみに.