菜鳥学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に関するドキュメントの説明を見てみましょう.
菜鸟学JDBC(二)_第1张图片
 
 
PreparedStatementはStatementを継承し、機能がより強力であることがわかります.最も明らかなのは、クエリー文を処理する柔軟性です.使えますか?クエリー条件の代わりに、setメソッドの置き換えを提供します.
違い:
Statement:(パラメータを持たない単純なSQL文を実行するために使用)
sql文を実行するたびに、
データベース#データベース#はいずれもsql文のコンパイルを実行し、PreparedStatementよりも効率的にクエリを1回だけ実行して結果を返す場合に使用するのが望ましい.
PreparedStatement:(INパラメータを持たないプリコンパイルSQL文の実行)
1.実行されるSQL文には、パラメータを使用できます.また、SQLの一括実行をサポートします.Cacheメカニズムを採用しているため、事前にコンパイルされた文はCacheに入れられ、次回同じSQL文を実行するとCacheから直接取り出すことができるため、同じ操作で一括データの効率が高い.
2.比較的安全で、sql注入を防止できる
 
ここではPreparedStatementを強くお勧めします.
 
さて、ここまでですが、次の記事では、基本的な添削変更操作と異なるデータ型の処理について説明します.お楽しみに.