通过代理类实现java连接数据库(使用dao层操作数据)实例分享
首先,我们在一个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方法获取代理类,代理类调用特定方法,然后由代理类内的具体操作对象去调用具体的操作方法。
其实这些东西看起来会觉得很简单,但是自己设计的时候往往会忘记。主要是因为用得不多吧,一开始总是要强迫自己想起来去做,然后慢慢地才能变成一种习惯。