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. android margin--负的margin的使用

    通常情况下,如果我们想要两个控件实现重叠的效果,一般都是使用FrameLayout 或者RelativeLayout布局.其实,如果设置两个控件的margin值为负数,也能实显控件重叠的效果. 先展示 ...

  2. Mysql复习大全(转)

    基础知识: 1.数据库的连接 mysql -u -p -h -u 用户名 -p 密码 -h host主机 2.库级知识 显示数据库: show databases; 选择数据库: use dbname ...

  3. 微信支付之JsApi支付

    常见问题:金额错误,微信金额是int类型,最小单位为分,即是1 客户端调用微信支付的时候一闪而过:这个原因是因为微信商户后台支付目录地址没设置对,导致js调用的时候验证没通过 .aspx页面设置: x ...

  4. hdu4942线段树模拟rotate操作+中序遍历 回头再做

    很有意思的题目,详细题解看这里 https://blog.csdn.net/qian99/article/details/38536559 自己的代码不知道哪里出了点问题 /* rotate操作不会改 ...

  5. hdu3183 rmq求区间最值的下标

    两个月前做的题,以后可以看看,是rmq关于求区间最值的下标 /* hdu3183 终点 给一个整数,可以删除m位,留下的数字形成一个新的整数 rmq 取n-m个数,使形成的数最小 */ #includ ...

  6. cf276E 两棵线段树分别维护dfs序和bfs序,好题回头再做

    搞了一晚上,错了,以后回头再来看 /* 对于每次更新,先处理其儿子方向,再处理其父亲方向 处理父亲方向时无法达到根,那么直接更新 如果能达到根,那么到兄弟链中去更新,使用bfs序 最后,查询结点v的结 ...

  7. ThreadLocal详解,处理成员变量线程不安全的情况

    ThreadLocal翻译成中文比较准确的叫法应该是:线程局部变量. 这个玩意有什么用处,或者说为什么要有这么一个东东?先解释一下,在并发编程的时候,成员变量如果不做任何处理其实是线程不安全的,各个线 ...

  8. hdu 3405 删掉某点后 求最小生成树

    给出N个点的坐标 边的权值为两点间的距离 删掉其中某点 求最小生成树的权值和 要求这权值最小 因为最多50个点 所以具体是删哪个点 用枚举假如有4个点 就要求4次最小生成树 分别是2 3 4 | 1 ...

  9. poj 2752 求一个字符串所有的相同前后缀

    求一个字符串所有的相同前后缀Sample Input ababcababababcababaaaaaSample Output 2 4 9 181 2 3 4 5 #include <iostr ...

  10. Linux 忘记了mysql 密码

    killall mysqld /usr/local/mysql/bin/mysqld_safe --skip-grant-tables & use mysql update user set ...