DAO和增刪改查通用方法
阿新 • • 發佈:2022-05-07
尊重原創版權: 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());
}
}
}
相關閱讀: