Java基础之JDBC之 DAO简单演示

本文介绍了Java中的DAO(Data Access Object)模式,用于封装数据操作,实现模块化,便于代码维护和升级。展示了典型的项目结构,包括bean、dao、util包的组织,并通过BaseDAO类和UserDAO接口及其实现展示了CRUD操作。此外,还利用泛型和反射优化了BaseDAO,简化了子类的实现。
摘要由CSDN通过智能技术生成

其实在操作数据的时候,会引入一个概念那就是DAO。

DAO(Data Access Object):访问数据信息的类和接口,包括了对数据的CRUD(Create ,Retrival, Update, Delete),而不包含任何业务相关的信息。又是也称作为BaseDAO.

其作用就是为了实现功能的模块化,更有利于代码的维护和升级。

其实这个会影响创建项目的时候结构。因为演示Java所以不在后面写更多的内容,简单的整理。

包的结构以及意义:

  • com.test : 这个是项目的定义的,具体如何看项目规范了。
  • com.test.beans: 这个是放对象类的,这个有的命名不是beans而是domain等,这个也是看如何规范了。
  • com.test.dao:定义一些父类以及操作不同对象的接口
  • com.test.dao.impl:实现接口的类。
  • com.test.util : 这个是放一些工具类,比如得到数据库连接等

所以一般结构如下:

在这里插入图片描述

演示

bean 类

package com.test.beans;

public class User {
    int id;
    String name;
    String addres;

    public User() {
    }
    public User(int id, String name, String addres) {
        this.id = id;
        this.name = name;
        this.addres = addres;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddres() {
        return addres;
    }

    public void setAddres(String addres) {
        this.addres = addres;
    }
}

工具类

package com.test.util;

import com.mysql.jdbc.Driver;

import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class MysqlJDBCUtils {
//     得到一个连接
     public static Connection getCon(){
     Connection con=null;
     Properties properties=new Properties();
         try {
             properties.load(MysqlJDBCUtils.class.getClassLoader().getResourceAsStream("mysql.properties"));
             String user=properties.getProperty("user");
             String password=properties.getProperty("password");
             String url=properties.getProperty("url");
             String drivername=properties.getProperty("driver");
             Class dirverClass=Class.forName(drivername);
             Driver dirver= (Driver) dirverClass.newInstance();
//             这一句可以省略
//             DriverManager.registerDriver(dirver);
             con=DriverManager.getConnection(url,user,password);


             return con;
         } catch (Exception e) {
             e.printStackTrace();
         }

         return null;
     }
// 关闭连接
    public static void closeCon(Statement sts, ResultSet rst,Connection con){
       if(rst!=null){
           try {
               rst.close();
           } catch (SQLException throwables) {
               throwables.printStackTrace();
           } finally {
               if(sts!=null){
                   try {
                       sts.close();
                   } catch (SQLException throwables) {
                       throwables.printStackTrace();
                   } finally {
                       if(con!=null){
                           try {
                               con.close();
                           } catch (SQLException throwables) {
                               throwables.printStackTrace();
                           }
                       }

                   }
               }


           }
       }


    }


}

BaseDAO类

因为这个有些方法通用,所以将其提出了单独一个类

package com.test.dao;
import com.test.util.MysqlJDBCUtils;
import java.lang.reflect.Field;
import java.sql.*;
import java.util.List;

//     无论操作什么数据库,其实有些方法可以提炼处理,然后通用的
// 所以写一个总父类
public class BaseDao {

    //    通用的增删改
//              为什么将连接作为一个参数而不是在方法种直接调用工具类得到连接,因为要考虑兼容是否需要使用事务
//    所以在子类种得到Connection
    public  int updata(Connection con,String sql,Object ... args) {
        PreparedStatement prst=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
//            executeUpdate 返回影响的行数,如果没有影响返回0
            returnint=prst.executeUpdate();
            return returnint;

        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, null,null);

        }

        return returnint;
    }
    //    返回一条数据
    public <T> T  getInstance(Connection con,String sql,Class<T> tClass ,Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            ResultSetMetaData rstme= rst.getMetaData();
            int columnCount=rstme.getColumnCount();
            if (rst.next()) {
                T t= tClass.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rstme.getColumnLabel(i + 1);
                    Field field = tClass.getField(columnName);
                    field.set(t,rst.getObject(i+1) );
                }
                return t;
            }
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return null;
    }
    //    返回一条数据
    public <T> List<T>  getAllInstance(Connection con, String sql, Class<T> tClass , Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        List<T> list=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            ResultSetMetaData rstme= rst.getMetaData();
            int columnCount=rstme.getColumnCount();
            while (rst.next()) {
                T t= tClass.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rstme.getColumnLabel(i + 1);
                    Field field = tClass.getField(columnName);
                    field.set(t,rst.getObject(i+1) );
                }
                list.add(t);
            }
            return list;
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return list;
    }
//     但是还是需要想到一个,那就是一些聚合函数,比如GROUP MAX 等 只返回一个特殊值

    public <T> T getValue(Connection con,String sql,Class<T> tClass ,Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        try {

            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            if (rst.next()) {
             return (T) rst.getObject(1);
            }
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return null;
    }


}

接口定义

package com.test.dao;

