首页 > 代码库 > MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

【声明】 

欢迎转载,但请保留文章原始出处→_→ 

生命壹号:http://www.cnblogs.com/smyhvae/

文章来源:http://www.cnblogs.com/smyhvae/p/4059514.html

联系方式:smyhvae@163.com

 

【正文】

一、DAO模式简介

DAO即Data Access Object,数据访问接口。数据访问:故名思义就是与数据库打交道。夹在业务逻辑与数据库资源中间。

DAO模式实际上是两个模式的组合,即Data Accessor (数据访问者)模式和 Active Domain Object(领域对象)模式。Data Accessor 模式实现了数据访问和业务逻辑的分离;Active Domain Object 模式实现了业务数据的对象化封装。

需要注意的是,DAO设计模式是Java EE中的设计模式,而非Java SE中的23种设计模式。

 

二、实现DAO模式

一个典型的DAO实现有下列几个组件:

  • 一个DAO接口;
  • 一个实现DAO接口的具体类; 
  • 数据传递对象(DTO):有些时候叫做值对象(VO)或领域模型(domain)

这种实现模式就是一个套路,记熟就好了。不过在这之前,如果有不明白的地方,还是要回顾一下之前几篇博文中的知识:PreparedStatement接口重构增删改查、封装JDBC工具类。好了,下面直接上代码。

 

三、代码实现

我们一下面的这张数据表为例:

新建Java工程文件DaoTest01,最终的工程文件结构如下:

ffbb2b6e-8d0d-4d4b-9b46-0283ee06a254

  • DBUtils:初步封装的JDBC工具类;
  • db-config.properties:属性文件,方便修改配置信息;
  • Person类就是领域模型,表示是对它(数据库表)进行增删改查。
  • PersonDao接口:专门对Person类进行操作(例如增删改查)的接口。注:这里不直接写操作类,是因为接口利于维护,可以在这里写上公共的代码。一个领域模型对应一个Dao接口。
  • PeronDaoImpl类:实现上面的PeronDao接口

步骤如下:

注:第(1)、(2)步操作和上一篇博文是一模一样的,这里只是为了保证本篇文章的完整性,所以重新写一下。

