一、 导入SSH的jar包,包括整合包。
PS:convention-plugin包是struts2提供的注解插件。
struts2-spring-plugin包是struts提供的与spring整合的用于注解的包,用于简化在struts2框架中使用spring的插件。
二、spring.xml的配置:
- 配置一个c3p0数据源(其实可以将这些属性写人一个properties文件中)
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql:///spring?characterEncoding=utf-8"></property>
<property name="user" value="root"></property>
<property name="password" value="root"></property>
</bean>
复制代码
- 给IOC注入一个SessionFactory对象:
<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<!-- 需要一个DataSource -->
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 配置文件映射的方式 -->
<!-- 使用注解的方式,可以直接使用包的扫描 -->
<property name="packagesToScan">
<list>
<value>cn.eduask.domain</value>
</list>
</property>
</bean>
复制代码
- 配置事务管理器:
<!-- 配置事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
<!-- 需要一个SessionFactory -->
<property name="sessionFactory" ref="sessionFactory"></property>
</bean>
复制代码
- 重点:开启事务的注解驱动:
<!-- 开启事务注解,需要一个事务管理器 -->
<tx:annotation-driven transaction-manager="transactionManager"/>
复制代码
- 重点:开启注解扫描
<!-- 扫描注解 -->
<context:component-scan base-package="cn.eduask"/>
复制代码
三、注解
实体类:
@Entity
@Table(name="t_customer")
public class Customer implements Serializable{
@Id //JPA java 持久化 API
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="cust_id")
private Long id ;
@Column(name="cust_name")
private String custName;
@Column(name="cust_phone")
private String custPhone;
@Column(name="cust_address")
private String custAddress;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getCustPhone() {
return custPhone;
}
public void setCustPhone(String custPhone) {
this.custPhone = custPhone;
}
public String getCustAddress() {
return custAddress;
}
public void setCustAddress(String custAddress) {
this.custAddress = custAddress;
}
}
复制代码
- 使用JavaEE提供的标准持久化注解
- @Entity:将类注解为实体类
- @Table:指定实体类应的表名,name属性是指定表名。
- @Id:指定该变量为主键
- @GeneratedValue(strategy=GenerationType.IDENTITY):指定该变量在表中的主键策略。
- @Column(name="cust_id"):对应表的字段名
Action层:
@Controller
@Scope(value="prototype")
@ParentPackage(value="struts-default")
@Namespace(value="/customer")
public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{
private Customer customer = new Customer();
@Override
public Customer getModel() {
return customer;
}
/* 开发中推荐使用。使用spring來管理action對象 */
@Resource
private CustomerService custService;
@Action(value="save",results={@Result(name="success",location="/success.jsp")})
public String save() throws Exception {
custService.save(customer);
return SUCCESS;
}
}
复制代码
- @Controller:使用spring的注解,将对应的action注解为控制层,放入IOC容器中。
- @Scope(value="prototype"):action必须是多例的。
- @ParentPackage(value="struts-default"):代表这个action类继承的哪个拦截器栈,目前是默认的。
- @Namespace(value="/customer"):action对应的命名空间。
- @Resource:从IOC容器中注入对象的注解。拥有自动注入和指定名称注入的功能,由JavaEE提供。
- @Action:将action类中对应的方法注解为请求方法,value属性>对应的action的name;results>值为@Result数组,可以定义多个@Result;
- @Result:action方法的返回结果。对应xml文件中的节点。属性name>result类型;location>返回的视图路径。
service层的注解:
@Service
@Transactional
public class CustomerServiceImpl implements CustomerService {
@Resource
private CustomerDao custDao;
@Override
public void save(Customer cust) {
custDao.save(cust);
}
}
复制代码
- @Service:spring提供的注解,用于区分不同层次,代表这个类是serivce层,将service放入IOC容器中。
- @Transactional:开启事务注解驱动后,此注解便可以定义在类上,代表将这个类的所以方法纳入事务范围。也可以注解在方法上,代表这个方法是被事务控制。
DAO层:
@Repository
public class CustomerDaoImpl extends HibernateDaoSupport implements CustomerDao {
@Resource
public void backHibernateTemplate(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}
@Override
public void save(Customer cust) {
this.getHibernateTemplate().save(cust);
}
}
复制代码
- @Repository:spring提供的注解,用于区分不同层次,代表这个类是持久层,将对应对象放入IOC容器中。
- 这里有个小技巧:由于spring中将HibernateTemplate的配置舍去,就造成无法获得HibernateTemplate的对象,从而使用hibernate的CURD方法,因此,从源码可以看出:
public abstract class HibernateDaoSupport extends DaoSupport {
/**
* Set the Hibernate SessionFactory to be used by this DAO.
* Will automatically create a HibernateTemplate for the given SessionFactory.
* @see #createHibernateTemplate
* @see #setHibernateTemplate
*/
public final void setSessionFactory(SessionFactory sessionFactory) {
//判断hibernateTemplate是否为空,并且当前线程的对象是否相等
//如果对象不相等,获取是空,那么就调用createHibernateTemplate(sessionFactory);方法,
//创建一个hibernateTemplate,并将对象赋值给这个类的hibernateTemplate属性。
if (this.hibernateTemplate == null || sessionFactory != this.hibernateTemplate.getSessionFactory()) {
this.hibernateTemplate = createHibernateTemplate(sessionFactory);
}
}
}
复制代码
所以spring给了我们一个解决方案,通过继承HibernateDaoSupport类并调用父类的setSessionFactory(sessionFactory);方法,注入一个SessionFactory就可以得到HibernateTemplate对象。