1. 介绍:

    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进行修改,这只是一个非常简单的介绍。

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的更多相关文章

  1. 跟着刚哥学习Spring框架--JDBC(六)

    Spring的JDBC框架 Spring JDBC提供了一套JDBC抽象框架,用于简化JDBC开发. Spring主要提供JDBC模板方式.关系数据库对象化方式.SimpleJdbc方式.事务管理来简 ...

  2. SSM框架之Mybatis(3)dao层开发

    Mybatis(3)dao层开发 以实现类完成CRUD操作 1.持久层dao层接口的书写 src\main\java\dao\IUserDao.java package dao; import dom ...

  3. MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  4. JDBC(14)—对DAO进行改进修改

    结构: DAO2_7< T >(接口)->DAOTestImpl< T >(实现类)->CustomerDAO(继承的子类)->CustomerDAOTest ...

  5. JDBC(四)

    1 Apache DBUtils框架 1.1 DBUtils简介 commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的简单封装,学习成本非常低,并且使用db ...

  6. JDBC(9)—事务(Transaction)

    数据库事务:在数据库中所谓事务是指一组逻辑操作单元,使数据从一种状态转换到另一种状态.为确保数据库中的数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这些 ...

  7. jdbc(MySQL)

    1.连接数据库 2.使用配置文件 3.启用连接池 4.事务 JDBC WHAT? 用于执行 SQL 语句的 Java API WHY? 不需要了解每一种数据库连接操作方式 HOW? 加载驱动.获取连接 ...

  8. JavaWeb基础—JDBC(二)事务与批处理

    一.批处理 这里给出PrepareStatement的示例,优点是可以发送预编译的SQL,缺点是SQL语句无法更换,但参数可以更换 批处理:多条语句的处理 mysql默认是关闭的,要打开需要在url后 ...

  9. JDBC(一)

    1.   JDBC介绍 JDBC(Java DataBase Connectivity),即Java数据库的连接.JDBC是一种用于执行SQL语句(DML,DDL,DQL)的Java API,可以为多 ...

随机推荐

  1. shell脚本中冒号

    格式:: your comment here 格式:# your comment here 写代码注释(单行注释). 例如: 格式:: 'comment line1 comment line2 mor ...

  2. VC++文件拖放

    属性Accept Files 设置True,消息WM_DROPFILES 设置事件OnDropFiles void CNWiReworkDlg::OnDropFiles(HDROP hDropInfo ...

  3. Java发送邮件时标题和发件人乱码

    最近碰到一个问题,Java发送邮件时,查看邮箱结果,发件人及邮件标题正文全部乱码 通过翻阅资料,原因及解决方法如下: // Set Subject: 头字段 message.setSubject(Mi ...

  4. IDEA测试结果查看

    点击漏斗图标切换查看测试日志信息,点击,导出测试报告

  5. PYTHON-模块-time&datetime-练习 +目录规范

    # 作业# 1.请写出规范目录# 并解释各文件夹的作用bin 可执行文件conf 配置文件core 主要业务逻辑db 数据文件lib 库(公共代码 第三方模块)log 日志文件 # 2.改造atm + ...

  6. 【必备】史上最全的浏览器 CSS & JS Hack 手册

    [必备]史上最全的浏览器 CSS & JS Hack 手册   浏览器渲染页面的方式各不相同,甚至同一浏览器的不同版本(“杰出代表”是 IE)也有差异.因此,浏览器兼容成为前端开发人员的必备技 ...

  7. hdu4638 莫队算法

    莫队算法基础题,题目看懂就能做出来 #include<iostream> #include<cstring> #include<cstdio> #include&l ...

  8. bzoj 2142

    数论大集合 只要你做完了这道题,除了线性筛和降幂公式以外,所有数论noip知识点就都会了... 题意:求C(n,∑w)*C(∑w,w1)*C(∑w-w1,w2).....mod p(不保证p为质数) ...

  9. SpringMVC MongoDB之“基本文档查询(Query、BasicQuery)”

    一.简介 spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我 ...

  10. RabbitMQ(一):RabbitMQ 安装与配置(Mac)

    一.rabbitmq 安装与配置 安装: brew install rabbitmq # 进入安装目录 cd /usr/local/Cellar/rabbitmq/3.7.12 # 启动 brew s ...