(1)先新建一个DBUtils工具类:(package com.util.db)

 1 package com.util.db; 2  3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.ResultSet; 6 import java.sql.SQLException; 7 import java.sql.Statement; 8 import java.util.ResourceBundle; 9 10 /**11  * 数据库操作工具类12  * @author lamp13  *14  */15 public class DBUtils {16     17     //数据库连接地址18     public static String URL;19     //用户名20     public static String USERNAME;21     //密码22     public static String PASSWORD;23     //mysql的驱动类24     public static String DRIVER;25     26     private static ResourceBundle rb = ResourceBundle.getBundle("com.util.db.db-config");27     28     private DBUtils(){}29     30     //使用静态块加载驱动程序31     static{32         URL = rb.getString("jdbc.url");33         USERNAME = rb.getString("jdbc.username");34         PASSWORD = rb.getString("jdbc.password");35         DRIVER = rb.getString("jdbc.driver");36         try {37             Class.forName(DRIVER);38         } catch (ClassNotFoundException e) {39             e.printStackTrace();40         }41     }42     //定义一个获取数据库连接的方法43     public static Connection getConnection(){44         Connection conn = null;45         try {46             conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);47         } catch (SQLException e) {48             e.printStackTrace();49             System.out.println("获取连接失败");50         }51         return conn;52     }53     54     /**55      * 关闭数据库连接56      * @param rs57      * @param stat58      * @param conn59      */60     public static void close(ResultSet rs,Statement stat,Connection conn){61             try {62                 if(rs!=null)rs.close();63                 if(stat!=null)stat.close();64                 if(conn!=null)conn.close();65             } catch (SQLException e) {66                 e.printStackTrace();67             }68     }69     70 }

注意:26行中,注意获取属性文件的包名是否正确。稍后会定义这个属性文件。

28行:既然是工具类,一般不要实例化,此时可以采用单例设计模式,或者将构造方法私有化。

26行:很明显可以看到,我们是将连接数据库的URL、用户名,密码等信息编写在一个属性文件(jdbc.properties)中,稍后再来定义这个属性文件。

31行:为避免重复代码,使用静态代码块:只会在类加载的时候执行一次。

42行:定义一个获取数据库连接的方法

60行:关闭数据库连接

(2)接下来新建一个属性文件,new-->file,命名为:db-config.properties,代码如下:

jdbc.url=jdbc:mysql://localhost:3306/jdbcdbjdbc.username=rootjdbc.password=smyhjdbc.driver=com.mysql.jdbc.Driver

以后如果需要修改配置信息,只需要在这里改就行了。注意在上面的DBUtils类中是怎么来调用这个配置信息的。

紧接着新建文件,定义好Person类:(package com.vae.domain)

 1 package com.vae.domain; 2  3 public class Person { 4     private int id; 5     private String name; 6     private int age; 7     private String description; 8     public int getId() { 9         return id;10     }11     public void setId(int id) {12         this.id = id;13     }14     public String getName() {15         return name;16     }17     public void setName(String name) {18         this.name = name;19     }20     public int getAge() {21         return age;22     }23     public void setAge(int age) {24         this.age = age;25     }26     public String getDescription() {27         return description;28     }29     public void setDescription(String description) {30         this.description = description;31     }32     public Person(int id, String name, int age, String description) {33         super();34         this.id = id;35         this.name = name;36         this.age = age;37         this.description = description;38     }39     public Person(String name, int age, String description) {40         super();41         this.name = name;42         this.age = age;43         this.description = description;44     }45     public Person() {46         super();47         // TODO Auto-generated constructor stub48     }49     @Override50     public String toString() {51         return "Person [id=" + id + ", name=" + name + ", age=" + age52                 + ", description=" + description + "]";53     }54     55     56 }

这个Person类就是领域模型,表示是对它进行增删改查。

(3)定义PersonDao接口:专门对Person类进行操作(例如增删改查)的接口(package com.vae.dao)

package com.vae.dao;import java.sql.SQLException;import java.util.List;import com.vae.domain.Person;public interface PersonDao {    //添加方法    public void add(Person p)throws SQLException;        //更新方法    public void update(Person p)throws SQLException;        //删除方法    public void delete(int id)throws SQLException;        //查找方法    public Person findById(int id)throws SQLException;        //查找所有    public List<Person> findAll()throws SQLException;    } 

(4)定义PeronDaoImpl实现类 ,实现上面的PeronDao接口(package com.vae.dao.impl)

  1 package com.vae.dao.impl;  2   3 import java.sql.Connection;  4 import java.sql.PreparedStatement;  5 import java.sql.ResultSet;  6 import java.sql.SQLException;  7 import java.util.ArrayList;  8 import java.util.List;  9  10 import com.util.db.DBUtils; 11 import com.vae.dao.PersonDao; 12 import com.vae.domain.Person; 13  14 /** 15  * PersonDao的具体实现类 16  * @author lamp 17  * 18  */ 19 public class PersonDaoImpl implements PersonDao{ 20  21     /** 22      * 实现添加方法 23      */ 24     @Override 25     public void add(Person p) throws SQLException { 26         Connection conn = null; 27         PreparedStatement ps = null; 28         String sql = "insert into person(name,age,description)values(?,?,?)"; 29         try{ 30             conn = DBUtils.getConnection(); 31             ps = conn.prepareStatement(sql); 32             ps.setString(1, p.getName()); 33             ps.setInt(2, p.getAge()); 34             ps.setString(3, p.getDescription()); 35             ps.executeUpdate(); 36         }catch(SQLException e){ 37             e.printStackTrace(); 38             throw new SQLException("添加数据失败"); 39         }finally{ 40             DBUtils.close(null, ps, conn); 41         } 42     } 43  44     /** 45      * 更新方法 46      */ 47     @Override 48     public void update(Person p) throws SQLException { 49         Connection conn = null; 50         PreparedStatement ps = null; 51         String sql = "update person set name=?,age=?,description=? where id=?"; 52         try{ 53             conn = DBUtils.getConnection(); 54             ps = conn.prepareStatement(sql); 55             ps.setString(1, p.getName()); 56             ps.setInt(2, p.getAge()); 57             ps.setString(3, p.getDescription()); 58             ps.setInt(4, p.getId()); 59             ps.executeUpdate(); 60         }catch(SQLException e){ 61             e.printStackTrace(); 62             throw new SQLException("更新数据失败"); 63         }finally{ 64             DBUtils.close(null, ps, conn); 65         }         66     } 67  68     /** 69      * 删除方法 70      */ 71     @Override 72     public void delete(int id) throws SQLException { 73         Connection conn = null; 74         PreparedStatement ps = null; 75         String sql = "delete from person where id=?"; 76         try{ 77             conn = DBUtils.getConnection(); 78             ps = conn.prepareStatement(sql); 79             ps.setInt(1,id); 80             ps.executeUpdate(); 81         }catch(SQLException e){ 82             e.printStackTrace(); 83             throw new SQLException(" 删除数据失败"); 84         }finally{ 85             DBUtils.close(null, ps, conn); 86         }         87     } 88  89     /** 90      * 根据ID查询一个对象 91      */ 92     @Override 93     public Person findById(int id) throws SQLException { 94         Connection conn = null; 95         PreparedStatement ps = null; 96         ResultSet rs = null; 97         Person p = null; 98         String sql = "select name,age,description from person where id=?"; 99         try{100             conn = DBUtils.getConnection();101             ps = conn.prepareStatement(sql);102             ps.setInt(1, id);103             rs = ps.executeQuery();104             if(rs.next()){105                 p = new Person();106                 p.setId(id);107                 p.setName(rs.getString(1));108                 p.setAge(rs.getInt(2));109                 p.setDescription(rs.getString(3));110             }111         }catch(SQLException e){112             e.printStackTrace();113             throw new SQLException("根据ID查询数据失败");114         }finally{115             DBUtils.close(rs, ps, conn);116         }117         return p;118     }119 120     /**121      * 查询所有数据122      */123     @Override124     public List<Person> findAll() throws SQLException {125         Connection conn = null;126         PreparedStatement ps = null;127         ResultSet rs = null;128         Person p = null;129         List<Person> persons = new ArrayList<Person>();130         String sql = "select id,name,age,description from person";131         try{132             conn = DBUtils.getConnection();133             ps = conn.prepareStatement(sql);134             rs = ps.executeQuery();135             while(rs.next()){136                 p = new Person();137                 p.setId(rs.getInt(1));138                 p.setName(rs.getString(2));139                 p.setAge(rs.getInt(3));140                 p.setDescription(rs.getString(4));141                 persons.add(p);142             }143         }catch(SQLException e){144             e.printStackTrace();145             throw new SQLException("查询所有数据失败");146         }finally{147             DBUtils.close(rs, ps, conn);148         }149         return persons;150     }151 152 }

我们在各自的增删改查里都抛出了异常,如果出现异常,就会抛出相应的错误信息。

总结:这样的话,我们就封装好了JDBC的工具类。以后如果要用的话,可以直接在主方法里调用这个类就行了。

【工程文件】

链接:http://pan.baidu.com/s/1qW6tew8

密码:t98s

MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)