三天学会JDBC(五)DAO模式

三天学会JDBC(五)DAO模式,第1张

三天学会JDBC(五)DAO模式

目录

一.应用程序分层

二.通用baseDao

三.UserDAO

四.测试UserDAO


一.应用程序分层

应用程序通过创建不同的包来实现项目的分层,将项目中的代码根据功能做具体划分,并存放在不同的包下。

com.bzcxy.controller//控制层com.bzcxy.service//业务逻辑层com.bzcxy.dao//数据库 *** 作com.bzcxy.pojo//数据库实体类

控制层主要连接前端,UI和后端中间层

业务逻辑层做具体的业务逻辑

dao层就是做数据库 *** 作

pojo就是数据库的实体类

1.1 分层优点 1. 分层结构将应用系统划分为若干层,每一层只解决问题的一部分,通过各层的协作提供整体解决方案。大的问题被分解为一系列相对独立的子问题,局部化在每一层中,这样就有效的降低了单个问 题的规模和复杂度,实现了复杂系统的第一步也是最为关键的一步分解。 2. 分层结构具有良好的可扩展性,为应用系统的演化增长提供了一个灵活的支持,具有良好的可扩展性。增加新的功能时,无须对现有的代码做修改,业务逻辑可以得到最大限度的重用。 3. 分层架构易于维护。在对系统进行分解后,不同的功能被封装在不同的层中,层与层之间的耦合显著降低。因此在修改某个层的代码时,只要不涉及层与层之间的接口,就不会对其他层造成严重影 响。

1.2 三层结构 三层结构就是将整个业务应用划分为: 界面层( User Interface layer ) :提供与用户交互的界面,如 GUI (图形用户界面), web 页面等; 业务逻辑层( Business Logic Layer ) :负责各种业务逻辑,直接访问数据库,提供对业务数据的保 存、更新、删除和查询 *** 作; 数据访问层( Data access layer ) :负责存放管理应用的持久性业务数据 三层结构的特点是: 所有下层向上层提供调用的接口,具体实现细节对上层透明。层与层之间存在自上而下的依赖关系,即 上层会访问下层的API,但下层不依赖于上层 。

二.通用baseDao DAO 一般是提供从数据库 增加、删除、修改记录、查询所有记录、查询符合某个条件记录、取得某条记录等方法的底层数据 *** 作自定义类。 由于可能 *** 作多个数据库表,这样就需要为每个表提供一个 *** 作他的类 xxDAO , 这些DAO继承 baseDAO 就可以省略很多重复代码 (从数据库 增加、删除、修改记录、查询所有记录、查询符合某个 条件记录、取得某条记录等方法的代码)。 1. 实现一个通用的 baseDao 抽象类 2. 通用的增删改 *** 作 3. 通用的查询 *** 作,需要用到 commons-beanutils-1.9.3.jar 包及其依赖包 commons-logging- 1.2.jar ,将它们导入并引入工程 4. 获取单一值,如 select(*)

即baseDao就是提取一些公共 *** 作封装起来,避免代码的重复写,减小代码量。

import org.apache.commons.beanutils.BeanUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetmetaData;
import java.util.ArrayList;
import java.util.List;

//抽象函数
public abstract class baseDao {
    //定义一个变量来接受泛型的类型
    private Class type;

    //获取T的Class对象,获取泛型类型,泛型是在被子类继承时才确定
    public baseDao(){
        //获取子类类型
        Class clazz=this.getClass();
        //获取父类类型
        ParameterizedType parameterizedType=(ParameterizedType)clazz.getGenericSuperclass();
        //getActualTypeArguments获取具体的泛型类型
        //这个方法返回一个Type类型数组
        Type[] types=parameterizedType.getActualTypeArguments();
        //获取具体的泛型类型,强制类型转换一下
        this.type= (Class) types[0];
    }

