JDBC-day05(DAO及相关实现类)

news2024/11/23 12:25:15

七:DAO及相关实现类

1. DAO介绍

  • DAOData Access Object访问数据信息的类和接口,包括了对数据的CRUDCreate、Retrival、Update、Delete),而不包含任何业务相关的信息。有时也称作:BaseDAO
  • 作用:为了实现功能的模块化,更有利于代码的维护和升级。在实际生产中,也是使用DAO的样式进行编写。

2. BaseDAO

  • 把用到的通用操作写在此类中,用作父类供子类调用

例:把之前编写的增删查改的具体方法代码放入其中,还可以添加一些其他方法

import java.lang.reflect.Field;
import java.sql.Connection;    
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.jdbc1.util.JDBC_Utils;

/***
 * 
 * @author Cat God 007 封装了数据表的基本通用操作
 *
 */
public abstract class BaseDAO {
	// 通用的增删改操作---version2.0
	public int update(Connection conn, String sql, Object... args) {
		PreparedStatement ps = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);// 小心参数声明错误(从1开始)
			}
			return ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBC_Utils.closeResource(null, ps);
		}
		return 0;
	}

	// 通用的查询操作,返回一条数据----version2.0(考虑上数据库事务)
	public <T> T getInstance(Connection conn, Class<T> clazz, String sql, Object... args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}
			rs = ps.executeQuery();
			// 获取结果集的元数据
			ResultSetMetaData rsmd = rs.getMetaData();
			// 通过ResultSetMetaData获取结果集中的列数
			int columnCount = rsmd.getColumnCount();
			if (rs.next()) {
				T t = clazz.newInstance();
				for (int i = 0; i < columnCount; i++) {
					// 获取列值:结果集
					Object columnvalue = rs.getObject(i + 1);
					// 获取每个列的列名:结果集元数据
//							String columnName = rsmd.getColumnName(i + 1);
					// 获取每个列的别名(无别名就获取表的列名):结果集元数据
					String columnLabel = rsmd.getColumnLabel(i + 1);

					// 给cust指定columnName属性赋值为columnvalue,通过反射
					Field field = clazz.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(t, columnvalue);
				}
				return t;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBC_Utils.closeResource(null, ps, rs);
		}
		return null;
	}

	// 通用的查询操作,返回多条数据----version2.0(考虑上数据库事务)
	public <T> List<T> getForList(Connection conn, Class<T> clazz, String sql, Object... args) {
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for (int i = 0; i < args.length; i++) {
				ps.setObject(i + 1, args[i]);
			}
			rs = ps.executeQuery();
			// 获取结果集的元数据
			ResultSetMetaData rsmd = rs.getMetaData();
			// 通过ResultSetMetaData获取结果集中的列数
			int columnCount = rsmd.getColumnCount();
			// 创建集合对象
			ArrayList<T> list = new ArrayList<T>();
			while (rs.next()) {
				T t = clazz.newInstance();
				// 给t对象指定的属性赋值
				for (int i = 0; i < columnCount; i++) {
					// 获取列值:结果集
					Object columnvalue = rs.getObject(i + 1);
					// 获取每个列的列名:结果集元数据
//							String columnName = rsmd.getColumnName(i + 1);
					// 获取每个列的别名(无别名就获取表的列名):结果集元数据
					String columnLabel = rsmd.getColumnLabel(i + 1);

					// 给cust指定columnName属性赋值为columnvalue,通过反射
					Field field = clazz.getDeclaredField(columnLabel);
					field.setAccessible(true);
					field.set(t, columnvalue);
				}
				list.add(t);
			}
			return list;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JDBC_Utils.closeResource(null, ps, rs);
		}
		return null;
	}
	//新增:用于查询特殊值的通用方法,如:查询表中的总人数等
	public <E> E getValue(Connection conn,String sql,Object ...args){
		PreparedStatement ps = null;
		ResultSet rs = null;
		try {
			ps = conn.prepareStatement(sql);
			for(int i = 0;i < args.length;i++) {
				ps.setObject(i + 1, args[i]);
			}
			rs = ps.executeQuery();
			if(rs.next()) {
				return (E) rs.getObject(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(null, ps, rs);
		}		
		return null;
	}
	
}

3.XxxDAO

  • 定义针对某一表或数据库的功能接口

例:
在此之前需要创建Customer类,有的话就直接调用就行,不需要再创建

package com.jdbc2.bean;

import java.sql.Date;

/**
 * 
 * @author Cat God 007
 * ORM编程思想(object relational mapping)对象关系映射
 * 一个数据表对应一个Java类
 * 表中的一条记录对应Java类的一个对象
 * 表中的一个字段对应Java类的一个属性
 */
public class Customer {
	private int id;       
	private String name;
	private String email;
	private Date birth;
	public Customer() {
		super();
	}
	public Customer(int id, String name, String email, Date birth) {
		super();
		this.id = id;
		this.name = name;
		this.email = email;
		this.birth = birth;
	}
	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 getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
	}
	

}

