下面的所有代码示例都取自李兴华的《Java Web开发实战经典》的随书源码,因为觉得设计得很好,所以将代码摘录下来作成笔记。

首先,我们在一个java文件中定义要存储的结构类型:

import java.util.Date ;
/**
*
* @author Nero
*/
public class Emp {
private int empno ;
private String ename ;
private String job ;
private Date hiredate ;
private float sal ;
public void setEmpno(int empno){
this.empno = empno ;
}
public void setEname(String ename){
this.ename = ename ;
}
public void setJob(String job){
this.job = job ;
}
public void setHiredate(Date hiredate){
this.hiredate = hiredate ;
}
public void setSal(float sal){
this.sal = sal ;
}
public int getEmpno(){
return this.empno ;
}
public String getEname(){
return this.ename ;
}
public String getJob(){
return this.job ;
}
public Date getHiredate(){
return this.hiredate ;
}
public float getSal(){
return this.sal ;
}
}

下面我们定义一个数据库连接类,负责向数据库发起连接。java连接数据库需要驱动包,我们可以自行下载,测试的时候我使用的是mysql-connector-java-5.0.5-bin.jar。在运行程序的时候Eclipse会提示需要加载的数据库驱动包,一些是类似于"org.gjt.mm.mysql.Driver" 之类的标准包,一般来说我们选择工作目录里的驱动包就可以了。

import java.sql.Connection ;
import java.sql.DriverManager ;
/**
*
* @author Nero
*/
public class DatabaseConnection {
private static final String DBDRIVER = "org.gjt.mm.mysql.Driver" ;
private static final String DBURL = "jdbc:mysql://localhost:3306/mldn" ;
private static final String DBUSER = "root" ;
private static final String DBPASSWORD = "root" ;
private Connection conn ;
public DatabaseConnection() throws Exception {
Class.forName(DBDRIVER) ;
this.conn = DriverManager.getConnection(DBURL,DBUSER,DBPASSWORD) ;
}
public Connection getConnection(){
return this.conn ;
}
public void close() throws Exception {
if(this.conn != null){
try{
this.conn.close() ;
}catch(Exception e){
throw e ;
}
}
}
}

接下来我们定义一个接口,这个接口能够帮助我们轻松地实现代理方法。接口内的方法只有三个:插入、查找全部和通过ID查找。

import java.util.* ;

/**
*
* @author Nero
*/
public interface IEmpDAO {
public boolean doCreate(Emp emp) throws Exception ;
public List<Emp> findAll(String keyWord) throws Exception ;
public Emp findById(int empno) throws Exception ;
}

然后呢,我们继承这个接口,实现具体数据库的操作类,都是一些很基本的数据库操作,没啥好说的。主要要注意的是构造函数那里,参数使用Connection对象,后面使用这个类的时候要传入前面定义的数据库连接类DatabaseConnection中的函数getConnection()返回的Connection对象。

import java.sql.* ;
/**
*
* @author Nero
*/
public class EmpDAOImpl implements IEmpDAO{
private Connection conn = null ;
private PreparedStatement pstmt = null ;
public EmpDAOImpl(Connection conn)
{
this.conn = conn;
}
public boolean doCreate(Emp emp) throws Exception{
boolean flag = false;
String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES(?,?,?,?,?)";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setInt(1, emp.getEmpno());
this.pstmt.setString(2,emp.getEname()) ;
this.pstmt.setString(3,emp.getJob()) ;
this.pstmt.setDate(4,new java.sql.Date(emp.getHiredate().getTime())) ;
this.pstmt.setFloat(5,emp.getSal()) ;
if(this.pstmt.executeUpdate() > 0)
{
flag = true;
}
this.pstmt.close();
return flag;
}
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all = new ArrayList<Emp>();
String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE ename LIKE ? OR job LIKE ?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1,"%"+keyWord+"%"); //转义字符
this.pstmt.setString(2,"%"+keyWord+"%");
ResultSet rs = this.pstmt.executeQuery(sql);
Emp emp = null;
while(rs.next())
{
emp = new Emp();
emp.setEmpno(rs.getInt(1));
emp.setEname(rs.getString(2)) ;
emp.setJob(rs.getString(3)) ;
emp.setHiredate(rs.getDate(4)) ;
emp.setSal(rs.getFloat(5)) ;
all.add(emp);
}
this.pstmt.close();
return all;
}
public Emp findById(int empno) throws Exception{
Emp emp = null ;
String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?" ;
this.pstmt = this.conn.prepareStatement(sql) ;
this.pstmt.setInt(1,empno) ;
ResultSet rs = this.pstmt.executeQuery() ;
if(rs.next()){
emp = new Emp() ;
emp.setEmpno(rs.getInt(1)) ;
emp.setEname(rs.getString(2)) ;
emp.setJob(rs.getString(3)) ;
emp.setHiredate(rs.getDate(4)) ;
emp.setSal(rs.getFloat(5)) ;
}
this.pstmt.close() ;
return emp ;
}
}

