一,概述
1)终于将Struts与Hibernate学习完了,现在就同时在一个web项目中完成一个简单小案例的开发!
2)在前面博客中已经介绍了怎样导入项目必须的jar包及环境的配置,就不再赘述,直接进入主题吧!
二,开发
1)实体及映射文件准备
a)Dept.java(限制篇幅,setter和getter方法省略,下面也是一样)
package com.bighuan.entity;
import java.util.HashSet;
import java.util.Set;
/**
* 部门表对应的实体类
* @author bighuan
*
*/
public class Dept {
private int deptId;
private String deptName;
// 【一对多】 部门对应的多个员工
private Set<Employee> emps = new HashSet<Employee>();
public Dept() {
}
public Dept(int deptId, String deptName) {
this.deptId = deptId;
this.deptName = deptName;
}
}
b)Dept.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bighuan.entity"
auto-import="true">
<class name="Dept" table="t_dept">
<id name="deptId">
<generator class="native"></generator>
</id>
<property name="deptName" length="20"></property>
<set name="emps">
<key column="dept_id"></key>
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>
c)Employee.java
package com.bighuan.entity;
/**
* 员工表对应的实体类
* @author bighuan
*
*/
public class Employee {
private int empId;
private String empName;
private double salary;
// 【多对一】员工与部门
private Dept dept;
public Employee(){
}
}
d)Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.bighuan.entity">
<class name="Employee" table="t_employee">
<id name="empId">
<generator class="native"></generator>
</id>
<property name="empName" length="20"></property>
<property name="salary" type="double"></property>
<many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
</class>
</hibernate-mapping>
2)dao层开发
package com.bighuan.dao;
import com.bighuan.entity.Dept;
import com.bighuan.utils.HibernateUtils;
public class DeptDao {
/**
* 主键查询
* @param id
* @return
*/
public Dept findById(int id){
//获取session
return (Dept) HibernateUtils.getSession().get(Dept.class, id);
}
}
3)service层开发
package com.bighuan.service;
import com.bighuan.dao.DeptDao;
import com.bighuan.entity.Dept;
import com.bighuan.utils.HibernateUtils;
public class DeptService {
//调用dao
private DeptDao dao=new DeptDao();
/**
* 主键查询
* @param id
* @return
*/
public Dept findById(int id){
//获取session
return dao.findById(id);
}
}
4)HibernateUtils工具类准备
package com.bighuan.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtils {
//初始化SessionFactory
private static SessionFactory sf;
static{
sf=new Configuration().configure().buildSessionFactory();
}
/**
* 创建(获取)session
* @return
*/
public static Session getSession(){
//1,线程的方式创建session,必须要进行配置;
//2,不用关闭,会自动关闭
return sf.getCurrentSession();
}
}
注意:通过线程方式获取session必须要在hibernate.cfg.xml中配置
5)Action开发
Action中主要就是通过主键查询一条数据,保存到request域中
package com.bighuan.action;
import com.bighuan.entity.Dept;
import com.bighuan.service.DeptService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DeptAction extends ActionSupport{
private DeptService service=new DeptService();
@Override
public String execute() throws Exception {
//主键查询,模拟数据
Dept dept = service.findById(11);
//保存到request域中
ActionContext.getContext().getContextMap().put("dept", dept);
return SUCCESS;
}
}
6)session拦截器
package com.bighuan.interceptor;
import org.hibernate.Session;
import com.bighuan.utils.HibernateUtils;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
/**
* Session管理拦截器
* 当访问Action的时候,创建session
* action->service->dao,获取的是这里创建的session
* @author bighuan
*
*/
public class SessionInterceptor extends AbstractInterceptor{
@Override
public String intercept(ActionInvocation invocation) throws Exception {
try {
//1,先创建session
Session session=HibernateUtils.getSession();
//2,开启事务
session.beginTransaction();
//3,执行action
String result = invocation.invoke();
//4,提交事务
session.getTransaction().commit();//不需要关闭session
//5,返回结果视图
return result;
} catch (Exception e) {
e.printStackTrace();
return "error";
}
}
}
7)hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<!-- 通常,一个session-factory节点代表一个数据库 -->
<session-factory>
<!-- 1. 数据库连接配置 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql:///hib_demo</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">abc</property>
<!--
数据库方法配置, hibernate在运行的时候,会根据不同的方言生成符合当前数据库语法的sql
-->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 2. 其他相关配置 -->
<!-- 2.1 显示hibernate在运行时候执行的sql语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 2.2 格式化sql
<property name="hibernate.format_sql">true</property> -->
<!-- 2.3 自动建表 -->
<property name="hibernate.hbm2ddl.auto">update</property>
<!-- session的创建方式 -->
<property name="hibernate.current_session_context_class">thread</property>
<!-- *********连接池配置*********** -->
<!-- 配置连接池驱动管理类 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<!-- 配置连接池参数信息 -->
<property name="hibernate.c3p0.max_size">5</property> <!-- 最大连接数 -->
<property name="hibernate.c3p0.min_size">2</property> <!-- 最小连接数 -->
<property name="hibernate.c3p0.timeout">5000</property> <!-- 超时时间 -->
<property name="hibernate.c3p0.max_statements">100</property> <!-- 最大执行的命令格个数 -->
<property name="hibernate.c3p0.idle_test_period">30000</property> <!-- 空闲测试时间 -->
<property name="hibernate.c3p0.acquire_increment">2</property> <!-- 连接不够用时,每次增加的个数 -->
<!-- 3. 加载所有映射 -->
<mapping resource="com/bighuan/entity/Dept.hbm.xml"/>
<mapping resource="com/bighuan/entity/Employee.hbm.xml"/>
</session-factory>
</hibernate-configuration>
8)struts.xml
a)配置拦截器,action返回"success"就跳转到index.jsp,并显示数据!
b)代码
<?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>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<package name="dept" extends="struts-default">
<!-- 拦截器配置 -->
<interceptors>
<interceptor name="sessionInterceptor" class="com.bighuan.interceptor.SessionInterceptor"></interceptor>
<interceptor-stack name="myStack">
<!-- 默认拦截器栈 -->
<interceptor-ref name="defaultStack"></interceptor-ref>
<interceptor-ref name="sessionInterceptor"></interceptor-ref>
</interceptor-stack>
</interceptors>
<!-- 使用拦截器 -->
<default-interceptor-ref name="myStack"></default-interceptor-ref>
<!-- 配置action -->
<action name="show" class="com.bighuan.action.DeptAction"
method="execute">
<!-- type默认就是dispatcher -->
<result name="success" type="dispatcher">/index.jsp</result>
</action>
</package>
<!-- Add packages here -->
</struts>
c)为了使用struts的核心功能,在web.xml中记得配置strtus的核心过滤器.
<!-- 引入struts2核心过滤器 -->
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
9)显示数据
a)引入struts标签:<%@ taglib uri="/struts-tags" prefix="s" %>
b)显示数据:
<body>
<h3>部门:<s:property value="#request.dept.deptName"></s:property></h3>
<!-- 部门下的员工:(懒加载数据) -->
<table border="1" align="center" cellpadding="5" cellspacing="0" width="55%">
<tr>
<th>员工编号</th>
<th>员工姓名</th>
<th>薪水</th>
</tr>
<s:if test="#request.dept.emps != null">
<s:iterator var="emp" value="#request.dept.emps">
<tr>
<td><s:property value="#emp.empId" /></td>
<td><s:property value="#emp.empName" /></td>
<td><s:property value="#emp.salary" /></td>
</tr>
</s:iterator>
</s:if>
<s:else>
<tr><td colspan="3">没有员工信息!</td></tr>
</s:else>
</table>
</body>
c)访问action,效果图: