17、簡單的企業人事管理系統(ssh)
–宣告,本部落格僅本人用於學習筆記
三大框架:
Struts框架
1. params攔截器: 請求資料封裝
2. 型別轉換/資料處理
3. struts配置
4. 檔案上傳/下載/國際化處理
5. 資料效驗/攔截器
6. Ognl表示式
7. 資料回顯/模型驅動/防止表單重複提交
Hibernate框架
1. Api簡介
2. 對映
多對一/一對多: 部門與員工
多對多/一對一
集合對映/元件對映/繼承對映
3. Hibernate 快取
4. 常用屬性:inverse/lazy/cascade
5. 物件狀態:臨時/持久/遊離
Spring框架
1) Spring IOC容器 【Inversion Of Control,即控制反轉】
建立物件/處理物件依賴關係
2) Aop程式設計
3) Spring宣告式事務管理
4) 框架整合
Spring與Struts
Spring與Hibernate
5)Spring對jdbc、hibernate操作的封裝
JdbcTemplate (dataSource)/ HibernateTemplate(SessionFactory)
目標:
案例 【軟體專案宣告週期】
- 需求分析
系統概述:
企業人事管理系統!
要求對員工資訊進行維護;
後臺系統先登陸,才能操作員工: 新增/修改/刪除
沒有登陸,只能檢視列表,不能操作!
功能分類:
【管理員模組:】
註冊/登陸
【員工模組】
1) 新增一個員工, 指定新增的部門
2) 對指定的員工資訊修改
3) 刪除選擇員工
4)列表展示
設計
2.1 系統設計
【系統架構師/技術經理】
主要做下面的事情,
1) 搭建系統框架結構
(基於mvc結構應用)
2) 確定專案的關鍵點/難點
3) 確定引用元件、公用類的版本
Struts2.3
Hibernate3.6
Spring3.2
2.2 資料庫設計
管理員表: t_admin
員工表: t_employee
部門: t_dept程式碼
步驟分析
編碼順序:1) 設計資料庫: hib_demo
建表: t_admin/t_employee/t_dept
2) 建立web專案、引入jar檔案、準備環境
…..3) 設計javvabean、寫對映
Admin.java 封裝管理員
Employee.java 員工
Dept.java 部門Admin.hbm.xml Employee.hbm.xml Dept.hbm.xml
4) Dao設計介面
IAdminDao.java 管理員模組
void save(Admin admin);
Admin findByAdmin(Admin admin);
IDeptDao.java 部門模組
List getAll();
Dept findById(int id);
IEmployeeDao.java 員工模組
Void save(Employee emp);
Void update(Employee emp);
Void delete(int id);
Employee findById(int id);
List getAll();
List getAll(String employeeName);
5) Dao介面實現6)Service介面設計
IAdminService.java 管理員模組
void register(Admin admin);
Admin login(Admin admin);
7)Service介面實現
8) Action實現
EmployeeAction.java 員工模組
AdminAction.java 管理員模組
9)jsp頁面
Index.jsp/list.jsp 首頁列表
http://localhost:8080/專案 首頁列表
優化部分:
10) 使用者登陸攔截器
UserInterceptor.java 檢查是否登陸
只有登陸才能操作; 否則只能檢視
11) Dao 操作優化
BaseDao.java 所有dao的通用方法,dao都必須繼承此類
(反射泛型)
實現步驟程式碼:
1) 設計資料庫: hib_demo
CREATE TABLE t_admin(
id INT PRIMARY KEY AUTO_INCREMENT,
adminName VARCHAR(20),
pwd VARCHAR(20)
)
表: t_dept/ t_employee
2) 建立web專案、引入jar檔案、準備環境
【struts相關jar】
commons-fileupload-1.2.2.jar
commons-io-2.0.1.jar
commons-lang3-3.1.jar
freemarker-2.3.19.jar
javassist-3.11.0.GA.jar
ognl-3.0.5.jar
struts2-core-2.3.4.1.jar
xwork-core-2.3.4.1.jar
【hibernate 相關 jar】
antlr-2.7.6.jar
commons-collections-3.1.jar
dom4j-1.6.1.jar
hibernate3.jar
hibernate-jpa-2.0-api-1.0.0.Final.jar
javassist-3.12.0.GA.jar
jta-1.1.jar
slf4j-api-1.6.1.jar
【Spring-core】
commons-logging-1.1.3.jar
spring-beans-3.2.5.RELEASE.jar
spring-context-3.2.5.RELEASE.jar
spring-core-3.2.5.RELEASE.jar
spring-expression-3.2.5.RELEASE.jar
【Spring-web】
spring-web-3.2.5.RELEASE.jar
struts2-spring-plugin-2.3.4.1.jar
【Spring-Aop】
aopalliance.jar
aspectjrt.jar
aspectjweaver.jar
spring-aop-3.2.5.RELEASE.jar
【Spring-orm】
c3p0-0.9.1.2.jar
mysql-connector-java-5.1.12-bin.jar
spring-orm-3.2.5.RELEASE.jar
spring-tx-3.2.5.RELEASE.jar
spring-jdbc-3.2.5.RELEASE.jar
結構圖
3) 設計javabean、寫對映
public class Admin {
private int id;
private String adminName;
private String pwd;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.itcast.entity">
<class name="Admin" table="t_admin">
<id name="id">
<generator class="native"></generator>
</id>
<property name="adminName" length="20"></property>
<property name="pwd" length="20"></property>
</class>
</hibernate-mapping>
public class Dept {
private int id;
private String name;
}
<hibernate-mapping package="cn.itcast.entity">
<class name="Dept" table="t_dept">
<id name="id" column="deptId">
<generator class="native"></generator>
</id>
<property name="name" column="deptName"></property>
</class>
</hibernate-mapping>
public class Employee {
private int id;
private String empName;
private double salary;
private Dept dept;
}
<hibernate-mapping package="cn.itcast.entity">
<class name="Employee" table="t_employee">
<id name="id" column="empId">
<generator class="native"></generator>
</id>
<property name="empName"></property>
<property name="salary"></property>
<!-- 多對一 -->
<many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
</class>
</hibernate-mapping>
4) Dao設計介面
IBaseDao
/**
* 所有dao的通用操作介面定義
*
*/
public interface IBaseDao<T> {
/**
* 儲存
* @param emp
*/
void save(T emp);
/**
* 跟新物件資訊
* @param emp
*/
void update(T emp);
/**
* 根據主鍵刪除
* @param id
*/
void delete(int id);
/**
* 根據主鍵查詢
* @param id
* @return
*/
T findById(int id);
/**
* 查詢全部
* @return
*/
List<T> getAll();
}
/**
* 部門模組dao介面設計
*
*/
public interface IDeptDao {
/**
* 查詢全部
* @return 返回全部資訊
*/
List<Dept> getAll();
/**
* 根據主鍵查詢
* @param id 主鍵
* @return 返回查詢後的結果
*/
Dept findById(int id);
}
/**
* 員工模組dao介面設計
*/
public interface IEmployeeDao {
/**
* 儲存員工
* @param emp
*/
void save(Employee emp);
/**
* 跟新員工資訊
* @param emp
*/
void update(Employee emp);
/**
* 根據主鍵刪除
* @param id
*/
void delete(int id);
/**
* 根據主鍵查詢
* @param id
* @return
*/
Employee findById(int id);
/**
* 查詢全部
* @return
*/
List<Employee> getAll();
/**
* 根據員工名稱條件查詢
* @param employeeName
* @return
*/
List<Employee> getAll(String employeeName);
}
/**
* 管理員模組dao介面
*
*/
public interface IAdminDao {
/**
* 儲存
* @param admin 管理員物件
*/
void save(Admin admin);
/**
* 根據管理員資訊查詢
* @param admin 管理員物件
* @return 返回查詢後的結果
*/
Admin findByAdmin(Admin admin);
}
Dao實現方法
/**
* 所有dao的通用操作,希望所有的dao都繼承此類
*
*
* @param <T>
*/
public class BaseDao<T> implements IBaseDao<T> {
// 當前操作的實際的bean型別
private Class<T> clazz;
// 獲取類名稱
private String className;
// 反射泛型
public BaseDao(){
Type type = this.getClass().getGenericSuperclass();
// 轉換為引數化型別
ParameterizedType pt = (ParameterizedType) type; // BaseDao<Employee>
// 得到實際型別
Type types[] = pt.getActualTypeArguments();
// 獲取實際型別
clazz = (Class<T>) types[0];
className = clazz.getSimpleName();//例如:Employee
}
// 容器注入
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
public SessionFactory getSessionFactory() {
return sessionFactory;
}
@Override
public void delete(int id) {
sessionFactory
.getCurrentSession()
.createQuery("delete from " + className + " where id=?")
.setParameter(0, id).executeUpdate();
}
@SuppressWarnings("unchecked")
@Override
public T findById(int id) {
return (T) sessionFactory.getCurrentSession().get(clazz, id);
}
@SuppressWarnings("unchecked")
@Override
public List<T> getAll() {
return sessionFactory.getCurrentSession().createQuery("from " + className).list();
}
@Override
public void save(T t) {
sessionFactory.getCurrentSession().save(t);
}
@Override
public void update(T t) {
sessionFactory.getCurrentSession().update(t);
}
}
public class AdminDao implements IAdminDao {
// IOC容器(依賴)注入SessionFactory物件
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public Admin findByAdmin(Admin admin) {
return (Admin) sessionFactory.getCurrentSession()//
.createQuery("from Admin where adminName=? and pwd=?")//
.setString(0, admin.getAdminName())//
.setString(1, admin.getPwd())//
.uniqueResult();
}
@Override
public void save(Admin admin) {
sessionFactory.getCurrentSession().save(admin);
}
}
public class DeptDao implements IDeptDao {
// 容器注入
private SessionFactory sessionFactory;
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
@Override
public Dept findById(int id) {
return (Dept) sessionFactory.getCurrentSession().get(Dept.class, id);
}
@SuppressWarnings("unchecked")
@Override
public List<Dept> getAll() {
return sessionFactory.getCurrentSession().createQuery("from Dept").list();
}
}
public class EmployeeDao extends BaseDao<Employee> implements IEmployeeDao {
@SuppressWarnings("unchecked")
@Override
public List<Employee> getAll(String employeeName) {
return getSessionFactory().getCurrentSession()//
.createQuery("from Employee where empName like ?")//
.setParameter(0, "%" +employeeName + "%")//
.list();
}
@Override
public Employee findById(int id) {
String hql = "from Employee e left join fetch e.dept where e.id=?";
return (Employee) getSessionFactory()
.getCurrentSession()
.createQuery(hql)
.setParameter(0, id)
.uniqueResult();
}
}
5) Service設計介面
/**
* 管理員業務邏輯層介面
*
*
*
*/
public interface IAdminService {
/**
* 註冊
* @param admin
*/
void register(Admin admin);
/**
* 登陸
* @param admin
* @return
*/
Admin login(Admin admin);
}
/**
* 部門模組業務邏輯層介面
*
*
*/
public interface IDeptService {
/**
* 查詢全部
* @return 返回全部資訊
*/
List<Dept> getAll();
/**
* 根據主鍵查詢
* @param id 主鍵
* @return 返回查詢後的結果
*/
Dept findById(int id);
}
/**
* 員工模組業務邏輯層介面
*
*
*/
public interface IEmployeeService {
/**
* 儲存員工
* @param emp
*/
void save(Employee emp);
/**
* 跟新員工資訊
* @param emp
*/
void update(Employee emp);
/**
* 根據主鍵查詢
* @param id
* @return
*/
Employee findById(int id);
/**
* 查詢全部
* @return
*/
List<Employee> getAll();
/**
* 根據員工名稱條件查詢
* @param employeeName
* @return
*/
List<Employee> getAll(String employeeName);
/**
* 根據主鍵刪除
* @param id
*/
void delete(int id);
/**
* 刪除多個員工
*/
void deleteMany(int[] ids);
}
Service實現
public class AdminService implements IAdminService {
// 注入dao 【這裡一定要用介面接收】
private IAdminDao adminDao; //JDK
public void setAdminDao(IAdminDao adminDao) {
this.adminDao = adminDao;
}
@Override
public Admin login(Admin admin) {
return adminDao.findByAdmin(admin);
}
@Override
public void register(Admin admin) {
adminDao.save(admin);
}
}
public class DeptService implements IDeptService {
private IDeptDao deptDao;
public void setDeptDao(IDeptDao deptDao) {
this.deptDao = deptDao;
}
@Override
public Dept findById(int id) {
return deptDao.findById(id);
}
@Override
public List<Dept> getAll() {
return deptDao.getAll();
}
}
public class EmployeeService implements IEmployeeService {
// 容器注入
private IEmployeeDao employeeDao;
public void setEmployeeDao(IEmployeeDao employeeDao) {
this.employeeDao = employeeDao;
}
@Override
public void delete(int id) {
employeeDao.delete(id);
}
@Override
public void deleteMany(int[] ids) {
if (ids != null && ids.length >0) {
for (int id : ids){
delete(id);
}
}
}
@Override
public Employee findById(int id) {
return employeeDao.findById(id);
}
@Override
public List<Employee> getAll() {
return employeeDao.getAll();
}
@Override
public List<Employee> getAll(String employeeName) {
return employeeDao.getAll(employeeName);
}
@Override
public void save(Employee emp) {
employeeDao.save(emp);
}
@Override
public void update(Employee emp) {
employeeDao.update(emp);
}
}
6) Action設計
/**
* 管理員登陸註冊模組
* 1. 登陸
*
*
*/
public class AdminAction extends ActionSupport implements ModelDriven<Admin> {
// 封裝請求資料
private Admin admin = new Admin();
public void setAdmin(Admin admin) {
this.admin = admin;
}
public Admin getAdmin() {
return admin;
}
@Override
public Admin getModel() {
return admin;
}
// 呼叫Service
private IAdminService adminService;
public void setAdminService(IAdminService adminService) {
this.adminService = adminService;
}
/**
* 登陸
*/
public String login(){
// 登陸驗證
Admin adminInfo = adminService.login(admin);
// 驗證
if (adminInfo == null){
// 登陸失敗
return "loginFaild";
} else {
// 登陸成功, 儲存資料到session
ActionContext.getContext().getSession().put("adminInfo", adminInfo);
return "index";
}
}
}
/**
* 員工模組控制器開發:
* 1. 員工列表展示
* 2. 新增員工
* 3. 修改員工資訊
* 5. 刪除
*
*
*/
public class EmployeeAction extends ActionSupport implements ModelDriven<Employee>, RequestAware{
/*******一、封裝資料********/
private Employee employee = new Employee(); // 【模型驅動】
// 封裝請求的部門id(下拉列表的實際的值)
private int deptId;
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Employee getEmployee() {
return employee;
}
public void setDeptId(int deptId) {
this.deptId = deptId;
}
public int getDeptId() {
return deptId;
}
@Override
public Employee getModel() {
return employee; // 返回例項化後的物件
}
/*******二、注入員工Service********/
private IEmployeeService employeeService;
public void setEmployeeService(IEmployeeService employeeService) {
this.employeeService = employeeService;
}
// 部門Service
private IDeptService deptService;
public void setDeptService(IDeptService deptService) {
this.deptService = deptService;
}
/**
* 1. 員工列表展示
*/
public String list() {
// 查詢所有員工
List<Employee> listEmp = employeeService.getAll();
// 儲存到request
request.put("listEmp", listEmp);
return "list";
}
/**
* 2. 新增員工 - 進入新增頁面
*/
public String viewAdd(){
// 查詢所有部門資訊, 儲存到request
List<Dept> listDept = deptService.getAll();
request.put("listDept", listDept);
return "add";
}
/**
* 2. 新增員工 - 新增員工資料
*/
public String save(){
// 先根據部門主鍵查詢
Dept dept = deptService.findById(deptId);
// 設定到員工物件中
employee.setDept(dept);
// 呼叫Service,儲存員工
employeeService.save(employee);
return "listAction"; // 重定向到Action
}
/**
* 3. 修改員工資訊 - 進入修改檢視
*/
public String viewUpdate(){
// 獲取要修改的記錄的id
int id = employee.getId();
// 1. 根據員工的主鍵查詢 (lazy="false")
Employee emp = employeeService.findById(id); // 已經有部門資訊
// 2. 查詢所有的部門
List<Dept> listDept = deptService.getAll();
// 資料回顯
ValueStack vs = ActionContext.getContext().getValueStack();
vs.pop();// 移除棧頂元素
vs.push(emp); // 入棧
// 儲存
request.put("listDept", listDept);
return "edit";
}
/**
* 4. 修改員工資訊 - 確認修改
*/
public String update() {
//1. 先根據部門id, 查詢部門物件; 再設定到員工屬性中
Dept dept = deptService.findById(deptId);
employee.setDept(dept);
//2. 更新員工
employeeService.update(employee);
return "listAction"; // 重定向到列表
}
/**
* 5. 修改員工資訊 - 刪除
*/
public String delete(){
// 獲取要刪除員工的主鍵
int empId = employee.getId();
// 呼叫service刪除
employeeService.delete(empId);
return "listAction";
}
// 接收框架執行時候傳入的代表request物件的map
private Map<String, Object> request;
@Override
public void setRequest(Map<String, Object> request) {
this.request = request;
}
}
7)攔截器
/**
* 效驗使用者是否登陸,只有登陸後才可以進行操作。
* 沒有登陸,只能檢視列表,不能操作!
*
*
*/
public class UserInterceptor extends AbstractInterceptor {
@Override
public String intercept(ActionInvocation invocation) throws Exception {
// 得到當前執行的方法
String methodName = invocation.getProxy().getMethod();
// 得到ActionContext物件
ActionContext ac = invocation.getInvocationContext();
// 獲取session, 從session中獲取登陸的管理員賬號
Object obj = ac.getSession().get("adminInfo");
// 判斷:
if (!"login".equals(methodName) && !"list".equals(methodName)){
// 驗證
if (obj == null){
// 沒有登陸
return "login";
} else {
// 執行Action
return invocation.invoke();
}
} else {
// 允許訪問登陸、列表展示
return invocation.invoke();
}
}
}
配置檔案 bean.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 引入其他配置檔案 -->
<import resource="config/bean-base.xml"/>
<import resource="config/bean-dao.xml"/>
<import resource="config/bean-service.xml"/>
<import resource="config/bean-action.xml"/>
</beans
struts.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="emp" extends="struts-default">
<!-- 攔截器配置 -->
<interceptors>
<interceptor name="userInterceptor" class="cn.itcast.action.UserInterceptor"></interceptor>
<interceptor-stack name="myStack">
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="userInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 執行指定的攔截器 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<!-- 全域性檢視 -->
<global-results>
<result name="success">/index.jsp</result>
<result name="login" type="redirect">/login.jsp</result>
<!-- 錯誤檢視配置 -->
<result name="null">/error/null.jsp</result>
<result name="error">/error/error.jsp</result>
</global-results>
<!-- 全域性異常 -->
<global-exception-mappings>
<!-- result 會取找全域性檢視的名稱 -->
<exception-mapping result="null" exception="java.lang.NullPointerException"></exception-mapping>
<exception-mapping result="error" exception="java.lang.Exception"></exception-mapping>
</global-exception-mappings>
<!-- Ation例項交給spring容器建立 -->
<!-- 員工Action -->
<action name="emp_*" class="employeeAction" method="{1}">
<!-- 列表展示 -->
<result name="list">/WEB-INF/list.jsp</result>
<!-- 進入新增頁面檢視 -->
<result name="add">/WEB-INF/add.jsp</result>
<!-- 新增成功,進入列表 (防止重新整理就多一條記錄問題,所以用重定向) -->
<result name="listAction" type="redirectAction">emp_list</result>
<!-- 進入修改頁面 -->
<result name="edit">/WEB-INF/edit.jsp</result>
</action>
<!-- 管理員Action -->
<action name="admin_*" class="adminAction" method="{1}">
<!-- 登陸失敗 -->
<result name="loginFaild">/login.jsp</result>
<!-- 登陸成功 -->
<result name="index" type="redirectAction">emp_list</result>
</action>
</package>
</struts>
8)config配置檔案
bean-base.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 1. 連線池例項 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/hib_demo"></property>
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
<property name="initialPoolSize" value="3"></property>
<property name="maxPoolSize" value="6"></property>
</bean>
<!-- 2. Spring管理SessionFactory 【全部配置都寫到spring中】 -->
<!-- # 注入DataSource、 注入常用配置屬性、對映配置屬性 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="mappingLocations">
<list>
<value>classpath:cn/itcast/entity/*.hbm.xml</value>
</list>
</property>
</bean>
<!-- 3. 事務相關配置 -->
<!-- 3.1 事務管理器類 -->
<bean id="txManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
<!-- 3.2 事務增強(如何管理事務)-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="*" read-only="false"/>
</tx:attributes>
</tx:advice>
<!-- 3.3 Aop配置 = 切入點表示式(攔截目標物件,生成代理) + 事務增強應用-->
<aop:config>
<aop:pointcut expression="execution(* cn.itcast.service.impl.*.*(..))" id="pt"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="pt"/>
</aop:config>
</beans>
bean-dao.xml
<?xml version="1.0" encoding=