定义针对Customer表的功能接口

import java.sql.Connection;        
import java.sql.Date;
import java.util.List;

import com.jdbc2.bean.Customer;

//此接口用于规范针对customers表的常用操作
public interface CustomerDAO {
	/**
	 * 将cust对象添加到数据库中
	 */
	void insert(Connection conn,Customer cust);
	/**
	 *针对指定的id,删除表中的一条记录
	 */
	void deleteById(Connection conn,int id);
	/*
	 * 针对内存中的cust对象,去修改数据表中指定的记录
	 */
	void update(Connection conn,Customer cust);
	
	/*
	 * 针对指定的id查询对应的Customer对象(一条记录)
	 */
	Customer getCustomerById(Connection conn,int id);
	
	/*
	 * 查询表中的所有记录构成的集合
	 */
	List<Customer> getAll(Connection conn);
	
	/*
	 * 返回数据表中的数据条目数
	 */
	Long getCount(Connection conn);
	
	/*
	 * 返回数据表中最大的生日(即最小的人的生日)
	 */
	Date getMaxBirth(Connection conn);
	
	

}

4.XxxDAOImpl

  • 继承BaseDAO,实现XxxDAO接口

例:

CustomerDAOImpl继承BaseDAO,实现CustomerDAO接口

import java.sql.Connection;        
import java.sql.Date;
import java.util.List;

import com.jdbc2.bean.Customer;

public class CustomerDAOImpl extends BaseDAO implements CustomerDAO{

	@Override
	public void insert(Connection conn, Customer cust) {
		String sql = "insert into customers(name,email,birth)values(?,?,?)";
		update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth());
		
	}

	@Override
	public void deleteById(Connection conn, int id) {
		String sql = "delete from customers where id = ?";
		update(conn,sql,id);
		
	}

	@Override
	public void update(Connection conn, Customer cust) {
		String sql = "update customers set name = ?,email = ?,birth = ? where id = ?";
		update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth(),cust.getId());
		
	}

	@Override
	public Customer getCustomerById(Connection conn, int id) {
		String sql = "select id ,name,email,birth from customers where id = ?";
		Customer customer = getInstance(conn,Customer.class,sql,id);
		return customer;
	}

	@Override
	public List<Customer> getAll(Connection conn) {
		String sql = "select id,name,email,birth from customers";
		List<Customer> list = getForList(conn,Customer.class,sql);
		return list;
	}

	@Override
	public Long getCount(Connection conn) {
		String sql = "select count(*) from customers";
		return getValue(conn,sql);
	}

	@Override
	public Date getMaxBirth(Connection conn) {
		String sql = "select max(birth) from customers";
		return getValue(conn,sql);
	}

}

5. XxxDAOImplTest测试

  • 对具体的XxxDAOImpl实现类i,进行测试

例:


import static org.junit.Assert.*;

import java.sql.Connection;        
import java.sql.Date;
import java.util.List;

import org.junit.Test;

import com.jdbc1.util.JDBC_Utils;
import com.jdbc2.bean.Customer;
import com.jdbc4.dao.CustomerDAOImpl;

public class CustomerDAOImplTest {
	private CustomerDAOImpl dao = new CustomerDAOImpl();

	@Test
	public void testInsert() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			Customer cust = new Customer(1,"猫神","catgod007@186.com",new Date(6323453234L));
			dao.insert(conn, cust);
			System.out.println("插入成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testDeleteById() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			dao.deleteById(conn, 16);
			System.out.println("删除成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testUpdateConnectionCustomer() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			Customer cust = new Customer(18,"马云","mayun@123.com",new Date(567865437L));
			dao.update(conn, cust);			
			System.out.println("修改成功");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testGetCustomerById() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection(); 
			Customer customer = dao.getCustomerById(conn,10);
			System.out.println(customer);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testGetAll() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			List<Customer> list = dao.getAll(conn);
			list.forEach(System.out::println);//注意遍历对象的方法
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testGetCount() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			Long count = dao.getCount(conn);
			System.out.println("表中的数据共有:" + count + "条");
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}

	@Test
	public void testGetMaxBirth() {
		Connection conn = null;
		try {
			conn = JDBC_Utils.getConnection();
			Date maxBirth = dao.getMaxBirth(conn);
			System.out.println("数据表中最年轻的人的生日是: " + maxBirth);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBC_Utils.closeResource(conn, null);
		}
	}
}

6. 创建测试文件测试多个方法(可略过)

