1. 程式人生 > 其它 >DAO和增刪改查通用方法

DAO和增刪改查通用方法

尊重原創版權: https://www.gewuweb.com/hot/5347.html

DAO和增刪改查通用方法

DAO和增刪改查通用方法

DAO:Data Access
Object訪問資料資訊的類和介面,包括了對資料的CRUD(Create、Retrival、Update、Delete),而不包含任何業務相關的資訊

作用:為了實現功能的模組化,更有利於程式碼的維護和升級。

1.1表和JavaBean

1.2 DAO介面

package com.atguigu.dao;

import java.util.List;

import com.atguigu.bean.Department;

public interface DepartmentDAO {
void addDepartment(Department department)throws Exception;
void updateDepartment(Department department)throws Exception;
void deleteById(String did)throws Exception;
Department getById(String did)throws Exception;
List<Department> getAll()throws Exception;
}


package com.atguigu.dao;

import java.util.List;
import java.util.Map;

import com.atguigu.bean.Employee;

public interface EmployeeDAO {
void addEmployee(Employee emp)throws Exception;
void updateEmployee(Employee emp)throws Exception;
void deleteById(String eid)throws Exception;
Employee getById(String eid)throws Exception;
List<Employee> getAll()throws Exception;
Long getCount()throws Exception;
List<Employee> getAll(int page, int pageSize)throws Exception;
Double getMaxSalary()throws Exception;
Map<Integer,Double> getAvgSalaryByDid()throws Exception;
}

1.3 DAO實現類

(1)原生版

package com.atguigu.dao.impl.original;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import com.atguigu.bean.Department;
import com.atguigu.dao.DepartmentDAO;
import com.atguigu.utils.JDBCUtils;

public class DepartmentDAOImpl implements DepartmentDAO{

@Override
public void addDepartment(Department department) throws Exception {
Connection conn = JDBCUtils.getConnection();

String sql = "INSERT INTO t_department(did,dname,description) VALUES(NULL,?,?)";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, department.getName());
pst.setString(2, department.getDescription());
pst.executeUpdate();

JDBCUtils.closeQuietly(pst, conn);
}

@Override
public void updateDepartment(Department department) throws Exception {
Connection conn = JDBCUtils.getConnection();

String sql = "UPDATE t_department SET dname = ?,description = ? WHERE did = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, department.getName());
pst.setString(2, department.getDescription());
pst.setInt(3, department.getId());
pst.executeUpdate();

JDBCUtils.closeQuietly(pst, conn);
}

@Override
public void deleteById(String did) throws Exception {
Connection conn = JDBCUtils.getConnection();

String sql = "DELETE FROM t_department WHERE did = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, did);
pst.executeUpdate();

JDBCUtils.closeQuietly(pst, conn);
}

@Override
public Department getById(String did) throws Exception {

Connection conn = JDBCUtils.getConnection();

String sql = "SELECT did,dname,description FROM t_department WHERE did = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, did);

ResultSet rs = pst.executeQuery();
Department dept = null;
if(rs.next()){
dept = new Department();
dept.setId(rs.getInt("did"));
dept.setName(rs.getString("dname"));
dept.setDescription(rs.getString("description"));
}

JDBCUtils.closeQuietly(rs, pst, conn);

return dept;
}

@Override
public List<Department> getAll() throws Exception {
Connection conn = JDBCUtils.getConnection();

String sql = "SELECT did,dname,description FROM t_department";
PreparedStatement pst = conn.prepareStatement(sql);

ResultSet rs = pst.executeQuery();
ArrayList<Department> list = new ArrayList<Department>();
while(rs.next()){
Department dept = new Department();
dept.setId(rs.getInt("did"));
dept.setName(rs.getString("dname"));
dept.setDescription(rs.getString("description"));
list.add(dept);
}

JDBCUtils.closeQuietly(rs, pst, conn);

return list;
}

}

1.4 抽取BasicDAO

package com.atguigu.dao.impl;

/*
* 這個類的作用是:對DAOImpl再次抽象,把共同的部分再次抽取
*/
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.atguigu.utils.JDBCUtils;

