<六>JDBC_DAO 设计模式

时间:2022-11-02 13:16:09

JDBC_DAO设计模式
 DAO:Data Access Object(数据访问对象)
  why:实现功能的模块化,更有利于代码的维护和升级。
  what:访问数据信息的类,包含了对数据的CRUD(create、read、update、delete),而不包含任何业务相关
  的信息。
  
  该DAO可以被子类继承或直接使用。
  
  how:使用JDBC编写DAO可能会包含的方法:
   //insert、update、delete操作都可以包含其中
   void update(String sql,Object...args);
   //查询一条记录,返回对应的对象
   <T> T get(Class<T> clazz,String sql,Object...args);
   //查询多条记录,返回对应的对象的集合
   <T> List<T> getForList(Class<T> clazz,String sql,Object...args);
   //返回某个对象的属性值
   <E>  E getForValue(String sql,Object...args);

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.kk.jdbc.JDBCTools;
import com.kk.jdbc.ReflectionUtils;

public class DAO {

//insert、update、delete操作都可以包含其中
 public void update(String sql,Object...args){
  Connection con=null;
  PreparedStatement ps=null;
  try {
   
   con=JDBCTools.getConnection();
   ps=con.prepareStatement(sql);
   for (int i = 0; i < args.length; i++) {
    ps.setObject(i+1, args[i]);
   }
   ps.executeUpdate();
  } catch (Exception e) {
   
  }
 }
 //查询一条记录,返回对应的对象
 public <T> T get(Class<T> clazz,String sql,Object...args){
  
  /*
   * 1、获取Connection
   * 2、获取PreparedStatement
   * 3、填充占位符
   * 4、进行查询,得到ResultSet
   * 5、准备一个Map<String,Object>对象,键->存放列的别名,键->存放列的值
   * 6、得到ResultSetMetaData对象
   * 7、处理ResultSet,把指针向下移动一个单位
   * 8、由ResultSetMetaData得到结果集中有多少列
   * 9、由ResultSetMetaData得到每一列的别名,由ResultSet得到具体每一列的值
   * 10、填充Map对象
   * 11、用反射创建Class对应的对象
   * 12、遍历Map对象,用反射填充对象的属性值:
   *   属性名为Map中的key,属性值为Map中的value
   * */
  
  T entity=null;
  Connection con=null;
  PreparedStatement ps=null;
  ResultSet rs=null;
  try {
   
   con=JDBCTools.getConnection();
   ps=con.prepareStatement(sql);
   for (int i = 0; i < args.length; i++) {
    ps.setObject(i+1, args[i]);
   }
   rs=ps.executeQuery();
   
   if (rs.next()) {
    Map<String,Object> values=new HashMap<>();
    ResultSetMetaData rsmd=rs.getMetaData();
    int columnCount=rsmd.getColumnCount();
    for (int i = 0; i < columnCount; i++) {
     String columnLabel=rsmd.getColumnLabel(i+1);
     Object columnValue=rs.getObject(columnLabel);
     values.put(columnLabel, columnValue);
    }
    
    entity=clazz.newInstance();
    
    for (Map.Entry<String, Object> entry : values.entrySet()) {
     String propertyName=entry.getKey();
     Object value=entry.getValue();
     //用反射赋值
     ReflectionUtils.setFieldValue(entity, propertyName, value);     
    }
    
   }
   
  } catch (Exception e) {
   e.printStackTrace();
  }
  return entity;
 }
 //查询多条记录,返回对应的对象的集合
 public <T> List<T> getForList(Class<T> clazz,String sql,Object...args){
  
  return null;
 }
 //返回某个对象的属性值
 public <E>  E getForValue(String sql,Object...args){
  
  return null;
 }
}

import static org.junit.Assert.*;
import java.sql.Date;
import org.junit.Test;
import com.kk.jdbc.Student;

public class DAOTest {

DAO dao=new DAO();
 
 @Test
 public void testUpdate() {
  String sql="insert into customers(name,email,birth) values (?,?,?)";
  dao.update(sql, "xiaoming","xm@.com",new Date(new java.util.Date().getTime()));
  
 }

@Test
 public void testGet() {
  String sql="select FlowId flow_Id,Type,IDCard,ExamCard,StudentName from examstudent where FlowId=?";
  Student stu=dao.get(Student.class,sql,1);
  System.out.println(stu);
 }

@Test
 public void testGetForList() {
  fail("Not yet implemented");
 }

@Test
 public void testGetForValue() {
  fail("Not yet implemented");
 }

}