  • 在要创建的包下,右键点击想要测试的java类,点击new------->Other
  • 搜索 Junit test case,如果不行就需要导入Junit 包
  • 在这里插入图片描述
  • 在这里插入图片描述
  • 在这里插入图片描述

到处DAO就结束了,如果需要编写针对Order表的DAO层,就需要编写OrderDAO,OrderDAOImpl即可

其中可能会出现不少的小问题,请多多包含
感谢大家的支持,关注,评论,点赞!
参考资料:尚硅谷_宋红康_JDBC核心技术

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1100898.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Java实战】Mysql读写分离主从复制搭建保姆级教程

MySQL 的数据同步通常采用主从复制&#xff08;Master-Slave&#xff09;的方式。 主从复制基于二进制日志&#xff08;binlog&#xff09;。主服务器&#xff08;Master&#xff09;在 binlog 中记录数据更改&#xff0c;从服务器&#xff08;Slave&#xff09;将这些日志读取…

坚持每日分享5款好用的小软件

今天推荐5款十分小众的软件&#xff0c;知道的人不多&#xff0c;但是每个都是非常非常好用的&#xff0c;有兴趣的小伙伴可以自行搜索下载。 1.素材管理——Billfish ​ Billfish是一款免费的素材管理软件&#xff0c;可以帮助设计师、摄影师、视频制作人等管理本地的图片、…

CSS3 就可以写出一个苹果官方渐变颜色文字效果,真的太逼真了!

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;web开发者、设计师、技术分享博主 &#x1f40b; 希望大家多多支持一下, 我们一起进步&#xff01;&#x1f604; &#x1f3c5; 如果文章对你有帮助的话&#xff0c;欢迎评论 &#x1f4ac;点赞&#x1…

使用Cpolar和Tipas在Ubuntu上搭建私人问答网站,构建专业问答系统

文章目录 前言2.Tipask网站搭建2.1 Tipask网站下载和安装2.2 Tipask网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 4. 公网访问测试5. 结语 前…

01、RocketMQ--安装windows版本

目录 安装windows版本&#xff1a;启动&#xff1a;启动mq&#xff1a;启动broker&#xff1a;启动管控台&#xff1a; 启动jar包启动linux的RocketMQ服务 安装windows版本&#xff1a; 1、使用rocketmq解压到指定的目录 2、需要配置环境变量 ROCKETMQ_HOME 3、修改broker的…

用户行为数据案例

一、环境要求 HadoopHiveSparkHBase 开发环境。 二、数据描述 本数据集包含了2017-09-11至2017-12-03之间有行为的约5458位随机用户的所有行为&#xff08;行为包括点击、购买、加购、喜欢&#xff09;。数据集的每一行表示一条用户行为&#xff0c;由用户ID、商品ID、商品类…

[MQ]Win平台RocketMQ安装启动

1、下载 官网下载地址&#xff1a;https://rocketmq.apache.org/zh/download 2、解压ZIP包 解压rocketmq-all-x.x.x-bin-release.zip到目录。 比如我解压到了E:\Env\MQ_rocket\rocketmq-all-5.1.4-bin-release 3、配置环境变量 ROCKETMQ_HOME 4、RocketMQ JVM内存配置 这个需要…

k8s 暴露pod

kubenretes中暴露Pod及Service的6种方式 &#xff0c;分别为port_forward、hostNetwork、hostPort、nodePort、loadBalancer、Ingress。 下面讲下nodeport nodePort Kubernetes中的service默认情况下都是使用的ClusterIP这种类型&#xff0c;这样的service会产生一个Cluster…

2023年全球及中国小分子化药CDMO市场发展概况分析:CDMO市场有望进一步扩大[图]

小分子药物指具有单一明确有效成分、分子量在1000道尔顿以下的有机化合物分子。广义上来说&#xff0c;小分子化药通常是化学合成的。小分子成分可制成易于被机体吸收的片剂或胶囊&#xff0c;活性物质相对较易溶解&#xff0c;被机体吸收经肠壁进入血液。此外&#xff0c;与生…

用对配音软件,轻松制作专业配音~

听说很多做短视频的小伙伴都在找简单好用的配音软件&#xff01;摆在应用商店里的配音软件成百上千&#xff0c;但却屡试不爽&#xff0c;有的配音员选择少&#xff0c;有的配音效果不自然&#xff0c;不知道大家是否也会有这样的烦恼&#xff1f;今天在这里为大家推荐一个简单…

使用Pytorch实现频谱归一化生成对抗网络(SN-GAN)

自从扩散模型发布以来&#xff0c;GAN的关注度和论文是越来越少了&#xff0c;但是它们里面的一些思路还是值得我们了解和学习。所以本文我们来使用Pytorch 来实现SN-GAN 谱归一化生成对抗网络是一种生成对抗网络&#xff0c;它使用谱归一化技术来稳定鉴别器的训练。谱归一化是…

2023年中国少儿在线英语教育分类、市场规模及发展趋势分析[图]

中国的少儿在线英语教育行业&#xff0c;主要是指面向3-16岁的学前阶段、幼儿园阶段、小学阶段、初中阶段的学生群体&#xff0c;由私立教育培训机构推出英语培训课程产品的一个英语教育培训市场的细分行业。 少儿在线英语教育分类 资料来源&#xff1a;共研产业咨询&#xff…

TDengine 资深研发整理:基于 SpringBoot 多语言实现 API 返回消息国际化

作为一款在 Java 开发社区中广受欢迎的技术框架&#xff0c;SpringBoot 在开发者和企业的具体实践中应用广泛。具体来说&#xff0c;它是一个用于构建基于 Java 的 Web 应用程序和微服务的框架&#xff0c;通过简化开发流程、提供约定大于配置的原则以及集成大量常用库和组件&a…

5.自定义地形及影像

愿你出走半生,归来仍是少年&#xff01; 通过Cesium For Unity的引导案例我们在前面几张搭建尝试了通过其自带的资源搭建三维场景。这篇文章&#xff0c;讲述如何通过我们自己的底图(Dom)和地形&#xff08;Terrain&#xff09;进行场景构建。 若是无高程和影像数据&#xff0c…

2023年全球及中国抗体/蛋白/非核酸疫苗CDMO市场分析:生物药CDMO规模同步增长[图]

对于生物大分子药物研发生产一体化的CDMO服务包括&#xff1a;临床前阶段&#xff0c;对备选药物进行体外研究&#xff0c;评估安全性和目标疾病的生物活性&#xff0c;提供细胞系工程及开发、检测配方及工艺开发、产品分析表达、cGMP 细胞库及细胞系表达等服务&#xff1b;临床…

Elasticsearch:什么是余弦相似度?

余弦相似度是数据科学、文本分析和机器学习领域的基本概念。 如果你想知道什么是余弦相似度或者它如何在现实世界的应用程序中使用&#xff0c;那么你来对地方了。 本指南旨在让你深入了解相似性是什么、其数学基础、优点及其在不同领域的各种应用。读完本指南后&#xff0c;你…

ESP32外部中断原理详解及代码示例

一、为什么要使用中断 ESP32是一个集成了Wi-Fi、蓝牙并支持低功耗的微控制器。它有许多GPIO&#xff08;通用输入/输出&#xff09;引脚&#xff0c;可以用于连接各种外部设备&#xff0c;如传感器、按钮、开关等。 在使用这些外部设备时&#xff0c;我们经常需要知道它们何时…

服务器数据恢复-RAID5常见故障的数据恢复方案

raid5阵列常见故障&#xff1a; 1、服务器硬件故障或者RAID阵列卡故障&#xff1b; 2、服务器意外断电导致的磁盘阵列故障&#xff1b; 3、服务器RAID阵列阵列磁盘出现物理故障&#xff0c;如&#xff1a;电路板坏、磁头损坏、盘面划伤、坏扇区、固件坏等&#xff1b; 4、误操作…

第二证券:10家央企集体行动!9月至今逾百家公司回购增持

10月16日&#xff0c;10家央企连续公告&#xff0c;掀起了新一轮回购增持潮。其间&#xff0c;5家上市公司发布新增增持方案&#xff0c;约5亿&#xff5e;16.3亿元&#xff1b;2家上市公司发布增持打开&#xff0c;估计约23.43亿元&#xff1b;1家上市公司新增回购方案&#x…

3dmax中的 (Corona 9)cr渲染器怎么渲染?cr渲染器使用教程

Corona 9渲染器在3ds Max和Cinema 4D中应用广泛&#xff0c;是一款高效且功能强大的渲染器&#xff0c;得到了许多用户的好评。 Corona 9有以下几个主要的特点&#xff1a; 出色的渲染速度&#xff1a;Corona 9被证明是一个快速且高效的渲染引擎&#xff0c;它能够在保证高质…