    //通用增删改 *** 作
    public int excuteQuery(String sql,Object ...args)throws Exception{
        //从数据池里获取链接
        Connection conn=JDBCUtilsDruid.getConnection();
        //预编译sql语句
        PreparedStatement psmt=conn.prepareStatement(sql);
        //绑定参数
        for (int i=0;i getBean(String sql,Object ...args)throws Exception{
        List list=new ArrayList<>();
        //获取连接
        Connection conn=JDBCUtilsDruid.getConnection();
        PreparedStatement psmt=conn.prepareStatement(sql);
        //绑定参数
        for (int i=0;i
三.UserDAO

针对User表的UserDAO

之前也写过User.java,如下:

public class User {
    private Integer id;
    private String username;
    private String userpassword;

    public Integer getId() {
        return id;
    }

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

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getUserpassword() {
        return userpassword;
    }

    public void setUserpassword(String userpassword) {
        this.userpassword = userpassword;
    }
}

接口UserDAO.java:

import com.hbb.jdbc.User;

public interface UserDAO {
    //根据username获取一条记录
    User getUser(String username) throws Exception;
    //插入一条user
    void insertUser(User user) throws Exception;
    //根据id删除一条数据
    void deleteUserById(Integer id) throws Exception;
    //获取一共有多少用户
    Integer getUserCount() throws Exception;
}

最终对应的数据库User表的一个实现类是UserDAOImple.java

import com.hbb.jdbc.User;

import java.util.List;

public class UserDAOImple extends baseDao implements UserDAO {

    @Override
    //这里抛出异常后接口UserDAO也需要抛出异常
    public User getUser(String username) throws Exception{
        User u=null;
        String sql="select * from user where username = ?";
        //使用baseDao中的通用查询方法getBean
        List list=this.getBean(sql,username);
        //判断是否有值
        if(list.size()!=0){
            //只获取列表的第一个对象
            u=list.get(0);
        }
        return u;
    }

    @Override
    //插入一个用户
    public void insertUser(User user)throws Exception {
        String sql="insert into user(username,userpassword)values(?,?)";
        //使用baseDAO中的通用增删改方法
        this.executeUpdate(sql,user.getUsername(),user.getUserpassword());
    }

    @Override
    //通过id删除用户
    public void deleteUserById(Integer id)throws Exception {
        String sql="delete from user where id = ?";
        //使用baseDAO中的通用增删改方法
        this.executeUpdate(sql,id);
    }

    @Override
    //统计用户个数
    public Integer getUserCount() throws Exception{
        String sql="select count(*) from user";
        //使用baseDAO中获取单一值的方法
        Integer count=Integer.valueOf(this.getValue(sql).toString());
        return null;
    }
}

感悟:

二.和三.的关系大致是:抽象函数baseDAO实现了一些对于泛型的使用频率较高的公共功能函数,然后用接口声明一下需要实现的功能函数 (我感觉是为了规范),最后对于数据库的某一个表,创建一个是具体的实现类,此类继承抽象函数,结合抽象函数的已实现的泛型函数的功能(减少代码量),来实现具体类的具体功能!

四.测试UserDAO

bug1:数据库无法连接

解决:在电脑左下角的搜索栏里输入“服务”,找到MySQL重启!

bug2:

Exception in thread "main" java.sql.SQLException: 
Parameter index out of range (1 > number of parameters, which is 0).

 参考这篇文章,是SQL语句中问号和赋值时的参数个数不匹配导致的,我检查了一下,我的某个SQL语句中的问号用了中文形式的问号,改成英文的就解决了。

import com.hbb.jdbc.User;

public class TestUserDAOImple {
    public static void main(String[] args) throws Exception {
        UserDAO userDAO=new UserDAOImple();
        //测试insertUser
//        User u=new User();
//        u.setUsername("test");
//        u.setUserpassword("password");
//        userDAO.insertUser(u);

        //测试getUser
        User u=userDAO.getUser("test");
        System.out.println(u.getUsername()+":"+u.getUserpassword());

        //测试delete
//        userDAO.deleteUserById(7);

        //获得用户总数
        //可顺序执行,比如上面删除语句没注释掉和这句一块执行,会先删除id=7的用户
        //然后再统计剩下的用户总数
//        System.out.println(userDAO.getUserCount());
    }
}

 感悟:

等实际使用时,直接调用接口的各种已经实现的功能即可了,这样写代码确实规范,具体的功能实现就不用管了!!!

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5716299.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存