在這個項目中,EmpService
和 EmpMapper
都定義接口,是基于面向接口編程(Interface Oriented Programming,IOP)的設計思想,這兩種接口在項目中承擔著不同的職責,具體說明如下:
EmpService接口
-
作用
- 業務邏輯抽象:
EmpService
接口對員工相關的業務邏輯進行了抽象和定義。它將復雜的業務操作封裝成一個個方法,比如員工的新增、刪除、修改、查詢等操作,使得上層的EmpController
無需關心業務邏輯的具體實現細節,只需要調用接口方法即可。 - 規范業務行為:通過定義接口,為業務邏輯的實現制定了統一的規范。不同的開發者可以根據這個規范,在
EmpService
接口的實現類(通常在EmpService
接口所在包的impl
子包下)中編寫具體的業務邏輯代碼。例如,在實現員工查詢方法時,可能需要對查詢條件進行合法性校驗、處理分頁邏輯、調用緩存服務(如果有的話)等,這些都可以在實現類中完成,只要保證方法簽名符合接口定義即可。 - 便于代碼維護和擴展:當業務需求發生變化時,比如需要在員工刪除操作中添加額外的業務校驗(如檢查該員工是否有關聯的訂單未處理),只需要在
EmpService
接口的實現類中修改對應的方法實現,而不會影響到EmpController
以及其他依賴該接口的代碼。同時,也方便在不修改接口的情況下,對業務邏輯進行擴展,例如添加新的業務方法。 - 實現業務層的依賴倒置:在 Spring 等框架中,可以通過依賴注入(Dependency Injection,DI)的方式將
EmpService
接口的實現類注入到EmpController
中,實現了高層模塊(EmpController
)不依賴于低層模塊(EmpService
實現類)的具體實現,而是依賴于抽象(EmpService
接口),提高了代碼的可維護性和可測試性。
- 業務邏輯抽象:
-
示例
假設EmpService
接口有以下定義:
public interface EmpService {// 查詢所有員工List<Emp> listAllEmp();// 根據員工ID查詢員工Emp getEmpById(Integer empId);// 新增員工void addEmp(Emp emp);// 修改員工void updateEmp(Emp emp);// 刪除員工void deleteEmp(Integer empId);
}
在 EmpService
接口的實現類中,會根據業務需求實現這些方法,可能會涉及到調用 EmpMapper
接口進行數據庫操作,以及處理其他業務相關的邏輯。
EmpMapper接口
-
作用
- 數據庫操作抽象:
EmpMapper
接口對員工相關的數據庫操作進行了抽象。它定義了與數據庫交互的方法,如查詢、插入、更新、刪除員工數據等,使得業務層(EmpService
)無需直接編寫 SQL 語句,也無需關心數據庫連接的獲取、關閉等底層操作。 - 配合 MyBatis 框架:在使用 MyBatis 框架的項目中,
EmpMapper
接口與對應的 XML 映射文件(如EmpMapper.xml
)配合使用。接口中的方法與 XML 文件中定義的 SQL 語句相對應,MyBatis 框架會通過動態代理等機制,在運行時生成接口的實現類,從而執行對應的 SQL 操作。例如,EmpMapper
接口中的查詢方法會根據 XML 文件中定義的 SQL 語句從數據庫中獲取數據,并將結果映射為 Java 對象(如Emp
實體類)返回給調用者。 - 實現數據訪問層的解耦:通過將數據庫操作抽象成接口,使得業務層與具體的數據庫實現解耦。如果后續需要更換數據庫(如從 MySQL 切換到 Oracle),只需要修改
EmpMapper.xml
中的 SQL 語句,以及數據庫連接配置等,而業務層的代碼(EmpService
及其實現類)無需進行大規模修改,提高了代碼的可移植性和可維護性。 - 方便測試和代碼復用:在單元測試中,可以通過模擬
EmpMapper
接口的行為來測試業務層代碼,而無需真正連接到數據庫。同時,EmpMapper
接口定義的數據庫操作方法可以在多個業務邏輯中復用,提高了代碼的復用性。
- 數據庫操作抽象:
-
示例
假設EmpMapper
接口有以下定義:
public interface EmpMapper {// 查詢所有員工List<Emp> selectAllEmp();// 根據員工ID查詢員工Emp selectEmpById(Integer empId);// 新增員工int insertEmp(Emp emp);// 修改員工int updateEmp(Emp emp);// 刪除員工int deleteEmp(Integer empId);
}
在 EmpMapper.xml
文件中,會有與這些方法對應的 SQL 語句定義,例如:
<select id="selectAllEmp" resultType="com.itheima.pojo.Emp">SELECT * FROM emp
</select>
<select id="selectEmpById" parameterType="int" resultType="com.itheima.pojo.Emp">SELECT * FROM emp WHERE emp_id = #{empId}
</select>
<insert id="insertEmp" parameterType="com.itheima.pojo.Emp">INSERT INTO emp (emp_name, age, gender,...) VALUES (#{empName}, #{age}, #{gender},...)
</insert>
<update id="updateEmp" parameterType="com.itheima.pojo.Emp">UPDATE emp SET emp_name = #{empName}, age = #{age}, gender = #{gender},... WHERE emp_id = #{empId}
</update>
<delete id="deleteEmp" parameterType="int">DELETE FROM emp WHERE emp_id = #{empId}
</delete>
兩者區別
- 功能職責不同:
EmpService
接口關注的是業務邏輯層面的操作,處理與員工相關的業務需求,如數據校驗、業務規則應用等;而EmpMapper
接口專注于數據庫操作,負責從數據庫中獲取數據或向數據庫中存儲、更新、刪除數據。 - 調用層次不同:
EmpController
調用EmpService
接口來處理業務請求,EmpService
接口在實現業務邏輯過程中會調用EmpMapper
接口來完成數據庫操作。即EmpService
接口處于業務層,EmpMapper
接口處于數據訪問層。 - 依賴關系不同:
EmpService
接口依賴于EmpMapper
接口,因為業務邏輯的實現往往需要對數據庫進行操作;而EmpMapper
接口不依賴于EmpService
接口,它直接與數據庫進行交互,為業務層提供數據訪問服務。 - 接口實現方式不同:
EmpService
接口的實現類由開發者根據業務需求編寫,實現業務邏輯代碼;EmpMapper
接口的實現是由 MyBatis 框架通過動態代理機制自動生成的,其具體的數據庫操作邏輯由對應的 XML 映射文件中的 SQL 語句決定。