数据库Dao和视图Entity---层次化开发

本文介绍了JavaWeb开发中DAO层的作用和规则,强调了DAO类封装数据库操作以简化代码的重要性和实现方式。同时,讲解了实体类(Entity)的创建,用于承载数据库查询结果,通过StudentDao实例展示了增删改查操作。最后,讨论了查询操作中如何返回查询结果集并转化为实体对象。通过DAO和实体类的使用,可以提高代码的可读性和复用性。
摘要由CSDN通过智能技术生成

DAO层 ---- 数据库

Javaweb — DAO 116天


DAO层和module层


或许感觉有点杂乱,但是也不杂乱,因为昨天分享了一下应用的分层,底层是DAO层调用的数据库;而不是直接用Action或者Service来操作数据库;昨天的单表操作是因为这个程序过于简单,所以就没有分层

数据库中每一张表都关联一个实体类接口和实现类,一个Dao接口和Dao实现类

DAO【mapper】

DAO database access object 数据库访问对象

作用就是 数据库访问对象在开发时提供针对某张表的操作细节【一张表就对应一个DAO】CRUD

优点就是: 在管理系统开发时,通过数据访问对象可以避免反复的SQL命令书写;

在管理系统开发时,通过数据库访问对象可以避免反复的JDBC开发步骤书写----昨天的程序中虽然有了DBUtil,但是还是出现了大量的重复的JDBC编程六步

DAO类就是提供数据库访问对象的类

DAO类开发规则

  1. 一个DAO类封装的时一张表的操作细节【每一张表对应一个DAO类】
  2. DAO类命名的规则是:表名 + DAO 比如封装student表-----》StudentDao
  3. DAO类所在包的命名规则:com.cfeng.DAO 所有的DAO类都在这个包中

DAO类实例:StudentDao

这里就知道为什么是一张表对应一个Dao了,因为每一张表的结构不同,参数不同;传入的参数和可能修改的位置都不同,而对于某一张表,其传入的参数的个数都是固定的;比如昨天的学生表,就三个参数;所以将这三个参数直接封装成为一个增的方法;然后删除和修改都是按照主键进行的操作,所以参数就是主键stuno

package cfeng.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import cfeng.utils.DBUtil;


public class StudentDao {
	//增加数据行;返回的是插入数据的行数
	public int addStudent(String stuno,String stuname,String stuclass) {
		Connection conn = null;
		PreparedStatement state = null;
		int count = 0;
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "INSERT INTO student (stuno,stuname,stuclass) VALUES (?,?,?)";
			state = conn.prepareStatement(sql);
			state.setString(1, stuno);
			state.setString(2, stuname);
			state.setString(3, stuclass);
			count = state.executeUpdate();
			conn.commit();
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, null);
		}
		return count;
	}
	//修改数据行
	public int  editModifyStudent(String stuno,String stuname,String stuclass) {
		Connection conn = null;
		PreparedStatement state = null;
		int count = 0;
		try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "UPDATE student SET stuname = ?,stuclass=? WHRER stuno =" + stuno;
			state = conn.prepareStatement(sql);
			state.setString(1, stuname);
			state.setString(2, stuclass);
			count = state.executeUpdate();
            //提交事务
		} catch (SQLException e) {
			if(conn != null) {
				try {
					conn.rollback();
				} catch (SQLException e1) {
					e1.printStackTrace();
				}
			}
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, null);
		}
		return count;
	}
	//还有查找,删除就类似写完就可
}

那么我们之前在写AddAction的时候就可以调用DAO层的操作完成简单的书写即可

package cfeng.oa.actions;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class StudentAddAction extends HttpServlet {
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		//获取数据,解决中文乱码
		req.setCharacterEncoding("UTF-8");
		String stuno = req.getParameter("stuno");
		String stuname = req.getParameter("stuname");
		String stuclass = req.getParameter("stuclass");
//		System.out.println(stuno + stuname + stuclass); 测试是否传入成功
		//连接数据库,操作数据库
		Dao studentDao = new StudentDao(); //这里要使用单例模式,并且严格分层还不能new对象
        int count = studentDao.addStudent(stuno,stuname,stuclass);
        //根据方法返回值来判断
		if(count == 1) {
			//success
			resp.sendRedirect(req.getContextPath() + "/student/list");
		}else {
			//添加失败
		}
	}
}

这样就可以简化代码,因为大量重复的代码,可能会影响后期的调试的效率;原本几十行的代码被封装到DAO数据库访问对象;这样就简单两行代码就取代了之前的很多的代码

查询操作的问题?

上面的是增删改,都很简单,就操作即可;那么对于查询怎么操作呢,查询需要返回一个查询结果集,比如最开始的index.html点击就是查询的数据库,将结果集返回插入表中

