反射機制指的是程序在運行時可以獲取自身的信息。在java中,只要給定類的名字,
那麼就能夠經過反射機制來得到類的全部信息。java
反射機制建立類對象sql
Class c=Class.forName("className");註明:className必須爲全名,也就是得包含包名,好比,com.cnblog.Bean;
Object obj=c.newInstance();//建立對象的實例數據庫
有了類對象就能夠對該類的方法及屬性進行操做 app
能夠對全部單表的增刪查改,無需新建對應的DAO文件,即新增表操做的的時候,只須要創建表的對應的javabean便可,無需新建表的DAO文件ide
鏈接數據庫的類 DBConnection.java測試
DAO的實現類 DAOImpl.javaui
DAO的代理類 DAOProxy.javathis
各個表的beanurl
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(); } }
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; } }
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; } }
創建對應的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; } }
測試代碼
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);
}