下面我们看看代理类的实现,个人觉得到这里就比较有意思了。在这个类里面,声明了一个数据库连接类DatabaseConnection的对象,一个数据库应用类EmpDAOImpl对象,用DatabaseConnection对象初始化EmpDAOImpl对象,然后在代理类的每个函数中都使用EmpDAOImpl对象去调用从同一接口继承而来的方法,这样即对具体实现方法进行了一定程度的隐藏。

import java.sql.* ;
/**
*
* @author Nero
*/
public class EmpDAOProxy implements IEmpDAO{
private DatabaseConnection dbc = null ;
private EmpDAOImpl dao = null ;
public EmpDAOProxy() throws Exception{
this.dbc = new DatabaseConnection();
this.dao = new EmpDAOImpl(this.dbc.getConnection());
}
public boolean doCreate(Emp emp) throws Exception{
boolean flag = false;
try{
if(this.dao.findById(emp.getEmpno()) == null)
{
flag = this.dao.doCreate(emp); }
}catch(Exception e)
{
throw e;
}finally{
this.dbc.close();
}
return flag;
}
public List<Emp> findAll(String keyWord) throws Exception{
List<Emp> all = null ;
try{
all = this.dao.findAll(keyWord) ;
}catch(Exception e){
throw e ;
}finally{
this.dbc.close() ;
}
return all ;
}
public Emp findById(int empno) throws Exception{
Emp emp = null ;
try{
emp = this.dao.findById(empno) ;
}catch(Exception e){
throw e ;
}finally{
this.dbc.close() ;
}
return emp ;
}
}

这还不是全部,我们可以再加一个工厂类来实现工厂模式:

/**
*
* @author Nero
*/
public class DAOFactory {
public static IEmpDAO getIEmpDAOInstance() throws Exception{
return new EmpDAOProxy() ;
}
}

这个工厂类有什么用呢?最后我们在主类文件中进行调用,可以看看工厂类有什么作用:

/**
*
* @author Nero
*/
public class TestDAOInsert {
public static void main(String args[]) throws Exception{
Emp emp = null ;
for(int x=0;x<5;x++){
emp = new Emp() ;
emp.setEmpno(1000 + x) ;
emp.setEname("中文显示测试 - " + x) ;
emp.setJob("程序员 - " + x) ;
emp.setHiredate(new java.util.Date()) ;
emp.setSal(500 * x) ;
DAOFactory.getIEmpDAOInstance().doCreate(emp) ;
}
}
}

可见具体的实现方法隐藏得比较好,通过工厂类调用get方法获取代理类,代理类调用特定方法,然后由代理类内的具体操作对象去调用具体的操作方法。

其实这些东西看起来会觉得很简单,但是自己设计的时候往往会忘记。主要是因为用得不多吧,一开始总是要强迫自己想起来去做,然后慢慢地才能变成一种习惯。

