利用JAVA反射機制設計通用的DAO

利用JAVA反射機制設計一個通用的DAO

反射機制

   反射機制指的是程序在運行時可以獲取自身的信息。在java中,只要給定類的名字,    
那麼就能夠經過反射機制來得到類的全部信息。java

   反射機制建立類對象sql

    Class c=Class.forName("className");註明:className必須爲全名,也就是得包含包名,好比,com.cnblog.Bean;   
    Object obj=c.newInstance();//建立對象的實例數據庫

    有了類對象就能夠對該類的方法及屬性進行操做   app

通用DAO

    能夠對全部單表的增刪查改,無需新建對應的DAO文件,即新增表操做的的時候,只須要創建表的對應的javabean便可,無需新建表的DAO文件ide

 

代碼結構也比較簡單

鏈接數據庫的類 DBConnection.java測試

DAO的實現類 DAOImpl.javaui

DAO的代理類 DAOProxy.javathis

各個表的beanurl

 

DBConnection.java 鏈接數據庫的類

package Utils;

import java.sql.Connection;
import java.sql.DriverManager;

public class DBConnection {
	private Connection conn;
	private String url;
	private String user;
	private String password;
	private String driver;
	
	
	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public String getUser() {
		return user;
	}

	public void setUser(String user) {
		this.user = user;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public String getDriver() {
		return driver;
	}

	public void setDriver(String driver) {
		this.driver = driver;
	}

	public Connection connection()throws Exception{
		try{
			Class.forName(driver);
		}catch(Exception e){
			System.out.println("Load error!");
			e.printStackTrace();
		}
	
	    
	    try{
	    	conn=DriverManager.getConnection(url, user, password);
	    }catch(Exception e){
	    	System.out.println("Login error ,please check your login information");
	    	e.printStackTrace();
	    }
	    
	    return conn;
		
	}
	
	public void close() throws Exception{
	
		this.conn.close();
		
	}

}

 

DAOImpl.java  增刪查改的實現類,全部的bean都做爲Object進來,而後經過反射機制拼裝數據庫操做的sql

query() 傳入的bean不須要每一個屬性都賦值,篩選已賦值的屬性拼裝sql,篩選的時候利用反射機制中的反射屬性Field[] fields =object.getClass().getFields()spa

insert() 拼裝sql時無需篩選未賦值的屬性,未賦值的直接插入null

update() 傳入兩個bean,第一個是更新前的記錄,第二個是更新後的記錄

delete() 傳入的bean不須要每一個屬性都賦值,篩選已賦值的屬性拼裝sql,篩選的時候利用反射機制中的反射屬性Field[] fields =object.getClass().getFields()

package DAO;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

import Bean.*;
import Utils.DBConnection;

public class DAOImpl {
    
    private DBConnection dataSource;
    DAOImpl(DBConnection dataSource) throws Exception{
        this.dataSource=dataSource;    
    }


    
    public ArrayList<Object> query(Object object) throws Exception{
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        ArrayList result=new ArrayList();
        //記錄非空的屬性值,用於SQL的變量綁定
        ArrayList args=new ArrayList();
        
        StringBuilder condition=new StringBuilder();
        String sql="select * from "+object.getClass().getSimpleName()+" where 1=1 ";
        
        //取出對象中的值做爲條件,若是值爲null則不加入查詢條件中
        Field[] fields=object.getClass().getFields();
        for(Field field:fields){
            field.setAccessible(true);
            if(this.isBlank(field.get(object))==false){
                    condition.append(" and ").append(field.getName()).append("=").append("?");    
                    args.add(field.get(object));
            }
            
        }
        sql=sql+condition.toString();

        //訪問數據庫返回查詢結果
        try{
        conn=dataSource.connection();
        ps=conn.prepareStatement(sql);
        for(int i=0;i<args.size();i++){
            //綁定變量下標從1開始
            ps.setObject(i+1, args.get(i));
        }
        rs=ps.executeQuery();
        
        //將查詢結果放到bean中
        while(rs.next()){
            //利用反射機制新建bean實例
            String className=object.getClass().getName();
            Class<?> obj=Class.forName(className);
            Object resultBean=obj.newInstance();
            Field[] resultFields=resultBean.getClass().getFields();
            for(Field resultField:resultFields){
                resultField.setAccessible(true);
                resultField.set(resultBean, rs.getObject(resultField.getName()));
            }
            
            result.add(resultBean);
        }
        
        
        }catch(Exception e){
            System.out.println("Operation in database fail");
            e.printStackTrace();
        }finally{ 
            if(rs != null){   // 關閉記錄集    
            try{    
                rs.close() ;    
            }catch(SQLException e){    
                e.printStackTrace() ;    
            }    
              }    
              if(ps != null){   // 關閉聲明    
            try{    
                ps.close() ;    
            }catch(SQLException e){    
                e.printStackTrace() ;    
            }    
              }    
              if(conn != null){  // 關閉鏈接對象    
             try{    
                conn.close() ;    
             }catch(SQLException e){    
                e.printStackTrace() ;                
             }                  
              } }
        return result;
    }
    
