DAO(Data Access Object ,数据访问对象)设计模式
 
 
DAO開發(fā)
DAO開發(fā)完全圍繞著數(shù)據(jù)操作進(jìn)行。(1)下面按照DAO的方式完成后端代碼的開發(fā),首行定義VO類,VO類的名稱與表的名稱一致,但是要注意類的命名的規(guī)范---單詞首字母大寫。
package com.test.vo;import java.util.Date;/*** VO類,VO類的名稱與數(shù)據(jù)庫中表的名稱一致,* 且類中各屬性與表中各字段一一對應(yīng)* */ public class GPSLOG {//屬性private String licenseplateno ;private Date in_date;private Date gps_time;private String longitude;private String latitude ;private String height ;private String speed ;private String direction;private String eff ;private String car_stat1;private String car_stat2;//getters and setterspublic String getLicenseplateno() {return licenseplateno;}public void setLicenseplateno(String licenseplateno) {this.licenseplateno = licenseplateno;}public Date getIn_date() {return in_date;}public void setIn_date(Date in_date) {this.in_date = in_date;}public Date getGps_time() {return gps_time;}public void setGps_time(Date gps_time) {this.gps_time = gps_time;}public String getLongitude() {return longitude;}public void setLongitude(String longitude) {this.longitude = longitude;}public String getLatitude() {return latitude;}public void setLatitude(String latitude) {this.latitude = latitude;}public String getHeight() {return height;}public void setHeight(String height) {this.height = height;}public String getSpeed() {return speed;}public void setSpeed(String speed) {this.speed = speed;}public String getDirection() {return direction;}public void setDirection(String direction) {this.direction = direction;}public String getEff() {return eff;}public void setEff(String eff) {this.eff = eff;}public String getCar_stat1() {return car_stat1;}public void setCar_stat1(String car_stat1) {this.car_stat1 = car_stat1;}public String getCar_stat2() {return car_stat2;}public void setCar_stat2(String car_stat2) {this.car_stat2 = car_stat2;} } 本程序只是一個簡單的VO類,包含了屬性、getter、setter方法。特別要注意的是,其中表示日期時使用的是java.util.Date類。(2)定義完VO類后,下面定義一個數(shù)據(jù)庫連接類,此類完成數(shù)據(jù)庫的打開及關(guān)閉操作。
1》在DAO操作中,由于要適應(yīng)不同的數(shù)據(jù)庫,所以會將所有可能變化的地方都通過接口進(jìn)行實現(xiàn)。例如,一個DAO操作類既可以在Oracle下使用,也可以在MySQL下使用,往往會將其定義成一個接口:
package com.test.jdbc;import java.sql.Connection; /*** 定義數(shù)據(jù)庫連接接口,以適用不同的數(shù)據(jù)庫連接,如Oracle,或者M(jìn)ySQL數(shù)據(jù)庫* */ public interface IDBConnection {//定義DatabaseConnection接口//取得數(shù)據(jù)庫連接public Connection getConnection();//關(guān)閉數(shù)據(jù)庫連接public void close(); }2》然后根據(jù)不同的數(shù)據(jù)庫定義不同的子類,例如以下是Oracle數(shù)據(jù)庫連接的代碼實現(xiàn): package com.test.jdbc;import java.sql.Connection; import java.sql.DriverManager;import com.test.jdbc.IDBConnection; /*** 取得Oracle數(shù)據(jù)庫連接* */ public class OracleDBConnection implements IDBConnection {//DB Driverprivate static final String DBDRIVER="oracle.jdbc.driver.OracleDriver";//DB URLprivate static final String DBURL="jdbc:oracle:thin:@192.168.95.86:1521:orcl"; //DB Userprivate static final String DBUSER="xxtmanage";//DB Passwordprivate static final String DBPASSWORLD="xxtinterface";//DB Connectionprivate Connection conn=null;//structorpublic OracleDBConnection() {//在構(gòu)造方法中進(jìn)行數(shù)據(jù)庫連接System.out.println("OracleDBConnection.OracleDBConnection()");try {// 加載驅(qū)動程序Class.forName(DBDRIVER);//連接數(shù)據(jù)庫this.conn=DriverManager.getConnection(DBURL, DBUSER, DBPASSWORLD);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}@Overridepublic Connection getConnection(){System.out.println("OracleDBConnection.getConnection()");return this.conn;}@Overridepublic void close(){System.out.println("OracleDBConnection.close()");if(this.conn!=null){try {this.conn.close();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}}
3》以下是MySQL的數(shù)據(jù)庫連接代碼(具體代碼未實現(xiàn)): package com.test.jdbc;import java.sql.Connection;import com.test.jdbc.IDBConnection; /*** 取得MySQL數(shù)據(jù)庫連接* */ public class MySQLDBConnection implements IDBConnection {@Overridepublic Connection getConnection() {// TODO Auto-generated method stubreturn null;}@Overridepublic void close() {// TODO Auto-generated method stub}} 4》此時,如果要想取得一個IDBConnection接口的連接對象,還需要一個工廠類完成。 package com.test.jdbc; /*** 數(shù)據(jù)庫連接工廠類,* 根據(jù)現(xiàn)有數(shù)據(jù)庫,取得相應(yīng)數(shù)據(jù)庫連接。* */ public class DBConnectionFactory {public static IDBConnection getDBConnection(){//根據(jù)所使用的數(shù)據(jù)庫,返回相應(yīng)的數(shù)據(jù)庫連接。//返回Oracle數(shù)據(jù)庫連接System.out.println("DBConnectionFactory.getDBConnection()");return new OracleDBConnection();/*** 返回MySQL數(shù)據(jù)庫連接* return new MySQLDBConnection();* */}}
通過以上代碼可以減少類之間的耦合度。
(3)在DAO設(shè)計模式中,最重要的就是定義DAO接口,在定義DAO接口之前必須對業(yè)務(wù)時行詳細(xì)的分析,要清楚地知道一張表在整個系統(tǒng)中應(yīng)該具備何種功能。
本程序只完成數(shù)據(jù)庫的增加功能 ,其他功能可以按照建好的架構(gòu)進(jìn)行增加。
1》定義DAO操作標(biāo)準(zhǔn)---IGpsDao.java
package com.test.dao;import com.test.vo.GPSLOG; /*** 定義DAO操作標(biāo)準(zhǔn)* */ public interface IGpsDao {/*** 數(shù)據(jù)的增加操作* @param gpslog 要增加的數(shù)據(jù)對象--GPS日志信息* @return 是否增加成功的標(biāo)記* @throws 有異常交給調(diào)用者處理* */public boolean insertLog(GPSLOG gpslog)throws Exception;/*** 建表* */public void createTab() throws Exception ;}在DAO的操作標(biāo)準(zhǔn)中定義了 insertLog(GPSLOG gpslog),和createTab()2個功能 。
 
2》DAO接口定義完成后需要做具體的實現(xiàn)類,但是這里DAO的實現(xiàn)類有兩種,一種是真實主題類,另外一種是代理操作類。
真實主題類主要負(fù)責(zé)具體的數(shù)據(jù)庫操作,在操作時為了性能及安全將使用PreparedStatement接口完成。
package com.test.dao;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException;import com.test.dao.IGpsDao; import com.test.vo.GPSLOG; /*** 真實主題實現(xiàn)類* */ public class GpsLogDAOImpl implements IGpsDao {//數(shù)據(jù)庫連接對象private Connection conn=null;//數(shù)據(jù)庫操作對象private PreparedStatement pstmt=null;public GpsLogDAOImpl(Connection conn){//通過構(gòu)造方法取得數(shù)據(jù)庫連接System.out.println("GpsLogDAOImpl.GpsLogDAOImpl()");this.conn=conn;}@Overridepublic boolean insertLog(GPSLOG gpslog) throws Exception {// TODO Auto-generated method stubSystem.out.println("GpsLogDAOImpl.doCreate()");boolean flag=false;String sql="INSERT INTO GPS_LOG_cxc "+ "(licenseplateno ,in_date,gps_time,longitude,latitude,height,speed, direction , eff, car_stat1, car_stat2)"+"VALUES(?,?,?,?,?,?,?,?,?,?,?)";//實例化PreparedStatement對象this.pstmt=this.conn.prepareStatement(sql);this.pstmt.setString(1, gpslog.getLicenseplateno());this.pstmt.setDate(2, new java.sql.Date(gpslog.getIn_date().getTime()));this.pstmt.setDate(3, new java.sql.Date(gpslog.getGps_time().getTime()));this.pstmt.setString(4, gpslog.getLongitude());this.pstmt.setString(5, gpslog.getLatitude());this.pstmt.setString(6, gpslog.getHeight());this.pstmt.setString(7, gpslog.getSpeed());this.pstmt.setString(8, gpslog.getDirection());this.pstmt.setString(9, gpslog.getEff());this.pstmt.setString(10,gpslog.getCar_stat1() );this.pstmt.setString(11, gpslog.getCar_stat2());System.out.println("GpsLogDAOImpl.doCreate()=="+sql);if(this.pstmt.executeUpdate()>0){flag=true;}this.pstmt.close();//關(guān)閉PreparedStatement對象 return flag;}@Overridepublic void createTab() throws Exception {// TODO Auto-generated method stubSystem.out.println("GpsLogDAOImpl.createTab()");String sql="create table GPS_LOG_cxc"+ "( licenseplateno VARCHAR2(20) not null, "+ " in_date DATE default SYSDATE,"+ " gps_time DATE not null,"+ " longitude CHAR(10),"+ " latitude CHAR(9),"+ " height CHAR(9),"+ " speed CHAR(3),"+ " direction CHAR(3),"+ " eff CHAR(1),"+ " car_stat1 CHAR(1),"+ " car_stat2 CHAR(1)"+ ")";this.pstmt=this.conn.prepareStatement(sql);this.pstmt.execute();this.pstmt.close();}}代理主題實現(xiàn)類代碼如下: package com.test.dao;import java.sql.Connection;import com.test.dao.IGpsDao; import com.test.jdbc.IDBConnection; import com.test.jdbc.DBConnectionFactory; import com.test.vo.GPSLOG;public class GpsDaoProxy implements IGpsDao {//數(shù)據(jù)庫連接private IDBConnection dbc=null;//DAO對象private IGpsDao dao=null;public GpsDaoProxy(){System.out.println("GpsDaoProxy.GpsDaoProxy()");this.dbc =DBConnectionFactory.getDBConnection();//連接數(shù)據(jù)庫//實例化真實主題類--多態(tài):接口對象指向?qū)崿F(xiàn)此接口類的實例this.dao=new GpsLogDAOImpl(this.dbc.getConnection() );System.out.println("GpsDaoProxy.GpsDaoProxy()---2");}@Overridepublic boolean insertLog(GPSLOG gpslog) throws Exception {// TODO Auto-generated method stubSystem.out.println("GpsDaoProxy.doCreate()");boolean flag=false;try {flag=this.dao.insertLog(gpslog);} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{this.dbc.close();}return flag;}@Overridepublic void createTab() throws Exception {// TODO Auto-generated method stubSystem.out.println("GpsDaoProxy.createTab()");try {this.dao.createTab();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}finally{this.dbc.close();}}}
可以發(fā)現(xiàn),在代理類的構(gòu)造方法中實實例化了數(shù)據(jù)庫連接類的對象以及真實主題實現(xiàn)類,而在代理中的各個方法也只是調(diào)用了真實主題實現(xiàn)類中的相應(yīng)方法。
 
3》DAO的真實實現(xiàn)類和代理實現(xiàn)類編寫完成后就需要編寫工廠類,以降低代碼間的耦合度。
package com.test.dao;import com.test.dao.IGpsDao;public class DAOFactory {public static IGpsDao getIGpsDaoInstance(){System.out.println("DAOFactory.getIGpsDaoInstance()");return new GpsDaoProxy();}} 至此DAO模式已經(jīng)書寫完成。其工程目錄結(jié)構(gòu)如下圖所示:
 
(4)測試DAO插入功能 。
 
結(jié)束。。。
完整代碼:點擊打開鏈接
 
總結(jié)
以上是生活随笔為你收集整理的DAO(Data Access Object ,数据访问对象)设计模式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: LinearLayout(线性布局)
- 下一篇: 关于Android SDK工具Lint的