//泛型類
public abstract class BasicDAOImpl<T> {
private Class<T> type;

@SuppressWarnings("all")
protected BasicDAOImpl() {
// 為什麼要在構造器中寫,因為子類繼承BasicDAOImpl類一定會呼叫父類的構造器
Class clazz = this.getClass();// this代表的是正在建立的那個物件,即子類的物件

// 獲取clazz的帶泛型父類資訊
Type superType = clazz.getGenericSuperclass();

// Father<String>:引數化的型別
ParameterizedType p = (ParameterizedType) superType;

// 獲取泛型實參
Type[] ts = p.getActualTypeArguments();

// 因為當前類只有一個泛型形參,即子類中只有一個泛型實參
type = (Class) ts[0];
}

protected int update(String sql, Object... params) throws SQLException {
//1、獲取連線
Connection conn = JDBCUtils.getConnection();
//2、執行更新資料庫語句
int len = executeUpdate(conn, sql, params);
//3、關閉連線
JDBCUtils.closeQuietly(conn);
return len;
}

// 如果有需要在一個事務中完成更新,可以呼叫這個帶conn的方法
protected int update(Connection conn, String sql, Object... params) throws SQLException {
//執行更新資料庫語句
int len = executeUpdate(conn, sql, params);
return len;
}

private int executeUpdate(Connection conn, String sql, Object... params) throws SQLException {
//1、sql預編譯
PreparedStatement pst = conn.prepareStatement(sql);

//2、設定sql中的?
if (params != null && params.length > 0) {
// 陣列的下標是從0開始,?的編號是1開始
for (int i = 0; i < params.length; i++) {
pst.setObject(i + 1, params[i]);
}
}

//3、執行sql
int len = pst.executeUpdate();

//4、釋放資源
JDBCUtils.closeQuietly(pst);
return len;
}

//通用的查詢方法之一:查詢一行,即一個物件
/**
* 執行查詢操作的SQL語句,SQL可以帶引數(?)
* @param sql String 執行查詢操作的SQL語句
* @param args Object... 對應的每個?設定的值,順序要與?對應
* @return T 封裝了查詢結果的實體
* @throws Exception
*/
protected T get(String sql, Object... params) throws Exception {
//1、獲取連線
Connection conn = JDBCUtils.getConnection();

//2、執行查詢語句
ResultSet rs = executeQuery( conn,sql, params);

//3、處理查詢結果
//(1)獲取查詢的結果集的元資料資訊
ResultSetMetaData rsmd = rs.getMetaData();

//(2)這是查詢的結果集中,一共有幾列
int count = rsmd.getColumnCount();

//(3)建立例項物件
T t = type.newInstance();// 要求這個Javabean型別必須有無參構造

//(4)遍歷結果集
while (rs.next()) {
/*
* 問題? (1)sql語句中查詢了幾列,每一列是什麼屬性 (2)怎麼把這個值設定到Javabean的屬性中
*/
// (5)迴圈每一行有幾列
for (int i = 0; i < count; i++) {
// (6)獲取第幾列的名稱
// String columnName = rsmd.getColumnName(i+1);
// 如果sql中沒有取別名,那麼就是列名,如果有別名,返回的是別名
String fieldName = rsmd.getColumnLabel(i + 1);

// (7)獲取該列的值
// Object value = rs.getObject(columnName);
Object value = rs.getObject(fieldName);

// (8)設定obj物件的某個屬性中
Field field = type.getDeclaredField(fieldName);// JavaBean的屬性名
field.setAccessible(true);
field.set(t, value);
}
}

//4、釋放資源
JDBCUtils.closeQuietly(rs);
JDBCUtils.closeQuietly(conn);

return t;
}

private static ResultSet executeQuery(Connection conn, String sql, Object... params) throws SQLException {
//1、sql預編譯
PreparedStatement pst = conn.prepareStatement(sql);

//2、設定?
if (params != null && params.length > 0) {
// 陣列的下標是從0開始,?的編號是1開始
for (int i = 0; i < params.length; i++) {
pst.setObject(i + 1, params[i]);
}
}

//3、查詢
ResultSet rs = pst.executeQuery();
return rs;
}

// 通用的查詢方法之二:查詢多行,即多個物件
// Class<T> clazz:用來建立例項物件,獲取物件的屬性,並設定屬性值
/**
* 執行查詢操作的SQL語句,SQL可以帶引數(?)
* @param sql String 執行查詢操作的SQL語句
* @param args Object... 對應的每個?設定的值,順序要與?對應
* @return ArrayList<T> 封裝了查詢結果的集合
* @throws Exception
*/
public ArrayList<T> getList(String sql, Object... args) throws Exception {
// 1、獲取連線
Connection conn = JDBCUtils.getConnection();

//2、執行查詢sql
ResultSet rs = executeQuery(conn,sql, args);

//3、獲取結果集的元資料
ResultSetMetaData metaData = rs.getMetaData();
// 獲取結果中總列數
int count = metaData.getColumnCount();

// 建立集合物件
ArrayList<T> list = new ArrayList<T>();

while (rs.next()) {// 遍歷的行
// 1、每一行是一個物件
T obj = type.newInstance();

// 2、每一行有很多列
// for的作用是為obj物件的每一個屬性設定值
for (int i = 0; i < count; i++) {
// (1)每一列的名稱
String fieldName = metaData.getColumnLabel(i + 1);// 獲取第幾列的名稱,如果有別名獲取別名,如果沒有別名獲取列名
// (2)每一列的值
Object value = rs.getObject(i + 1);// 獲取第幾列的值
// (3)獲取屬性物件
Field field = type.getDeclaredField(fieldName);
// (4)設定可見性
field.setAccessible(true);
// (5)設定屬性值
field.set(obj, value);
}

// 3、把obj物件放到集合中
list.add(obj);
}

// 6、釋放資源
JDBCUtils.closeQuietly(rs);
JDBCUtils.closeQuietly(conn);

// 7、返回結果
return list;
}

//通用的查詢方法之三:查詢單個值
//單值:select max(salary) from employee; 一行一列
//select count(*) from t_goods; 一共幾件商品
public Object getValue(String sql,Object... args)throws Exception{
//1、獲取連線
Connection conn = JDBCUtils.getConnection();

//2、執行查詢sql
ResultSet rs = executeQuery(conn, sql, args);

Object value = null;
if(rs.next()){//一行
value = rs.getObject(1);//一列
}

//3、釋放資源
JDBCUtils.closeQuietly(rs);
JDBCUtils.closeQuietly(conn);

return value;
}

//通用的查詢方法之四:查詢多行多列,但每一行又不是一個JavaBean
/*
* SELECT did,AVG(salary),MAX(Salary) FROM t_employee GROUP BY did;
* did avg(salary) max(salary)
1 1990.90 8900
2 4889 6899
*/
public List<Map<String,Object>> getListMap(String sql,Object... args)throws Exception{
//1、獲取連線
Connection conn = JDBCUtils.getConnection();

//2、執行sql
ResultSet rs = executeQuery(conn, sql, args);

//獲取結果集的元資料物件
ResultSetMetaData metaData = rs.getMetaData();
//一共有幾列
int count = metaData.getColumnCount();
//建立List
ArrayList<Map<String,Object>> list = new ArrayList<Map<String,Object>>();

while(rs.next()){
//每一行是一個Map的物件
HashMap<String,Object> map = new HashMap<String,Object>();

//map的key是列名
for (int i = 0; i < count; i++) {
//(1)獲取列名或別名
String columnName = metaData.getColumnLabel(i+1);
//(2)獲取對應的值
Object value = rs.getObject(i+1);
//(3)把這對值放到map中
map.put(columnName, value);
}

//把map放到List中
list.add(map);
}

//6、釋放資源
JDBCUtils.closeQuietly(rs);
JDBCUtils.closeQuietly(conn);

return list;
}

//通用的查詢方法之四:查詢一行多列,但一行又不是一個JavaBean
public Map<String,Object> getMap(String sql,Object... args)throws Exception{
List<Map<String, Object>> listMap = getListMap(sql,args);
if(listMap.size()>0){
return listMap.get(0);
}
return null;
}
}