    public boolean insert(Object object) throws Exception{
        boolean flag=false;
        Connection conn=null;
        PreparedStatement ps=null;

                
        StringBuilder area=new StringBuilder("(");
        StringBuilder value=new StringBuilder("(");
        //獲取Bean下全部的fields
        Field[] fields=object.getClass().getFields();
        //組裝Sql
        String sql="insert into "+object.getClass().getSimpleName();
        
        for(int i=0 ;i<fields.length;i++){
            area.append(fields[i].getName());
            value.append("?");
            if(i<fields.length-1){
                area.append(",");
                value.append(",");
            }
        }
        
        area.append(")");
        value.append(")");
        
        sql=sql+area.toString()+" values "+value.toString();
        System.out.println(sql);
        
        try{
            conn=dataSource.connection();
            ps = conn.prepareStatement(sql);
        for(int i=0;i<fields.length;i++){
            fields[i].setAccessible(true);
            //setObject 下標 從1開始
            ps.setObject(i+1,fields[i].get(object));
            System.out.println(fields[i]);
        }
       if(ps.executeUpdate()>0){
           flag=true;
       }
       
        }catch(Exception e){
            System.out.println("Operation in database fail");
            e.printStackTrace();
        }finally{
            if(ps != null){   // 關閉聲明    
                try{    
                    ps.close() ;    
                }catch(SQLException e){    
                    e.printStackTrace() ;    
                }    
                  }    
                  if(conn != null){  // 關閉鏈接對象    
                 try{    
                    conn.close() ;    
                 }catch(SQLException e){    
                    e.printStackTrace() ;                
                 }                  
                  }
        }
      
     return flag;
    }
    
    public boolean update(Object previous,Object follow) throws Exception{
        boolean flag=false;
        Connection conn=null;
        PreparedStatement ps=null;
        ArrayList preArgs=new ArrayList();
        ArrayList folArgs=new ArrayList();
        
        
        //獲取where條件的字段值
        Field[] preFields=previous.getClass().getFields();
        
        //獲取set的字段值
        Field[] folFields=follow.getClass().getFields();
        
        StringBuilder set=new StringBuilder("");
        StringBuilder where=new StringBuilder("");
        
        String sql="update "+previous.getClass().getSimpleName()+" set 1=1";
        
        //組裝sql語句
        for(Field folField:folFields){
            //若是bean中的屬性值沒有被set方法賦值過則不添加到sql語句的條件中
            if(this.isBlank(folField.get(follow))==false){
                    set.append(",").append(folField.getName()).append(" = ").append("?");
                    folArgs.add(folField.get(follow));
            
            }
        }
        
        sql=sql+set.toString()+" where 1=1 ";
        
        for(Field preField:preFields){
            if(this.isBlank(preField.get(previous))==false){
                
                    where.append(" and ").append(preField.getName()).append(" = ").append("?");
                    preArgs.add(preField.get(previous));
            }
        }
        
        sql=sql+where.toString();
        System.out.println(sql);
        
        try{
            
            conn=dataSource.connection();
            ps=conn.prepareStatement(sql);
            //先綁定set部分的變量,而後再綁定where部分的變量
            for(int i=0;i<(folArgs.size()+preArgs.size());i++){
                if(i<folArgs.size()){
                    ps.setObject(i+1, folArgs.get(i));
                }else{
                    ps.setObject(i+1, preArgs.get(i-folArgs.size()));
                }
                                
            }
            if(ps.executeUpdate()>0){
                flag=true;
            }
        }catch(Exception e){
            System.out.println("Operation in database fail");
            e.printStackTrace();
        }finally{
            if(ps != null){   // 關閉聲明    
                try{    
                    ps.close() ;    
                }catch(SQLException e){    
                    e.printStackTrace() ;    
                }    
                  }    
                  if(conn != null){  // 關閉鏈接對象    
                 try{    
                    conn.close() ;    
                 }catch(SQLException e){    
                    e.printStackTrace() ;                
                 }                  
                  }
        }

    return flag;
    }
    