//查询,按照学号查询;不用事务,不会修改表
	public ResultSet GetStudent(String stuno) {
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		try {
			conn = DBUtil.getConnection();
			String sql = "SELECT stuno,stuname,stuclass FROM student WHERE stuno= ?";
			state = conn.prepareStatement(sql);
			state.setString(1, stuno); //注意State才是拼接sql,而PreparedState是预编译,都是?通配
			result = state.executeQuery();
			//处理查询结果集
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
		return result;  //这里上面的finally已经将result给关闭了,返回的是null
	}

查询的过程中就有了问题,上面的处理查询结果集,就是想将查询结果集给返回,但是上面关闭了,怎么办?难道不关闭,不可以,因为这是规范,必须要释放资源

那就必须有一个变量来接收这个结果集,什么变量呢? 首先结果集里面是什么?是表中的字段,这些字段就是对应的一个类的属性,比如一个student类,它的属性有stuno,stuname,stuclass;这就是成员变量,定义为私有即可

实体类model层 【Entity,domain】

  1. 实体类就是实体的软件建模,一个实体类描述一张表结构【这是学习数据库之后的思维转换】,实体类的创建也应该有接口和实现类;面向接口编程
  2. 实体类的类名应该和关联的表名保持一致,可以忽略大小写 比如student表对应的实体的实现类就是Student
Student.frm     ---------------->   public class Student(){
stuno  INT							private int stuno;
stuname VARCHAR(255)				private String stuname;
stuclass VARCHAR(255)              	private String stuclass;
                                     }
  1. 实体类中的一个实例对象用于在内存中存储对应的表文件中一个数据行
比如 表中的数据 1 张三 HC2001    ----->    Student student = new Student(1,"张三","HC2001");

那么现在就建立一个实体类Student类接收这个表中的数据【其实实际的过程就是产生了实体,同时分析和建立数据库表】

//直接使用快捷键创建构造器和set和get方法
package cfeng.entity;

/**
 * @author OMEY-PC student表的实体,可以承载表的查询结果集
 */
public class Student {
	private int stuno;
	private String stuname;
	private String stuclass;

	public Student() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Student(int stuno, String stuname, String stuclass) {
		super();
		this.stuno = stuno;
		this.stuname = stuname;
		this.stuclass = stuclass;
	}

	public int getStuno() {
		return stuno;
	}

	public void setStuno(int stuno) {
		this.stuno = stuno;
	}

	public String getStuname() {
		return stuname;
	}

	public void setStuname(String stuname) {
		this.stuname = stuname;
	}

	public String getStuclass() {
		return stuclass;
	}

	public void setStuclass(String stuclass) {
		this.stuclass = stuclass;
	}

}

那么查询出来的一行结果就是一个实例对象

//查询,按照学号查询;不用事务,不会修改表 -- 查询所有
	public List GetStudent() {
		Connection conn = null;
		PreparedStatement state = null;
		ResultSet result = null;
		List list = new ArrayList<Student>();
		try {
			conn = DBUtil.getConnection();
			String sql = "SELECT stuno,stuname,stuclass FROM student";// WHERE stuno= ?
			state = conn.prepareStatement(sql);
//			state.setString(1, stuno); //注意State才是拼接sql,而PreparedState是预编译,都是?通配
			result = state.executeQuery();
			//处理查询结果集
			//将查询结果创建为实体对象返回,但是这里是结果集,所以使用容器接收
			while(result.next()) {
				int no = Integer.valueOf(result.getString("stuno"));
				String name = result.getString("stuname");
				String stuclass = result.getString("stuclass");
				Student student = new Student(no,name,stuclass);
				//将对象给放进去
				list.add(student);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			DBUtil.close(conn, state, result);
		}
		return list;  //这里上面的finally已经将result给关闭了,返回的是null
	}

将对象放到集合中返回就可以了,这样查询操作就完成

现在可以测试一下查询的效果

package cfeng.oa.actions;

import java.util.List;

import cfeng.oa.dao.StudentDao;
import cfeng.oa.entity.Student;

public class Test {
	public static void main(String[] args) {
		//测试DAO的查询功能
		StudentDao stuDao =  new StudentDao();
		List<Student> list = stuDao.GetStudent();
		for(Student s:list) {
			System.out.println(s.getStuno() + " : " + s.getStuname() + " : " + s.getStuclass());
		}
	}
}

1 : 张三 : HC2001
2 : 李四 : HC2002
3 : Cfeng : HC2002
4 : 王五 : HC2001
6 : Jning : HC2001
7 : 里斯 : HC2003
8 : 卡夫卡 : HC2004
9 : 里仁 : HC2003

所以开发主要是要层次化开发,这个小小的编程实例,其实也可以分成多层来进行开发,这里可以分为entity实体层【model】;数据库访问层Dao,这两层就是项目初期分析的时候设计数据库表,分析实体;之后还应该有service层和view层的;但是这里就简单使用了action层,收转功能;控制层的,直接和页面进行交互

在这里插入图片描述

之前写程序的时候,没有使用Dao,导致action的开发异常繁杂,主要就是JDBC的编程规范,将JDBC操作封装到Dao中之后业务开发就简化了许多。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值