Java通过代理类实现数据库DAO操作的更多相关文章

  1. 初看Mybatis 源码 (二) Java动态代理类

    先抛出一个问题,用过Mybatis的都知道,我们只需要定义一个Dao的接口,在里面写上一些CRUD相关操作,然后配置一下sql映射文件,就可以达到调用接口中的方法,然后执行sql语句的效果,为什么呢? ...

  2. android SQLite使用SQLiteOpenHelper类对数据库进行操作

    android SQLite使用SQLiteOpenHelper类对数据库进行操作 原文: http://byandby.iteye.com/blog/835580

  3. java动态代理类

    很有意思的一个东西,在java.lang.reflect包下 示例代码 package com.guangshan.test.proxy; import java.lang.reflect.Invoc ...

  4. Java常用工具类之数据库操作辅助类DBUtil.java

    package com.qushida.util; import java.beans.BeanInfo; import java.beans.Introspector; import java.be ...

  5. 使用SQLiteOpenHelper类对数据库简单操作

    实现数据库基本操作       数据库创建的问题解决了,接下来就该使用数据库实现应用程序功能的时候了.基本的操作包括创建.读取.更新.删除,即我们通常说的CRUD(Create, Read, Upda ...

  6. JAVA实现File类中的遍历操作并输出内容

    package shb.java.testIo; import java.io.BufferedReader; import java.io.BufferedWriter; import java.i ...

  7. JAVA通过实体类生成数据库查询语句(驼峰命名规则)

    import java.io.IOException; import java.lang.reflect.Field; import java.util.HashMap; import java.ut ...

  8. java代理模式及动态代理类

     1.      代理模式 代理模式的作用是:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个客户不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用 ...

  9. Java中数组操作 java.util.Arrays 类常用方法的使用

    任何一门编程语言,数组都是最重要和常用的数据结构之一,但不同的语言对数组的构造与处理是不尽相同的. Java中提供了java.util.Arrays 类能方便地操作数组,并且它提供的所有方法都是静态的 ...

随机推荐

  1. IIS6_IIS7日志文件位置

    准备统计下页面访问量 查找IIS日志,发现在以前IIS6日志的位置,竟然木有找到日志... 查看下IIS设置,发现IIS7和6的默认日志位置不一样额... IIS 6 Log files locati ...

  2. Linux修改用户组

    usermod -g group loginname 强行设置某个用户所在组 usermod -G groups loginname 把某个用户改为 group(s) usermod -a -G gr ...

  3. Linux根文件系统的制作

    转载:http://www.cnblogs.com/hnrainll/archive/2011/06/09/2076655.html 1. 根文件系统 文件系统是包括在一个磁盘(包括光盘.软盘.闪盘及 ...

  4. javascript函数中的实例对象、类对象、局部变量(局部函数)

    定义 function Person(national,age) { this.age = age; //实例对象,每个示例不同 Person.national = national; //类对象,所 ...

  5. google gflags使用.

    code.google.com 被墙的好开心... gflags很简单. 编译使用都很简单. (不像omaha这种丧心病狂的编译依赖). cmake 生成一下. 一路顺风顺水. 值得注意的是:  默认 ...

  6. NSNotificationCenter 使用姿势详解

    来源:JamesYu 链接:http://www.jianshu.com/p/a4d519e4e0d5 最近在做平板的过程中,发现了一些很不规范的代码.偶然修复支付bug的时候,看到其他项目代码,使用 ...

  7. EMS电子面单接口对接使用-免费版

    快递鸟电子面单接口,可一次对接15家快递公司, 无需和每一家快递公司做对接.支持快递有四通一达.顺丰.EMS.宅急送.德邦.优速等15家快递公司,对顺丰有电子面单服务需求的可以选择顺丰自有的电子面单或 ...

  8. 从零开始学JAVA(06)-WebService_Jersey_Restful

    由于项目上需要写一个简单的评价系统,像银行MM前面的那种非常满意.满意.不满意那种,结合一个安卓的APP一起使用.由于使用3G网页通讯,个人认为http这种方式更合适.曾经听在Delphi鸟窝群的白雪 ...

  9. Long Long Message 后缀数组入门题

    Long Long Message Time Limit: 4000MS   Memory Limit: 131072K Total Submissions: 22564   Accepted: 92 ...

  10. Handle类的用法

    android中Handle类的用法 当我们在处理下载或是其他需要长时间执行的任务时,如果直接把处理函数放Activity的OnCreate或是OnStart中,会导致执行过程中整个Activity无 ...