在SSH(Struts2+Spring+Hibernate)框架中,Action层作为业务逻辑控制的核心,常需要获取页面的数据库操作结果或数据,以下是几种常见实现方式及详细说明:
通过Service层间接获取数据
Action层通常不直接操作数据库,而是通过调用Service层方法实现数据交互,Spring框架通过依赖注入(DI)为Action提供Service实例,Service层再调用DAO层完成数据库操作。
实现步骤:
- 配置Spring注入:在Spring配置文件中声明Service和Action的Bean,通过
<property>
注入Service实例。 - Service层方法设计:在Service接口中定义业务方法,如
List<User> getAllUsers()
,实现类中调用DAO方法。 - Action调用Service:Action通过注入的Service调用业务方法,获取数据后存入值栈(ValueStack)。
示例代码:
// Action层 public class UserAction extends ActionSupport { @Autowired private UserService userService; private List<User> userList; public String listUsers() { userList = userService.findAll(); // 调用Service获取数据 return SUCCESS; } // Getter/Setter }
直接注入DAO层(不推荐)
对于简单场景,Action可直接注入DAO层,但违反了分层原则,可能导致代码耦合度高。
示例:
public class UserAction { @Autowired private UserDao userDao; public String execute() { userList = userDao.getAllUsers(); // 直接调用DAO return SUCCESS; } }
使用Hibernate Session(需谨慎)
若Action必须直接操作数据库,可通过Hibernate Session实现,但需确保事务管理正确。
步骤:
- 获取Session:通过
SessionFactory
或HibernateUtil
类获取当前线程绑定的Session。 - 执行查询:使用HQL或Criteria API查询数据。
- 关闭资源:确保Session在操作后关闭。
示例:
public class UserAction { private SessionFactory sessionFactory; public String listUsers() { Session session = sessionFactory.getCurrentSession(); userList = session.createQuery("FROM User").list(); return SUCCESS; } }
通过Struts2拦截器传递数据
利用Struts2的拦截器机制,在请求处理前将数据库查询结果存入值栈,Action层直接读取。
配置示例:
<interceptors> <interceptor name="dataInterceptor" class="com.interceptor.DataInterceptor"/> </interceptors>
分页查询数据获取
若涉及分页,Action需接收页面参数(如页码、每页数量),传递给Service层处理。
参数传递方式:
| 参数类型 | 获取方式 | 适用场景 |
|—————-|———————————–|————————|
| URL参数 | request.getParameter("page")
| GET请求分页 |
| 表单提交 | modelDriven
或属性封装 | POST请求表单提交 |
| Struts2标签 | <s:param name="page" value="1"/>
| 标签库传递参数 |
分页Action示例:
public class UserAction extends ActionSupport implements ModelDriven<User> { private User user = new User(); private int page = 1; private int pageSize = 10; public String list() { PageResult<User> result = userService.findPage(user, page, pageSize); // 存入值栈 return SUCCESS; } // Getter/Setter }
注意事项
- 事务管理:确保Service层方法添加
@Transactional
注解,避免数据不一致。 - 异常处理:在Action层捕获Service抛出的异常,返回错误页面。
- 性能优化:避免N+1查询问题,使用Hibernate的
fetch
属性或JOIN语句优化。
相关问答FAQs
Q1:Action层如何获取数据库连接池配置?
A1:在Spring配置文件中定义数据源(如DataSource
),并通过@Autowired
注入到Service或DAO层,Action层无需直接获取连接池,由Spring管理依赖注入即可。
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test"/> </bean>
Q2:为什么Action层不建议直接操作数据库?
A2:直接操作数据库会导致以下问题:
- 违反分层原则:Action层应专注于请求响应,业务逻辑应交由Service层处理。
- 事务管理困难:Service层可通过Spring声明式事务管理,而Action层手动控制事务易出错。
- 代码复用性差:数据库操作逻辑分散在Action中,难以复用和维护。
- 测试复杂度增加:Action层直接依赖数据库,单元测试时需模拟数据库环境。
【版权声明】:本站所有内容均来自网络,若无意侵犯到您的权利,请及时与我们联系将尽快删除相关内容!
发表回复