该工具类是在JavaWeb中连接mysql所用到的通用工具类
该类用于Java+Servlet的编程中,方便数据库的操作,连接,获取其列表值。下面是这个数据库操作类的通用方法,基本上能够用于类里面只含有简单数据的类,例如类是Date,int,double,String等数据库里面包含的类型。
这个并不是一个模板,而是一个工具类,也就是说,符合只有简单数据的类可以直接调用以下提供的功能就能操作数据库,返回类的List的值。
之前在进行编程的时候发现在操作数据库的过程中特别麻烦,每次重新写一个新类要存储到数据库的话,总是要在service写新的方法才能适应相应的操作,但是我觉得这些方法大都大同小异,似乎没有必要每次都为一个类写一个方法适应一个新的类。所以写这个通用数据库操作的类的想法就产生了。
首先,该工具主要是对数据库进行操作,所以首先要对数据库进行连接,下面是实现对数据库连接的一个DBUtil.java文件,实现了对数据库的连接
packagecom.hjf.util;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;/*** 数据库连接工具
*@authorHDQ
**/
public classDBUtil {public static String db_url = "jdbc:mysql://localhost:3306/数据库名";public static String db_user = "数据库用户名";public static String db_pass = "数据库密码";public staticConnection 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();
}returnconn;
}/*** 关闭连接
*@paramstate
*@paramconn*/
public static voidclose (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 voidclose (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) throwsSQLException {
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是一个通用操作类,实现了对数据库操作
packagecom.hjf.dao;importjava.lang.reflect.Field;importjava.lang.reflect.Modifier;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;importjava.util.ArrayList;importjava.util.List;importcom.hjf.util.DBUtil;/*** 通用类Dao
* Dao层操作数据
*@authorHDQ
**/
public classClassDao {/*** 添加*@return
*/
public booleanadd(String table,String []strList,String []strList1) {if(strList.length==0)return false;
String sql= "insert into "+table+"(";for(int i=0;i
{if(i!=strList.length-1)
sql+=strList[i]+",";else sql+=strList[i]+")";
}
sql+=" values('";for(int i=0;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;
}returnf;
}/*** 删除
**@return
*/
public booleandelete (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;
}returnf;
}/*** 修改*/
public booleanupdate(String table,String []strlist,String []strlist1,String qian,String hou) {
String sql= "update "+table+" set ";for(int i=0;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;
}returnf;
}/*** 验证通用类名称是否唯一
* true --- 不唯一
*@return
*/
public booleanname(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);
}returnflag;
}/*** 查找*@return*@throwsIllegalAccessException
*@throwsInstantiationException*/@SuppressWarnings("deprecation")public List search(String table,String []strList,String []strList1,Class clazz) throwsInstantiationException, 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 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);
}returnlist;
}/*** 由时间和条件查找*@return*@throwsIllegalAccessException
*@throwsInstantiationException*/@SuppressWarnings("deprecation")public List searchByTime(String table,String []strList,String []strList1,String biaoshi,String qian,String hou,Class clazz) throwsInstantiationException, 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 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);
}returnlist;
}/*** 创建数据库*@return*@throwsClassNotFoundException
*@throwsIllegalAccessException
*@throwsInstantiationException*/
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;returnf;
}/*** 全部数据*@return*@throwsClassNotFoundException
*@throwsIllegalAccessException
*@throwsInstantiationException*/@SuppressWarnings("deprecation")public List list(String table,String []strList,Class clazz) throwsClassNotFoundException, InstantiationException, IllegalAccessException {
String sql= "select * from "+table;
List 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);
}returnlist;
}//获取field属性,属性有可能在父类中继承
public staticField getDeclaredField(Object obj,String fieldName){for (Class> clazz=obj.getClass(); clazz!=Object.class; clazz=clazz.getSuperclass()){try{returnclazz.getDeclaredField(fieldName);
}catch(Exception e){
}
}return null;
}//判断field的修饰符是否是public,并据此改变field的访问权限
public static voidmakeAccessiable(Field field){if(!Modifier.isPublic(field.getModifiers())){
field.setAccessible(true);
}
}
}
在dao层里面的方法应该是为了安全性考虑吧,还要有一个sevice类来调用dao层里面的方法,就相当一个中介一样吧,也就是一个提供dao层里面接口的一个类,以下是位于service层的service.java,实现dao层方法的接口
packagecom.hjf.service;importjava.util.List;importcom.hjf.dao.ClassDao;/*** CourseService
* 服务层
*@authorHDQ
**/
public classClassService {
ClassDao cDao= newClassDao();/*** 添加
*@paramcourse
*@return
*/
public booleanadd(String table,String strList[],String strList1[]) {boolean f =cDao.add(table,strList,strList1);returnf;
}/*** 删除*/
public booleandel(String table,String qian,String hou) {returncDao.delete(table,qian,hou);
}/*** 修改
*@return
*/
public booleanupdate(String table,String []strlist,String []strlist1,String qian,String hou) {returncDao.update(table,strlist,strlist1,qian,hou);
}/*** 查找
*@return*@throwsIllegalAccessException
*@throwsInstantiationException*/
public List search(String table, String []strList, String []strList1,Class clazz) throwsInstantiationException, IllegalAccessException {returncDao.search(table,strList,strList1,clazz);
}/*** 由时间查找
*@return*@throwsIllegalAccessException
*@throwsInstantiationException*/
public List searchByTime(String table, String []strList, String []strList1,String biaoshi,String qian,String hou,Class clazz) throwsInstantiationException, IllegalAccessException {returncDao.searchByTime(table, strList, strList1, biaoshi, qian, hou, clazz);
}/*** 全部数据
*@return*@throwsIllegalAccessException
*@throwsInstantiationException
*@throwsClassNotFoundException*/
public List list(String table,String []strList,Class clazz) throwsClassNotFoundException, InstantiationException, IllegalAccessException {returncDao.list(table,strList,clazz);
}/*** 创建数据库表单
*@return*@throwsIllegalAccessException
*@throwsInstantiationException*/
public boolean createTable(String table,String []info,String []type,int[]size)
{returncDao.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 []strList=new String[] {"id","name","birth"};
String []strList1=new String[] {"11","王老师",“2001-09-22”};
service.add("teacherlist",strList,strList1);
就会将数据库中teacherlist表里面对应的id,name,birth项添加上11,王老师,2001-09-22的信息
值得注意的是,strLis[]里面的字符串要对应和类中的变量名称相等,而且数据库中的名称也是,这样才能正确的反射,当然,添加的过程并没有用到反射,但是规范化而言,用到list等功能的时候就可以直接使用了。
当出现数据添加失败的时候,add函数会返回一个false,执行成功时则是true
//--------------获取列表信息功能--------------
首先上述是teacherlist数据库表的信息,现在如果我们想把所有信息获取到一个List里面,可以调用service提供的
获取全部数据的方法
list(table,strlist[],Class);
其中参数table是要获取数据的表格名称,strList[]填写的是要获取数据库中的哪个项的名称所对应的信息,Class是需要返回的List<>数组的类型,不过这个返回的类型一般还得强制转换一下
以获取上述的数据到一个List里面为例子,调用的函数如下所示:
String []strList=new String[]{"id","name","birth"};
@SuppressWarnings("unchecked")
List teachers= (List) service.list("teacherlist",strList,new Teacher().getClass());
此时teachers变量里面就储存了你想要的数据了。然后,如果想要获取的数据项没有birth这个的话,在strList中填写对应想要获取的数据项就可以了,String []strList=new String[]{"id","name"};再执行获取的函数,这个时候获取的teachers里面的birth就没有储存数据了
然后这里拓展一点小知识,获取的list可以存储到attribute里面后直接在网页上输出,当然要利用到jstl.jar和standard.jar这两个包
这里调用tlist这个函数的时候,将会跳转到teacherlist这个网页
Insert title hereObjectmessage=request.getAttribute("message");if(message!=null &&!"".equals(message)){%>
alert("");
老师信息列表
返回主页
编号id名字出生日期${item.id}${item.name}${item.birth}