1.5 繼承BasicDAO的後的DAO實現類

DepartmentDAO實現類

package com.atguigu.dao.impl.basic;

import java.util.ArrayList;
import java.util.List;

import com.atguigu.bean.Department;
import com.atguigu.dao.DepartmentDAO;
import com.atguigu.dao.impl.BasicDAOImpl;

public class DepartmentDAOImplBasic extends BasicDAOImpl<Department> implements DepartmentDAO{

@Override
public void addDepartment(Department department) throws Exception {
String sql = "INSERT INTO t_department(did,dname,description) VALUES(NULL,?,?)";
update(sql, department.getName(),department.getDescription());
}

@Override


public void updateDepartment(Department department) throws Exception {
String sql = "UPDATE t_department SET dname = ?,description = ? WHERE did = ?";
update(sql, department.getName(),department.getDescription(),department.getId());
}

@Override
public void deleteById(String did) throws Exception {
String sql = "DELETE FROM t_department WHERE did = ?";
update(sql, did);
}

@Override
public Department getById(String did) throws Exception {
String sql = "SELECT did as id,dname as name,description FROM t_department WHERE did = ?";
Department department = get(sql, did);
return department;
}

@Override
public List<Department> getAll() throws Exception {
String sql = "SELECT did as id,dname as name,description FROM t_department";
ArrayList<Department> list = getList(sql);
return list;
}
}

EmployeeDAO實現類

