该工具类是在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>里面为例子,调用的函数如下所示:
原文:https://www.cnblogs.com/halone/p/10494715.html