import com.test.beans.User;

import java.sql.Connection;

//定义操作用户的接口
public interface UserDAO {
//    插入数据据
    void  inserData(Connection con, User user);
//    一般创建表的时候,创建一个唯一标识符的值
    User  getDataByid(Connection con, int id);

//    当然后面还可以有得到全部数据,以及特殊数据等 只为了展现如何使用和概念,不在作其它操作
}

实现某个具体对象操作

package com.test.dao.impl;

import com.test.beans.User;
import com.test.dao.BaseDao;
import com.test.dao.UserDAO;
import java.sql.Connection;

public class UserDAOimpl extends BaseDao implements UserDAO {


    @Override
    public void inserData(Connection con, User user) {
       String sql="INSERT INTO test.user  VALUES (?,?, ?)";
//       直接调用父类的方法
       updata(con,sql,user.getId(),user.getName(),user.getAddres());
    }

    @Override
    public User getDataByid(Connection con, int id) {
        String sql="select id,name,addres from  test.user  where  `id` =  ?";
        //       直接调用父类的方法

        User user= (User) getAllInstance(con,sql,User.class,id);

    return user;
    }


}

升级

上面虽然可以满足了很多需求,但是为了在UserDAOimpl类种调用的时候传递了要操作对象的Class,有点琐碎,可以BaseDaoUserDAOimpl可以再升级一下:

也就是使用泛型和泛型的反射进行修改

升级后的baseDAO 类

package com.test.dao;
import com.test.util.MysqlJDBCUtils;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.*;
import java.util.List;

//     无论操作什么数据库,其实有些方法可以提炼处理,然后通用的
// 所以写一个总父类
public class BaseDao<T> {

    private Class<T> clazz=null;
//    通过反射得到这个类的Class 这个虽然放在父类中,但是是通过自己调用的所以this值 就是子类本身了
    {
        Type genericSuperclass  = this.getClass().getGenericSuperclass();
        ParameterizedType   parameterizedType= (ParameterizedType) genericSuperclass;
        Type[] types= parameterizedType.getActualTypeArguments();
        clazz= (Class<T>) types[0];
    }


    //    通用的增删改
//              为什么将连接作为一个参数而不是在方法种直接调用工具类得到连接,因为要考虑兼容是否需要使用事务
//    所以在子类种得到Connection
    public  int updata(Connection con,String sql,Object ... args) {
        PreparedStatement prst=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
//            executeUpdate 返回影响的行数,如果没有影响返回0
            returnint=prst.executeUpdate();
            return returnint;

        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, null,null);

        }

        return returnint;
    }
    //    返回一条数据
    public T  getInstance(Connection con,String sql ,Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            ResultSetMetaData rstme= rst.getMetaData();
            int columnCount=rstme.getColumnCount();
            if (rst.next()) {
                T t= clazz.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rstme.getColumnLabel(i + 1);
                    Field field = clazz.getField(columnName);
                    field.set(t,rst.getObject(i+1) );
                }
                return t;
            }
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return null;
    }
    //    返回一条数据
    public List<T>  getAllInstance(Connection con, String sql,  Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        List<T> list=null;
        int returnint=0;
        try {
            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            ResultSetMetaData rstme= rst.getMetaData();
            int columnCount=rstme.getColumnCount();
            while (rst.next()) {
                T t= clazz.newInstance();
                for (int i = 0; i < columnCount; i++) {
                    String columnName = rstme.getColumnLabel(i + 1);
                    Field field = clazz.getField(columnName);
                    field.set(t,rst.getObject(i+1) );
                }
                list.add(t);
            }
            return list;
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return list;
    }
//     但是还是需要想到一个,那就是一些聚合函数,比如GROUP MAX 等 只返回一个特殊值

    public   T getValue(Connection con,String sql ,Object ... args) {
        PreparedStatement prst=null;
        ResultSet rst=null;
        try {

            prst=con.prepareStatement(sql);
            int len=args.length;
            for (int i = 0; i < len; i++) {
                prst.setObject(i+1,args[i]);
            }
            rst=prst.executeQuery();
            if (rst.next()) {
             return (T) rst.getObject(1);
            }
        } catch ( Exception throwables) {
            throwables.printStackTrace();
        }finally {
//             因为连接是传递过来的,所以不在这里关闭连接
            MysqlJDBCUtils.closeCon(prst, rst,null);

        }
        return null;
    }


}

升级后的UserDAOimpl

package com.test.dao.impl;

import com.test.beans.User;
import com.test.dao.BaseDao;
import com.test.dao.UserDAO;
import java.sql.Connection;

public class UserDAOimpl extends BaseDao<User> implements UserDAO {


    @Override
    public void inserData(Connection con, User user) {
       String sql="INSERT INTO test.user  VALUES (?,?, ?)";
//       直接调用父类的方法
       updata(con,sql,user.getId(),user.getName(),user.getAddres());
    }

    @Override
    public User getDataByid(Connection con, int id) {
        String sql="select id,name,addres from  test.user  where  `id` =  ?";
        //       直接调用父类的方法

        User user= (User) getAllInstance(con,sql,id);

    return user;
    }


}

这个地方也看出了反射在框架中的作用了,本篇就是简单走Dao而已,大家理解一下。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值