1. 程式人生 > >jdbc-DAO的實現

jdbc-DAO的實現

什麼是 DAO

DAO(Data Access Object)是一個數據訪問介面,夾在業務邏輯與資料庫資源中間。

在核心J2EE模式中是這樣介紹DAO模式的:為了建立一個健壯的J2EE應用,應該將所有對資料來源的訪問操作抽象封裝在一個公共API中。用程式設計的語言來說,就是建立一個介面,介面中定義了此應用程式中將會用到的所有事務方法。在這個應用程式中,當需要和資料來源進行互動的時候則使用這個介面,並且編寫一個單獨的類來實現這個介面在邏輯上對應這個特定的資料儲存。DAO中的主要操作:增刪改查(CRUD).

DAO的實現

實現的步驟一般是:

  • 先建立模型的物件domain
  • 編寫DAO介面
  • 定義DAO實現類
  • 生產DAO測試類
  • 在DAO測試類中測試方法

一般的規範是分domain包和dao包,dao包中有DAO介面,介面名為IXxxDAO,實現類為XxxDAO,建立實現類物件賦給介面,體現多型。還有一個測試類名為XxxTestDAOTest.如:

img

DAO介面:

public interface IStudentDAO {
    /**
     * 儲存學生物件
     * @param stu 需要儲存的學生
     */
    void save(Student stu);

    /**
     * 刪除指定id的學生
     * @param id  需要刪除的學生的id
     */
    void delete(int id);

    /**
     * 更改操作
     * @param newStu 更改後的學生物件,根據id更改
     */
    void update(Student newStu);

    /**
     * 根據id查詢單個學生物件資訊
     * @param id  需要查詢學生的id
     * @return  存在該學生返回學生物件  不存在則返回null
     */
    Student get(long id );

    /**
     * 查詢所有學生
     * @return  返回一個學生物件的集合
     */
    List<Student> list();
}

實現類:

public void save(Student stu) {
        String sql = "INSERT INTO s_student(name,age) VALUES('狗哲',21)";
        Connection conn = null;
        Statement st = null
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///demo","root","admin");
            st = conn.createStatement();
            st.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try{
                if(st != null){
                    st.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                try{
                    if(conn != null){
                        conn.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
增刪改只有sql語句不一樣,省略
····
····
public List<Student> list() {
    String sql = "SELECT * FROM s_student";
    Connection conn = null;
    Statement st = null;
    ResultSet rs = null;
    List<Student> list = new ArrayList<>();
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql:///demo","root","admin");
        st = conn.createStatement();
        rs = st.executeQuery(sql);
        while(rs.next()){
            String name = rs.getString("name");
            Integer age = rs.getInt("age");
            list.add(new Student(name,age));
        }

    } catch (Exception e) {
        e.printStackTrace();
    }finally {
        try{
            if(st != null){
                st.close();
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            try{
                if(conn != null){
                    conn.close();
                }
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }
    return  list;
}

DAO實現的重構

可以看出程式碼重複非常之多,尤其是增刪改只有sql語句不一樣

  • 1、定義一個JdbcUtil類,把載入註冊驅動放到靜態程式碼塊中,因為沒有必要每次都去載入。
  • 2、把url,classDriverName,username,password ,放在一個資原始檔中,用載入資原始檔的方式獲取這些值,保證了程式碼的可維護性
  • 3、異常處理程式碼也放在工具類中,異常處理及其麻煩,影響程式碼的美觀
public class JdbcUtil {
    private static Properties p = new Properties();
    //載入資原始檔
    static{
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        InputStream inStream = loader.getResourceAsStream("db.properties");
        try {
            p.load(inStream);
            Class.forName(p.getProperty("classDriver"));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //獲取連線物件
    public static Connection getConn(){
        Connection conn = null;
        try {
             conn = DriverManager.getConnection(p.getProperty("url"),p.getProperty("username"), p.getProperty("password"));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }
    //關閉資源
    public static void close(Connection conn,Statement st,ResultSet rs){
        try{
            if(rs != null){
                rs.close();
            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            try{
                if(st != null){
                    st.close();
                }
            }catch(Exception e){
                e.printStackTrace();
            }finally{
                try{
                    if(conn != null){
                        conn.close();
                    }
                }catch(Exception e){
                    e.printStackTrace();
                }
            }
        }
    }
}