package com.atguigu.dao.impl.basic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import com.atguigu.bean.Employee;
import com.atguigu.dao.EmployeeDAO;
import com.atguigu.dao.impl.BasicDAOImpl;

public class EmployeeDAOImpl extends BasicDAOImpl<Employee> implements EmployeeDAO{

@Override
public void addEmployee(Employee emp) throws Exception {
String sql = "INSERT INTO t_employee "
+ "(eid,ename,tel,gender,salary,commission_pct,birthday,hiredate,job_id,email,mid,address,native_place,did)"
+ "VALUES(NULL,?,?,?,?,?,?,?,?,?,?,?,?,?)";
Object[] args = new Object[13];
args[0] = emp.getEname();
args[1] = emp.getTel();
args[2] = emp.getGender();
args[3] = emp.getSalary();
args[4] = emp.getCommissionPct();
args[5] = emp.getBirthday();
args[6] = emp.getHiredate();
args[7] = emp.getJobId();
args[8] = emp.getEmail();
args[9] = emp.getMid();
args[10] = emp.getAddress();
args[11] = emp.getNativePlace();
args[12] = emp.getDid();

update(sql, args);
}

@Override
public void updateEmployee(Employee emp) throws Exception {
String sql = "UPDATE t_employee SET "
+ "ename=?,tel=?,gender=?,salary=?,commission_pct=?,birthday=?,hiredate=?,job_id=?,email=?,MID=?,address=?,native_place=?,did=?"
+" WHERE eid = ?";
Object[] args = new Object[14];
args[0] = emp.getEname();
args[1] = emp.getTel();
args[2] = emp.getGender();
args[3] = emp.getSalary();
args[4] = emp.getCommissionPct();
args[5] = emp.getBirthday();
args[6] = emp.getHiredate();
args[7] = emp.getJobId();
args[8] = emp.getEmail();
args[9] = emp.getMid();
args[10] = emp.getAddress();
args[11] = emp.getNativePlace();
args[12] = emp.getDid();
args[13] = emp.getEid();
update(sql, args);
}

@Override
public void deleteById(String eid) throws Exception {
String sql = "DELETE FROM t_employee WHERE eid = ?";
update(sql, eid);
}

@Override
public Employee getById(String eid) throws Exception {
String sql = "SELECT eid,ename,tel,gender,salary,commission_pct as 'commissionPct',birthday,hiredate,"
+ "job_id as 'jobId',email,mid,address,native_place as 'nativePlace' ,did FROM t_employee WHERE eid = ?";
Employee employee = get(sql, eid);
return employee;
}

@Override
public List<Employee> getAll() throws Exception {
String sql = "SELECT eid,ename,tel,gender,salary,commission_pct as 'commissionPct',birthday,hiredate,"
+ "job_id as 'jobId',email,mid,address,native_place as 'nativePlace' ,did FROM t_employee";

ArrayList<Employee> list = getList(sql);
return list;
}

@Override
public Long getCount() throws Exception {
String sql = "SELECT COUNT(*) FROM t_employee";
Long value = (Long) getValue(sql);
return value;
}

@Override
public List<Employee> getAll(int page, int pageSize) throws Exception {
String sql = "SELECT eid,ename,tel,gender,salary,commission_pct as 'commissionPct',birthday,hiredate,"
+ "job_id as 'jobId',email,mid,address,native_place as 'nativePlace' ,did FROM t_employee LIMIT ?,?";

ArrayList<Employee> list = getList( sql, (page-1)*pageSize, pageSize);
return list;
}

@Override
public Double getMaxSalary() throws Exception {
String sql = "SELECT MAX(salary) FROM t_employee";
Double value = (Double) getValue(sql);
return value;
}

@Override
public Map<Integer, Double> getAvgSalaryByDid() throws Exception {
String sql = "SELECT did,MAX(salary) FROM t_employee GROUP BY did";
List<Map<String, Object>> list = getListMap(sql);

HashMap<Integer, Double> result = new HashMap<>();
for (Map<String, Object> map : list) {
Set<Entry<String, Object>> entrySet = map.entrySet();
Integer did = null;
Double salary = null;
for (Entry<String, Object> entry : entrySet) {
String key = entry.getKey();
if("did".equals(key)){
did = (Integer) entry.getValue();
}else{
salary = (Double) entry.getValue();
}
}

result.put(did, salary);
}
return result;
}
}

1.6 測試類

package com.atguigu.dao.test;

import java.util.List;
import java.util.Scanner;

import org.junit.Test;

