JavaWeb編程中mysql數據庫操作通用工具類
該工具類是在JavaWeb中連接mysql所用到的通用工具類
該類用於Java+Servlet的編程中,方便數據庫的操作,連接,獲取其列表值。下面是這個數據庫操作類的通用方法,基本上能夠用於類裏面只含有簡單數據的類,例如類是Date,int,double,String等數據庫裏面包含的類型。
這個並不是一個模板,而是一個工具類,也就是說,符合只有簡單數據的類可以直接調用以下提供的功能就能操作數據庫,返回類的List的值。
之前在進行編程的時候發現在操作數據庫的過程中特別麻煩,每次重新寫一個新類要存儲到數據庫的話,總是要在service寫新的方法才能適應相應的操作,但是我覺得這些方法大都大同小異,似乎沒有必要每次都為一個類寫一個方法適應一個新的類。所以寫這個通用數據庫操作的類的想法就產生了。
首先,該工具主要是對數據庫進行操作,所以首先要對數據庫進行連接,下面是實現對數據庫連接的一個DBUtil.java文件,實現了對數據庫的連接
package com.hjf.util; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 數據庫連接工具 *@author HDQ * */ public class DBUtil { public static String db_url = "jdbc:mysql://localhost:3306/數據庫名"; public static String db_user = "數據庫用戶名"; public static String db_pass = "數據庫密碼"; public static Connection getConn () { Connection conn = null;try { Class.forName("com.mysql.jdbc.Driver");//加載驅動 conn = DriverManager.getConnection(db_url, db_user, db_pass); } catch (Exception e) { e.printStackTrace(); } return conn; } /** * 關閉連接 * @param state * @param conn */ public static void close (Statement state, Connection conn) { if (state != null) { try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void close (ResultSet rs, Statement state, Connection conn) { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (state != null) { try { state.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) throws SQLException { Connection conn = getConn(); PreparedStatement pstmt = null; ResultSet rs = null; String sql ="select * from course"; pstmt = conn.prepareStatement(sql); rs = pstmt.executeQuery(); if(rs.next()){ System.out.println("空"); }else{ System.out.println("不空"); } } }
然後在對數據庫連接完成之後,接著就是對數據庫進行操作的一個類了,這個類位於dao層
這個ClassDao.java類可以根據傳遞進來的參數返回相應類型的類的List,其實現的原理是利用Field 反射其值到對應的類裏面,所以在使用的時候帶有返回List的功能的時候,其數據庫裏面的數據項名稱和類裏面定義的變量的名稱需要保持一致,才能保證其值被正確反射到類裏面,反射機制所以返回的類的List都已經被賦予相應的值,可以直接被使用
相應的操作方法用法會在本文的最後給出,ClassDao.java是一個通用操作類,實現了對數據庫操作
package com.hjf.dao; import java.lang.reflect.Field; import java.lang.reflect.Modifier; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.List; import com.hjf.util.DBUtil; /** * 通用類Dao * Dao層操作數據 * @author HDQ * */ public class ClassDao { /** * 添加 * @return */ public <T> boolean add(String table,String []strList,String []strList1) { if(strList.length==0) return false; String sql = "insert into "+table+"("; for(int i=0;i<strList.length;i++) { if(i!=strList.length-1) sql+=strList[i]+","; else sql+=strList[i]+")"; } sql+=" values(‘"; for(int i=0;i<strList1.length;i++) { if(i!=strList1.length-1) sql+=strList1[i]+"‘,‘"; else sql+=strList1[i]+"‘)"; } //創建數據庫鏈接 Connection conn = DBUtil.getConn(); Statement state = null; boolean f = false; int a = 0; try { state = conn.createStatement(); a=state.executeUpdate(sql); } catch (Exception e) { e.printStackTrace(); } finally { //關閉連接 DBUtil.close(state, conn); } if (a > 0) { f = true; } return f; } /** * 刪除 * * @return */ public boolean delete (String table,String zhixing,String biaoshi) { boolean f = false; String sql = "delete from "+table+" where "+zhixing+"=‘" + biaoshi + "‘"; Connection conn = DBUtil.getConn(); Statement state = null; int a = 0; try { state = conn.createStatement(); a = state.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(state, conn); } if (a > 0) { f = true; } return f; } /** * 修改*/ public boolean update(String table,String []strlist,String []strlist1,String qian,String hou) { String sql = "update "+table+" set "; for(int i=0;i<strlist.length;i++) { if(i!=strlist.length-1) sql+=strlist[i]+"=‘" + strlist1[i] + "‘,"; else sql+=strlist[i]+"=‘" + strlist1[i] + "‘ where "+qian+"=‘" + hou + "‘"; } Connection conn = DBUtil.getConn(); Statement state = null; boolean f = false; int a = 0; try { state = conn.createStatement(); a = state.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(state, conn); } if (a > 0) { f = true; } return f; } /** * 驗證通用類名稱是否唯一 * true --- 不唯一 * @return */ public boolean name(String table,String zhi,String weiyi) { boolean flag = false; String sql = "select "+zhi+" from "+table+" where "+zhi+" = ‘" + weiyi + "‘"; Connection conn = DBUtil.getConn(); Statement state = null; ResultSet rs = null; try { state = conn.createStatement(); rs = state.executeQuery(sql); while (rs.next()) { flag = true; } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(rs, state, conn); } return flag; } /** * 查找 * @return * @throws IllegalAccessException * @throws InstantiationException */ @SuppressWarnings("deprecation") public <T> List<T> search(String table,String []strList,String []strList1,Class<T> clazz) throws InstantiationException, IllegalAccessException { String sql = "select * from "+table; int i=0,k=0; for(String it:strList1) { if(it!=null&&!it.equals("")) { if(k==0) sql +=" where "+ strList[i]+" like ‘%" + it + "%‘"; else sql +=" and "+ strList[i]+" like ‘%" + it + "%‘"; ++k; } ++i; } List<T> list = new ArrayList<>(); Connection conn = DBUtil.getConn(); Statement state = null; ResultSet rs = null; try { state = conn.createStatement(); rs = state.executeQuery(sql); T bean = null; while (rs.next()) { bean=clazz.newInstance(); for(String it:strList) { Field fs=getDeclaredField(bean, it); if(fs==null){ throw new IllegalArgumentException("Could not find field["+ it+"] on target ["+bean+"]"); } makeAccessiable(fs); try{ fs.set(bean, rs.getObject(it)); } catch(IllegalAccessException e){ System.out.println("不可能拋出的異常"); } } list.add(bean); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(rs, state, conn); } return list; } /** * 由時間和條件查找 * @return * @throws IllegalAccessException * @throws InstantiationException */ @SuppressWarnings("deprecation") public <T> List<T> searchByTime(String table,String []strList,String []strList1,String biaoshi,String qian,String hou,Class<T> clazz) throws InstantiationException, IllegalAccessException { String sql = "select * from "+table+" where "; int i=0,k=0; for(String it:strList1) { if(it!=null&&!it.equals("")) { sql += strList[i]+" like ‘%" + it + "%‘"; ++k; } ++i; } if(qian!=null&&!qian.equals("")) { if(k>0) sql+=" and "+biaoshi+" Between ‘"+qian+"‘ AND ‘"+hou+"‘"; else sql+=biaoshi+" Between ‘"+qian+"‘ AND ‘"+hou+"‘"; } //and shijian Between ‘"+request.getParameter("shijian1")+"‘ AND ‘"+request.getParameter("shijian2")+"‘" //查詢的時間格式例如:2015-10-27 24:00:0(假如為DateTime的話,Date只需要年-月-日) List<T> list = new ArrayList<>(); Connection conn = DBUtil.getConn(); Statement state = null; ResultSet rs = null; try { state = conn.createStatement(); rs = state.executeQuery(sql); T bean = null; while (rs.next()) { bean=clazz.newInstance(); for(String it:strList) { Field fs=getDeclaredField(bean, it); if(fs==null){ throw new IllegalArgumentException("Could not find field["+ it+"] on target ["+bean+"]"); } makeAccessiable(fs); try{ fs.set(bean, rs.getObject(it)); } catch(IllegalAccessException e){ System.out.println("不可能拋出的異常"); } } list.add(bean); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(rs, state, conn); } return list; } /** * 創建數據庫 * @return * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ public boolean createTable(String table,String []info,String []type,int []size) { String sql = "CREATE TABLE "+table+"("; String lei[]=new String[] {"char","varchar"}; int i=0; for(String it:info) { if(!it.equals("")) { boolean g_trit=false; for(String sit:lei) { if(type[i].toLowerCase().contains(sit.toLowerCase())) { g_trit=true; } } if(g_trit) sql += it+" "+type[i]+"("+size[i]+")"; else sql += it+" "+type[i]; } if(i!=info.length-1) sql+=","; ++i; } sql+=")"; //and shijian Between ‘"+request.getParameter("shijian1")+"‘ AND ‘"+request.getParameter("shijian2")+"‘" //查詢的時間格式例如:2015-10-27 24:00:0 Connection conn = DBUtil.getConn(); Statement state = null; ResultSet rs = null; int a=0; boolean f=false; try { state = conn.createStatement(); a = state.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(rs, state, conn); } if(a>0) f=true; return f; } /** * 全部數據 * @return * @throws ClassNotFoundException * @throws IllegalAccessException * @throws InstantiationException */ @SuppressWarnings("deprecation") public <T> List<T> list(String table,String []strList,Class<T> clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException { String sql = "select * from "+table; List<T> list = new ArrayList<>(); Connection conn = DBUtil.getConn(); Statement state = null; ResultSet rs = null; try { state = conn.createStatement(); rs = state.executeQuery(sql); T bean = null; while (rs.next()) { bean=clazz.newInstance(); for(String it:strList) { Field fs=getDeclaredField(bean, it); if(fs==null){ throw new IllegalArgumentException("Could not find field["+ it+"] on target ["+bean+"]"); } makeAccessiable(fs); try{ fs.set(bean, rs.getObject(it)); } catch(IllegalAccessException e){ System.out.println("不可能拋出的異常"); } } list.add(bean); } } catch (SQLException e) { e.printStackTrace(); } finally { DBUtil.close(rs, state, conn); } return list; } //獲取field屬性,屬性有可能在父類中繼承 public static Field getDeclaredField(Object obj,String fieldName){ for (Class<?> clazz=obj.getClass(); clazz!=Object.class; clazz=clazz.getSuperclass()){ try{ return clazz.getDeclaredField(fieldName); } catch(Exception e){ } } return null; } //判斷field的修飾符是否是public,並據此改變field的訪問權限 public static void makeAccessiable(Field field){ if(!Modifier.isPublic(field.getModifiers())){ field.setAccessible(true); } } }
在dao層裏面的方法應該是為了安全性考慮吧,還要有一個sevice類來調用dao層裏面的方法,就相當一個中介一樣吧,也就是一個提供dao層裏面接口的一個類,以下是位於service層的service.java,實現dao層方法的接口
package com.hjf.service; import java.util.List; import com.hjf.dao.ClassDao; /** * CourseService * 服務層 * @author HDQ * */ public class ClassService { ClassDao cDao = new ClassDao(); /** * 添加 * @param course * @return */ public boolean add(String table,String strList[],String strList1[]) { boolean f = cDao.add(table,strList,strList1); return f; } /** * 刪除 */ public boolean del(String table,String qian,String hou) { return cDao.delete(table,qian,hou); } /** * 修改 * @return */ public boolean update(String table,String []strlist,String []strlist1,String qian,String hou) { return cDao.update(table,strlist,strlist1,qian,hou); } /** * 查找 * @return * @throws IllegalAccessException * @throws InstantiationException */ public <T> List<T> search(String table, String []strList, String []strList1,Class<T> clazz) throws InstantiationException, IllegalAccessException { return cDao.search(table,strList,strList1,clazz); } /** * 由時間查找 * @return * @throws IllegalAccessException * @throws InstantiationException */ public <T> List<T> searchByTime(String table, String []strList, String []strList1,String biaoshi,String qian,String hou,Class<T> clazz) throws InstantiationException, IllegalAccessException { return cDao.searchByTime(table, strList, strList1, biaoshi, qian, hou, clazz); } /** * 全部數據 * @return * @throws IllegalAccessException * @throws InstantiationException * @throws ClassNotFoundException */ public <T> List<T> list(String table,String []strList,Class<T> clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException { return cDao.list(table,strList,clazz); } /** * 創建數據庫表單 * @return * @throws IllegalAccessException * @throws InstantiationException */ public boolean createTable(String table,String []info,String []type,int []size) { return cDao.createTable(table, info, type, size); } }
其3個類組成的工具類就如上面所示。
就以一個查找功能為例子,我現在Entity層中有3個類用到了這個通用類,假如現在想再定義一個新類調用這個通用數據庫的函數,實現對數據庫對這個類的數據的增刪改查功能,以下就以一個具體的例子來展示如何調用這個通用類的函數
然後下面介紹這個通用類的用法:
首先假如現在有一個類,位於entity層,假如是一個老師類,Teacher
然後在entity層中定義一個Teacher類,其中含有int類型的編號id,String類型的名字name,還有Date類型的出生日期birth,(定義的類的多少不受限制),並定義getter和setter的方法
定義完這個類之後,數據庫裏面對應的項的名稱要和類的名稱一致,這樣才能被正確反射
所以在數據庫裏面新建一個teacherlist的表,對應的項的名稱設置為int類型的id,char或者text類型的name,Date類型的birth
名字分別都與Teacher類裏面的名稱相對應
雖然該工具類裏面有提供表創建的函數,但是為了方便讀者理解,這裏用數據庫管理軟件的創建過程來展示
創建完成之後,要實現往這個數據庫的teacherlist裏面添加數據的功能的話,我們查看一下service層提供的接口
這個是ClassServlet裏面的前綴,ClassService就是數據庫通用工具的接口類,可以通過調用這個service裏面的函數實現數據的操作
//--------------添加功能--------------
提供的方法是add(table,strList[],strList1[]),返回的類型是boolean類型
第一個參數是table表名,第二個參數strList是需要添加的項的名稱字符串組,第三個參數strList1是對應要需要添加項的內容
例如執行
String []str=new String[] {"id","name","birth"};
String []str1=new String[] {"11","王老師",“2001-09-22”};
service.add("teacherlist",str,str1);
就會將數據庫中teacherlist裏面對應的id,name,birth項添加上11,王老師,2001-09-22的信息
當出現數據添加失敗的時候,add函數會返回一個false,執行成功時則是true
//--------------獲取列表功能--------------
首先上述是teacherlist數據庫表的信息,現在如果我們想把所有信息獲取到一個List<Teacher>裏面,可以調用service提供的
獲取全部數據的方法
list(table,strlist[],Class);
其中參數table是要獲取數據的表格名稱,strList[]填寫的是要獲取數據庫中的哪個項的名稱所對應的信息,Class是需要返回的List<>數組的類型,不過這個返回的類型一般還得強制轉換一下
以獲取上述的數據到一個List<Teacher>裏面為例子,調用的函數如下所示:
JavaWeb編程中mysql數據庫操作通用工具類