    public boolean delete(Object object) throws Exception{
        boolean flag=false;
        Connection conn=null;
        PreparedStatement ps=null;
        ArrayList args=new ArrayList();
        
        
        //獲取where條件的字段值
        Field[] fields=object.getClass().getFields();
        StringBuilder where=new StringBuilder("");
        
        //拼裝sql
        String sql="delect from "+object.getClass().getSimpleName()+" where 1=1";
        
        for(Field field:fields){
            //若是屬性值沒有被set方法設置過,則不添加到條件進去
            if(this.isBlank(field.get(object))==false){
                
                    where.append(" and ").append(field.getName()).append("=").append("?");
                    args.add(field.get(object));                
            }
        }
        
        sql=sql+where.toString();
        System.out.println(sql);
        
        try{
            conn=dataSource.connection();
            ps=conn.prepareStatement(sql);
            for(int i=0;i>args.size();i++){
                //綁定變量下標從1開始
                ps.setObject(i+1, args.get(i));
            }
            if(ps.executeUpdate()>0){
                flag=true;
            }
        }catch(Exception e){
            System.out.println("Operation in database fail");
            e.printStackTrace();
        }finally{
            if(ps != null){   // 關閉聲明    
                try{    
                    ps.close() ;    
                }catch(SQLException e){    
                    e.printStackTrace() ;    
                }    
                  }    
                  if(conn != null){  // 關閉鏈接對象    
                 try{    
                    conn.close() ;    
                 }catch(SQLException e){    
                    e.printStackTrace() ;                
                 }                  
                  }
        }
        return flag;
    }
    
    /*
     * @description 判斷bean屬性值是否爲空
     */
    public boolean isBlank(Object object){
        
        boolean flag;
        if(null==object||"".equals(object)){
            flag=true;
        }else{
            flag=false;
        }
                
        return flag;
    }
    
    
}
View Code

 

DAOProxy.java DAO的代理,DBConnection和DAOImpl的鏈接橋樑

package DAO;

import java.util.ArrayList;

import Utils.DBConnection;

public class DAOProxy {
    private DBConnection dataSource;
    DAOProxy(DBConnection dataSource){
        this.dataSource=dataSource;
        
    }
    
    public ArrayList doQuery(Object object)throws Exception{
        ArrayList result=new ArrayList();
        DAOImpl dao=new DAOImpl(dataSource);
        result=dao.query(object);
        return result;
    }
    
    public boolean doInsert(Object object)throws Exception{
        boolean result;
        DAOImpl dao=new DAOImpl(dataSource);
        result=dao.insert(object);
        return result;
    }
    
    public boolean doUpdate(Object previous,Object follow)throws Exception{
        boolean result;
        DAOImpl dao=new DAOImpl(dataSource);
        result=dao.update(previous,follow);
        return result;
        
    }
    
    public boolean doDelete(Object object)throws Exception{
        boolean result;
        DAOImpl dao=new DAOImpl(dataSource);
        result=dao.delete(object);
        return result;
    }

}
View Code

 

Bean.java 數據庫表對應的javabean

創建對應的javabean時須要注意,屬性類型最好不要用基本數據類型,由於這些數據類型會自動初始化,即int類型的屬性默認是0,若是沒有給該屬性賦值,即插入到數據庫的時候是0而不是空

其中一個bean的例子

package Bean;

import java.math.BigDecimal;
import java.util.Date;

public class Employee {
    public BigDecimal emp_id;
    public String emp_name;
    public String emp_dep;
    public Date entry_time;
    public BigDecimal getEmp_id() {
        return emp_id;
    }
    public void setEmp_id(BigDecimal emp_id) {
        this.emp_id = emp_id;
    }
    public String getEmp_name() {
        return emp_name;
    }
    public void setEmp_name(String emp_name) {
        this.emp_name = emp_name;
    }
    public String getEmp_dep() {
        return emp_dep;
    }
    public void setEmp_dep(String emp_dep) {
        this.emp_dep = emp_dep;
    }
    public Date getEntry_time() {
        return entry_time;
    }
    public void setEntry_time(Date entry_time) {
        this.entry_time = entry_time;
    }
    
        

}
View Code

 

測試代碼

public static void main(String[] args){

 

    //設置數據庫鏈接
     DBConnection dbSource=new DBConnection();
    dbSource.setDriver(driver);
    dbSource.setUser(user);
    dbSource.setPassword(password);
    dbSource.setUrl(url);


    DAOProxy testDAO=new DAOProxy(dbSource)
    Employee jack=new Employee();
    jack.setEmp_id(123);
    jack.setEmp_name("jack");
    jack.setEmp_dep("dev");
    testDAO.doInsert(jack);
  
    Employee jack2=new Employee();
    jack2.setEmp_id(123);
    jack2.setEmp_name("jack");
    jack2.setEmp_dep("test");
    testDAO.doUpdate(jack, jack2);

}

相關文章
相關標籤/搜索