import com.atguigu.bean.Department;
import com.atguigu.dao.DepartmentDAO;
import com.atguigu.dao.impl.basic.DepartmentDAOImplBasic;
import com.atguigu.dao.impl.original.DepartmentDAOImpl;
import com.atguigu.utils.CMUtility;

public class TestDepartmentDAO {
// DepartmentDAO dao = new DepartmentDAOImpl();
DepartmentDAO dao = new DepartmentDAOImplBasic();

@Test
public void addDepartment() {
Scanner input = new Scanner(System.in);
System.out.println("請輸入部門名稱:");
String name = input.nextLine();

System.out.println("請輸入部門簡介:");
String description = input.nextLine();

Department department = new Department(name, description);

try {
dao.addDepartment(department);
System.out.println("新增成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("新增失敗");
}
}

@Test
public void getAllDepartment() throws Exception {
List<Department> all = dao.getAll();
for (Department department : all) {
System.out.println(department);
}
}

@Test
public void updateDepartment() {

try {
getAllDepartment();

Scanner input = new Scanner(System.in);
System.out.println("請選擇要修改的部門編號:");
String did = input.nextLine();

Department dept = dao.getById(did);

System.out.println("請輸入部門名稱("+dept.getName()+"):");
String name = CMUtility.readString(dept.getName());

System.out.println("請輸入部門簡介("+dept.getDescription()+"):");
String description = CMUtility.readString(dept.getDescription());

Department department = new Department(dept.getId(),name, description);

dao.updateDepartment(department);
System.out.println("修改成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("修改失敗");
}
}

@Test
public void deleteDepartment() {

try {
getAllDepartment();

Scanner input = new Scanner(System.in);
System.out.println("請選擇要刪除的部門編號:");
String did = input.nextLine();

dao.deleteById(did);
System.out.println("刪除成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("刪除失敗");
}
}
}


package com.atguigu.dao.test;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

import com.atguigu.bean.Employee;
import com.atguigu.dao.EmployeeDAO;
import com.atguigu.dao.impl.basic.EmployeeDAOImpl;

public class TestEmployeeDAO {
EmployeeDAO ed = new EmployeeDAOImpl();

@Test
public void addEmployee()throws Exception{
//省略鍵盤輸入
String ename = "張三";
String tel = "10080";
String gender = "男";
double salary = 10000;


double commissionPct = 0.3;
Date birthday = new Date();
Date hiredate = new Date();;
int jobId = 2;
String email="[email protected]";
int mid = 1;
String address = "xx";
String nativePlace = "xxx";
int did = 2;

Employee emp = new Employee(ename, tel, gender, salary, commissionPct, birthday, hiredate, jobId, email, mid, address, nativePlace, did);
try {
ed.addEmployee(emp);
System.out.println("新增成功");
} catch (Exception e) {
e.printStackTrace();


System.out.println("新增失敗");
}
}

@Test
public void updateEmployee()throws Exception{
//省略鍵盤輸入
String eid = "1";
Employee emp = ed.getById(eid);

//這裡只演示修改一下,可以修改除了eid以外的所有專案
emp.setSalary(emp.getSalary() + 1000);

try {
ed.updateEmployee(emp);
System.out.println("修改成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("修改失敗");
}
}

@Test
public void deleteById()throws Exception{
//省略鍵盤輸入
String eid = "26";

try {
ed.deleteById(eid);
System.out.println("刪除成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("刪除失敗");
}

}

@Test
public void getAll()throws Exception{
List<Employee> all = ed.getAll();
for (Employee employee : all) {
System.out.println(employee);
}
}

@Test
public void getAllPage()throws Exception{
Long count = ed.getCount();
System.out.println("總記錄數:" + count);
int pageSize = 5;
System.out.println("每頁顯示5條");
int page = 2;
System.out.println("使用者選擇第" + page + "頁");

List<Employee> all = ed.getAll(page, pageSize);
for (Employee employee : all) {
System.out.println(employee);
}
}

@Test
public void getMaxSalary()throws Exception{
Double maxSalary = ed.getMaxSalary();
System.out.println("公司最高工資是: " + maxSalary);
}

@Test
public void getAvgSalaryByDid()throws Exception{
Map<Integer, Double> map = ed.getAvgSalaryByDid();
Set<Entry<Integer, Double>> entrySet = map.entrySet();
for (Entry<Integer, Double> entry : entrySet) {
System.out.println(entry.getKey()+ ":" + entry.getValue());
}
}
}

相關閱讀:

JDBC的操作有哪些

java程式設計技術JDBC

JDBC API的使用與操作詳解

JDBC工具類解讀,讓你快速入門

如何使用JDBC API操作資料庫

更多內容參考: https://www.gewuweb.com/sitemap.html