JDBC(7)—DAO
介绍:
DAO(Data Access Object):数据访问对象- 1.what:访问数据信息的类,包含了对数据的CRUD(create read、update、delete),而不包含业务相关的信息。
2.why:实现功能模块化,更有利于代码的维护和升级。 - 3.how:使用JDBC编写DAO可能会包含的方法。
- public void update(String sql, Object … objects)
- public T get(Class clazz, String sql, Object … objects)
- public List getForList(Class calzz, String sql, Object … objects)
public E getForValue(String sql, Object … objects)
版本:1.0,之后还会对DAO进行修改,这只是一个非常简单的介绍。
- 1.what:访问数据信息的类,包含了对数据的CRUD(create read、update、delete),而不包含业务相关的信息。
2.实例:
DAO层代码
public class DAO1_7 {
/**
* 1.更新操作,insert、update、delete操作都包含在其中。
* @param sql
* @param objects
*/
public void update(String sql, Object ...objects){
Connection conn = null;
PreparedStatement preparedstatement = null;
try {
conn = TestTools.getConnection();
preparedstatement = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
preparedstatement.setObject(i + 1, objects[i]);
}
preparedstatement.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(preparedstatement, conn);
}
}
/**
* 2.查询一条记录,返回对应的对象。
* @param clazz
* @param sql
* @param objects:占位符从1开始
* @return
*/
public <T> T get(Class<T> clazz,String sql,Object ...objects){
T entity = null;
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
ResultSetMetaData rsmd = null;
try {
//1.获取Connection
conn = TestTools.getConnection();
//2.获取PreparedStatement
preparedstatement = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0; i < objects.length; i++){
preparedstatement.setObject(i + 1, objects[i]);
}
//4.进行查询,获取ResultSet对象
rs = preparedstatement.executeQuery();
//5.若ResultSet中有数据,准备一个Map<String,Object>:键:存放列的别名,值:存放列的值
if(rs.next()){
Map<String,Object> values = new HashMap<String,Object>();
//6.得到ResultSetMetaData对象。
rsmd = rs.getMetaData();
//7.处理ResultSet,把指针向下移动一个单位。(在判断是否有数据是已经移动,此处不在需要)
//8.ResultSetMetaData对象中得到结果集中有多少列
int columnCount = rsmd.getColumnCount();
//9.由ResultSetMetaData得到每一列的值,再由ResultSet得到具体每一列的值
for(int i = 0; i < columnCount; i++){
String columnLabel = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
//10.填充Map对象
values.put(columnLabel, columnValue);
}
//11.使用反射创建Class对应的对象
entity = clazz.newInstance();
//12.遍历Map对象,使用反射遍历填充对象的属性值,Map:key为属性名,value为属性值
for(Map.Entry<String, Object> entry : values.entrySet()){
String propertyName = entry.getKey();
Object value = entry.getValue();
TestTools.setFieldValue(entity, propertyName, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return entity;
}
/**
* 3.查询多条记录,返回对应的对象的集合。
* @param calzz
* @param sql
* @param objects
* @return
*/
public <T> List<T> getForList(Class<T> calzz,String sql,Object ... args){
List<T> list = new ArrayList<>();//用于返回多个对象
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
try {
//1.获取Connection连接
conn = TestTools.getConnection();
//2.获取PreparedStatement对象
preparedstatement = conn.prepareStatement(sql);
//3.填充占位符
for(int i = 0; i < args.length; i++){
preparedstatement.setObject(i + 1, args[i]);
}
//4.进行查询,获取ResultSet对象
rs = preparedstatement.executeQuery();
//5.若ResultSet中有数据,准备一个List<Map<String,Object>>:
//键:存放列的别名,值:存放列的值,其中一个Map对象对应一条记录,values用于存放
List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> map = null;
//6.得到ResultSetMetaData对象。
ResultSetMetaData rsmd = preparedstatement.getMetaData();
//7.处理ResultSet,使用while()循环。(在判断是否有数据是已经移动,此处不在需要)
while(rs.next()){
map = new HashMap<>();
//8.把每个列别名和列值取出来,存到Map对象中
for(int i = 0; i < rsmd.getColumnCount(); i++){
String columnName = rsmd.getColumnLabel(i + 1);
Object columnValue = rs.getObject(i + 1);
map.put(columnName, columnValue);
}
//9.再把Map对象存到List中
values.add(map);
}
//12.判断List是否为空集合,若不空则便利List得到一个个Map对象,
//再把Map对象转化成Class参数对应的Object对象
T bean = null;
if(values.size() > 0){
for(Map<String, Object> m : values){
bean = calzz.newInstance();
for(Map.Entry<String, Object> entry : m.entrySet()){
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
//为类成员变量赋值。
TestTools.setFieldValue(bean, propertyName, propertyValue);
}
//13.把Object对象放入到list中
list.add(bean);
}
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return list;
}
/**
* 4_1.功能:查询多条记录,返回对应的对象的集合。对以上3.方法进行的拆分。
*与上一致,其中对ResultSet对象之后的代码进行优化,包括每次循环都都要获取列别名进行优化修改。
* @param calzz
* @param sql
* @param objects
* @return
*/
public <T> List<T> getForLists(Class<T> calzz,String sql,Object ... args){
List<T> list = new ArrayList<>();//用于接收返回的多个对象
Connection conn = null;
PreparedStatement preparedstatement = null;
ResultSet rs = null;
try {
//1.得到结果集
conn = TestTools.getConnection();
preparedstatement = conn.prepareStatement(sql);
for(int i = 0; i < args.length; i++){
preparedstatement.setObject(i + 1, args[i]);
}
rs = preparedstatement.executeQuery();
//-----------------修改
//2.处理结果集,得到Map的List,其中一个Map对象就是一条记录,Map中Key表示列别名,Value表示列值
List<Map<String, Object>> values = handleResultSetToMapList(rs);
//3.把Map的list转为Clazz对应的list,其中Map的Key表示Class的成员属性,Value表示成员属性的值
list = transfterMapListToBeanList(calzz, values);
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, preparedstatement, conn);
}
return list;
}
/**
* 4_2.处理结果集,获取Map的List,其中一条Map对象对应一条记录。
* @param rs
* @return
* @throws SQLException
*/
private List<Map<String, Object>> handleResultSetToMapList(ResultSet rs)
throws SQLException {
List<Map<String, Object>> values = new ArrayList<>();
Map<String, Object> map = null;
//---------------此处被修改。6.得到ResultSetMetaData对象。
List<String> columnLabels = getColumnLabels(rs);
while(rs.next()){
map = new HashMap<>();
//---------------此处被修改。8.把每个列别名和列值取出来,存到Map对象中
for(String columnName : columnLabels){
Object columnValue = rs.getObject(columnName);
map.put(columnName, columnValue);
}
values.add(map);
}
return values;
}
/**
* 4_3获取结果集所有的列别名,存到集合中,再返回集合。
* @param rs
* @return
*/
private List<String> getColumnLabels(ResultSet rs){
List<String> labels = new ArrayList<>();
try {
ResultSetMetaData rsmd = rs.getMetaData();
for(int i = 0; i < rsmd.getColumnCount(); i++){
labels.add(rsmd.getColumnLabel(i + 1));
}
} catch (SQLException e) {
e.printStackTrace();
}
return labels;
}
/**
* 4_4.
* @param calzz
* @param values
* @return
* @throws InstantiationException
* @throws IllegalAccessException
*/
private <T> List<T> transfterMapListToBeanList(Class<T> calzz,
List<Map<String, Object>> values) throws InstantiationException,
IllegalAccessException {
List<T> result = new ArrayList<>();
T bean = null;
if(values.size() > 0){
for(Map<String, Object> m : values){
bean = calzz.newInstance();
for(Map.Entry<String, Object> entry : m.entrySet()){
String propertyName = entry.getKey();
Object propertyValue = entry.getValue();
//为类成员变量赋值。
TestTools.setFieldValue(bean, propertyName, propertyValue);
}
//13.把Object对象放入到list中
result.add(bean);
}
}
return result;
}
/**
* 返回某条记录的某一个字段的值或一个统计的值(一共有多少条记录等。),即:确定的某一行的某个字段的值,或者计算的值
* @param sql
* @param objects
* @return
*/
public <E> E getForValue(String sql, Object ... objects){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.得到结果集:该结果集应该只有一行,且只有一列
conn = TestTools.getConnection();
ps = conn.prepareStatement(sql);
for(int i = 0; i < objects.length; i++){
ps.setObject(i + 1, objects[i]);
}
rs = ps.executeQuery();
if(rs.next()){
//2.取得结果
return (E) rs.getObject(1);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
TestTools.release(rs, ps, conn);
}
return null;
}
}
测试dao层代码
public class DAOTest_1_7 {
DAO1_7 dao = new DAO1_7();
//测试:DAO——update(String sql, Object ...objects)方法。
@Test
public void testUpdate() {
String sql = "insert into customers(name,age,birth,address) " +
"value(?,?,?,?)";
dao.update(sql, "刘飒","20",new Date(new java.util.Date().getTime()),"河南省");
}
//测试:DAO——get(Class<T> clazz,String sql,Object ...objects)方法。
@Test
public void testGet() {
String sql = "select * from customers where id = ?";
Customers customers = dao.get(Customers.class, sql, 12);
System.out.println(customers);
}
//测试:DAO——getForList(Class<T> calzz,String sql,Object ... args)方法。
@Test
public void testGetForList() {
String sql = "select FlowID ,Type , IDCard , ExamCard " +
", StudentName , Location , Grade from examStudent";
List<Student> student = dao.getForLists(Student.class, sql);
for(int i = 0; i < student.size(); i++){
System.out.println(student.get(i));
}
}
//测试:DAO——getForValue(String sql, Object ... objects)
@Test
public void testGetForValue(){
String sql = "select examCard from examstudent where FlowID = ?";
String examCard = dao.getForValue(sql, 33);
if(examCard == null){
System.out.println("查无信息!");
}else{
System.out.println(examCard);
}
sql = "select Count(*) from examstudent";
Object count = dao.getForValue(sql);
System.out.println("共有:"+count+"行");
}
}
JDBC(7)—DAO的更多相关文章
- 跟着刚哥学习Spring框架--JDBC(六)
Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要提供JDBC模板方式.关系数据库对象化方式.SimpleJdbc方式.事务管理来简 ...
- SSM框架之Mybatis(3)dao层开发
Mybatis(3)dao层开发 以实现类完成CRUD操作 1.持久层dao层接口的书写 src\main\java\dao\IUserDao.java package dao; import dom ...
- MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JDBC(14)—对DAO进行改进修改
结构: DAO2_7< T >(接口)->DAOTestImpl< T >(实现类)->CustomerDAO(继承的子类)->CustomerDAOTest ...
- JDBC(四)
1 Apache DBUtils框架 1.1 DBUtils简介 commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本非常低,并且使用db ...
- JDBC(9)—事务(Transaction)
数据库事务:在数据库中所谓事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态.为确保数据库中的数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这些 ...
- jdbc(MySQL)
1.连接数据库 2.使用配置文件 3.启用连接池 4.事务 JDBC WHAT? 用于执行 SQL 语句的 Java API WHY? 不需要了解每一种数据库连接操作方式 HOW? 加载驱动.获取连接 ...
- JavaWeb基础—JDBC(二)事务与批处理
一.批处理 这里给出PrepareStatement的示例,优点是可以发送预编译的SQL,缺点是SQL语句无法更换,但参数可以更换 批处理:多条语句的处理 mysql默认是关闭的,要打开需要在url后 ...
- JDBC(一)
1. JDBC介绍 JDBC(Java DataBase Connectivity),即Java数据库的连接.JDBC是一种用于执行SQL语句(DML,DDL,DQL)的Java API,可以为多 ...
随机推荐
- CentOS 6.5结合busybox完成自制Linux系统及远程登录和nginx安装测试
前言 系统定制在前面的博文中我们就有谈到过了,不过那个裁减制作有简单了点,只是能让系统跑起来而,没有太多的功能,也没的用户登录入口,而这里我们将详细和深入的来谈谈Linux系统的详细定制过程和实 ...
- linux压缩与解压
1.tar -zcvf /home/aaa.tar.gz /xahot tar -zcvf 打包后生成的文件名全路径 要打包的目录 解压 #tar -zxvf /usr/local/test.tar. ...
- python算法双指针问题:使用列表和数组模拟单链表
这个很多基础算法,python已内部实现了. 所以,要想自己实现链表这些功能时, 反而需要自己来构造链表的数据结构. 当然,这是python灵活之处, 也是python性能表达不如意的来源. valu ...
- P2152 [SDOI2009]SuperGCD 未完成
辗转相减求a,b的gcd其实可以优化的: 1.若a为偶数,b为奇数:gcd(a,b)=gcd(a/2,b) 2.若a为奇数,b为偶数:gcd(a,b)=gcd(a,b/2) 3.若a,b都是偶数:gc ...
- [转]win7远程连接ubuntu14.04的相关配置,解决连接时灰屏
如何设置可以远程操作 安装必要的远程桌面的软件:xfce,xrdp,vnc4server sudo apt-get update sudo apt-get install xfce4 sudo apt ...
- 项目部署到liunx环境下访问接口返回异常
1.访问接口返回异常 已经连续踩了两次这个坑了.所以记下来了.方便下次搜索! 项目在window下运行正常,无任何异常! 但是部署到liunx环境下的服务器上就有问题 访问静态页面毫无问题,一旦涉及到 ...
- ajax请求案例
let url="loginToIndex"; $.ajax({ url:url,//请求的url type:"POST",//请求方式 async:false ...
- 【Java】 剑指offer(33) 二叉搜索树的后序遍历序列
本文参考自<剑指offer>一书,代码采用Java语言. 更多:<剑指Offer>Java实现合集 题目 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如 ...
- 093实战 Nginx日志切割,以及脚本上传nginx的切割日志
一:日志切割步骤 命令都在root下进行 1.创建目录 mkdir -p /etc/opt/modules/bin ## 创建文件夹 2.上传cut 3.观察目录 4.修改的cut文件 5.检测 需要 ...
- [漏洞分析]thinkphp 5.1.25 insert、insetAll、update方法注入
0x00 前言 这个洞,早在9月29号的时候我提交给先知,那时候tp还是5.1.25的版本,天还很蓝,我也还很年轻.时至今日这个洞依旧没有审核,而tp在这期间都已经更新到了5.1.29.在最近我去跟踪 ...