介绍:
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+"行");
}
}