SSH框架之Spring+Struts2+Hibernate整合篇
程序员文章站
2022-06-19 10:33:41
回顾 -Hibernate框架 ORM: 对象关系映射.把数据库表和JavaBean通过映射的配置文件映射起来, 操作JavaBean对象,通过映射的配置文件生成SQL语句,自动执行.操作数据库. 1: 类名.hbm.xml 映射配置文件. 2: hibernate.cfg.xml 核心配置文件. ... ......
回顾 -hibernate框架 orm: 对象关系映射.把数据库表和javabean通过映射的配置文件映射起来, 操作javabean对象,通过映射的配置文件生成sql语句,自动执行.操作数据库. 1: 类名.hbm.xml 映射配置文件. 2: hibernate.cfg.xml 核心配置文件. 3: 使用hibernate提供的api操作. struts2框架 : 和客户端进行交互 1. 在web.xml配置过滤器. 2. struts.xml配置文件. spring框架 1. applicationcontext.xml配置 2. 核心ioc和aop 3. 事务管理. customeraction类 在struts.xml配置中配置的 1. action对象由struts2框架创建的. customeraction:创建customeraction对象,由struts2框架创建的 ---> spring的ioc容器中对象,找customerservice对象,默认按名称找的. 2. action对象也可以由spring框架类创建 <bean id="customeraction" class="com.baidu.customer.action.customeraction" scope="prototype"> <property name="customerservice" ref="customerservice"/> </bean> <action name="customeraction_*" class="customeraction" method="{1}"> <result name="initsave">/jsp/customer/add.jsp</result> </action> day67_spring_05 第1章整合前的准备 1.1整合说明 a.独立式整合指的是三个框架都使用自己的配置文件。 b.引入式整合指的是hibernate主配置文件中的内容都配置到spring配置文件中 c.在整合过程中,确保每步都运行成功,然后在继续往下做。 d.整合中使用的案例是客户的保存和列表查询操作。 e.后面的三种整合方式都基于1.2中的环境准备。 1.2环境准备 1.2.1第一步:创建java web工程 此处使用servlet2.5规范。 1.2.2第二步:创建数据库和表结构 create database crm; use crm; /*创建客户表*/ create table `cst_customer` ( `cust_id` bigint(32) not null auto_increment comment '客户编号(主键)', `cust_name` varchar(32) not null comment '客户名称(公司名称)', `cust_source` varchar(32) default null comment '客户信息来源', `cust_industry` varchar(32) default null comment '客户所属行业', `cust_level` varchar(32) default null comment '客户级别', `cust_address` varchar(128) default null comment '客户联系地址', `cust_phone` varchar(64) default null comment '客户联系电话', primary key (`cust_id`) ) engine=innodb auto_increment=1 default charset=utf8; 1.2.3第三步:编写实体类 /** * 客户的实体类(数据模型) */ public class customer implements serializable { private long custid; private string custname; private string custsource; private string custindustry; private string custlevel; private string custaddress; private string custphone; public long getcustid() { return custid; } public void setcustid(long custid) { this.custid = custid; } public string getcustname() { return custname; } public void setcustname(string custname) { this.custname = custname; } public string getcustsource() { return custsource; } public void setcustsource(string custsource) { this.custsource = custsource; } public string getcustindustry() { return custindustry; } public void setcustindustry(string custindustry) { this.custindustry = custindustry; } public string getcustlevel() { return custlevel; } public void setcustlevel(string custlevel) { this.custlevel = custlevel; } public string getcustaddress() { return custaddress; } public void setcustaddress(string custaddress) { this.custaddress = custaddress; } public string getcustphone() { return custphone; } public void setcustphone(string custphone) { this.custphone = custphone; } @override public string tostring() { return "customer [custid=" + custid + ", custname=" + custname + ", custsource=" + custsource + ", custindustry=" + custindustry + ", custlevel=" + custlevel + ", custaddress=" + custaddress + ", custphone=" + custphone + "]"; } } 1.2.4第四步:编写业务层接口和实现类 /** * 客户的业务层接口 */ public interface icustomerservice { /** * 查询所有客户 * @return */ list<customer> findallcustomer(); /** * @param customer */ void savecustomer(customer customer); } /** * 客户的业务层实现类 */ public class customerserviceimpl implements icustomerservice { private icustomerdao customerdao; public void setcustomerdao(icustomerdao customerdao) { this.customerdao = customerdao; } @override public list<customer> findallcustomer() { return customerdao.findallcustomer(); } @override public void savecustomer(customer customer) { customerdao.savecustomer(customer); } } 1.2.5第六步:创建持久层接口 /** * 客户的持久层接口 */ public interface icustomerdao { /** * 查询所有客户 * @return */ list<customer> findallcustomer(); /** * 保存客户 * @param customer */ void savecustomer(customer customer); } 注意:做上述操作时,并不需要导入任何jar包。 第2章基于xml的独立式整合 2.1保证spring框架在web工程中独立运行 2.1.1第一步:拷贝spring的ioc,aop和事务控制三组jar包 2.1.2第二步:编写spring配置文件并导入约束 <?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> </beans> 2.1.3第三步:把业务层和持久层配置到文件中 <!-- 把资源交给spring来管理 --> <!-- 配置dao --> <bean id="customerdao" class="com.baidu.dao.impl.customerdaoimpl"></bean> <!-- 配置service --> <bean id="customerservice" class="com.baidu.service.impl.customerserviceimpl"> <!-- 注入dao --> <property name="customerdao" ref="customerdao"></property> </bean> 持久层实现类代码: 此时不要做任何操作,就输出一句话。目的是测试spring框架搭建的结果。 /** * 客户的持久层实现类 */ public class customerdaoimpl implements icustomerdao { @override public list<customer> findallcustomer() { system.out.println("查询了所有用户"); return null; } @override public void savecustomer(customer customer) { system.out.println("保存了用户"); } } 2.1.4第四步:测试spring能否独立运行 /** * 测试类,测试spring框架可以独立运行 */ public class spring01test { public static void main(string[] args) { //1.获取spring容器 applicationcontext ac = new classpathxmlapplicationcontext("bean.xml"); //2.跟id获取bean对象 icustomerservice customerservice = (icustomerservice) ac.getbean("customerservice"); customerservice.findallcustomer(); } } 2.2保证hibernate框架能够在web工程中独立运行 2.2.1第一步:拷贝hibernate必备jar包到工程的lib目录 2.2.2第二步:编写实体类的映射文件 <?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="com.baidu.domain"> <class name="customer" table="cst_customer"> <id name="custid" column="cust_id"> <generator class="native"></generator> </id> <property name="custname" column="cust_name"></property> <property name="custsource" column="cust_source"></property> <property name="custindustry" column="cust_industry"></property> <property name="custlevel" column="cust_level"></property> <property name="custaddress" column="cust_address"></property> <property name="custphone" column="cust_phone"></property> </class> </hibernate-mapping> 2.2.3第三步:编写hibernate主配置文件 <?xml version="1.0" encoding="utf-8"?> <!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> <!-- 1.连接数据库的信息 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.driver</property> <property name="hibernate.connection.url">jdbc:mysql:///crmroperty> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">1234</property> <!-- 2.hibernate的基本配置 --> <!-- 数据库的方言--> <property name="hibernate.dialect">org.hibernate.dialect.mysqldialect</property> <!-- 是否显示sql语句--> <property name="hibernate.show_sql">true</property> <!-- 是否格式化sql语句--> <property name="hibernate.format_sql">false</property> <!-- 采用何种方式生成数据库表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置使用c3p0数据源 --> <property name="hibernate.connection.provider_class">org.hibernate.connection.c3p0connectionprovider</property> <!--把session绑定到当前线程上的配置--> <property name="hibernate.current_session_context_class">thread</property> <!-- 3.映射文件的位置 --> <mapping resource="com/baidu/domain/customer.hbm.xml"/> </session-factory> </hibernate-configuration> 2.2.4第四步:编写测试类-测试保存客户 /** * hibernate的测试类 * 保证hibernate框架可以独立运行 */ public class hibernate02test { @test public void testfindall(){ //1.读取配置文件 configuration cfg = new configuration(); cfg.configure(); //2.根据配置文件获取sessionfactory sessionfactory factory = cfg.buildsessionfactory(); //3.根据sessionfactory获取一个session session s = factory.getcurrentsession(); //4.开启事务 transaction tx = s.begintransaction(); //5.执行操作 query query = s.createquery("from customer"); list list = query.list(); for(object o : list){ system.out.println(o); } //6.提交事务 tx.commit(); //7.释放资源 factory.close(); } @test public void testsave(){ customer c = new customer(); c.setcustname("传智专修学院"); //1.读取配置文件 configuration cfg = new configuration(); cfg.configure(); //2.根据配置文件获取sessionfactory sessionfactory factory = cfg.buildsessionfactory(); //3.根据sessionfactory获取一个session session s = factory.getcurrentsession(); //4.开启事务 transaction tx = s.begintransaction(); //5.执行操作 s.save(c); //6.提交事务 tx.commit(); //7.释放资源 factory.close(); } } 2.3整合spring和hibernate框架 2.3.1明确 a.spring和hibernate的整合就是spring接管sessionfactory的创建 b.spring针对hiberante的操作有一个封装的对象hibernatetemplate c.和jdbctemplate一样,hibernatetemplate也有一个hibernatedaosupport d.hibernatetemplate和hibernatedaosupport都在spring-orm-4.2.4.release.jar中 e.我们dao采用继承hiberantedaosupport的方式编写,它一样不能用于注解配置。 2.3.2整合步骤 2.3.2.1第一步:在spring配置文件中配置sessionfactory <!-- 配置sessionfactory --> <bean id="sessionfactory" class="org.springframework.orm.hibernate5.localsessionfactorybean"> <!-- 使用的是hibernate主配置文件中的内容,我们只需要指定hibernate主配置文件的所在位置 --> <property name="configlocation" value="classpath:hibernate.cfg.xml"/> </bean> 2.3.2.2第二步:改造dao继承hibernatedaosupport /** * 客户的持久层实现类 */ public class customerdaoimpl extends hibernatedaosupport implements icustomerdao { @override public list<customer> findallcustomer() { return (list<customer>) gethibernatetemplate().find("from customer"); } @override public void savecustomer(customer customer) { gethibernatetemplate().save(customer); } } 2.3.2.3第三步:在spring配置文件中给dao注入sessionfactory <!-- 配置dao --> <bean id="customerdao" class="com.baidu.dao.impl.customerdaoimpl"> <property name="sessionfactory" ref="sessionfactory"></property> </bean> 2.3.2.4第四步:测试 /** * 整合spring和hibernate的测试类 * spring整合junit * 第一步:拷贝jar包 * spring-junit-4.2.4.jar * 第二步:使用注解替换运行器(原来junit的main方法) * @runwith(支持spring的main方法) * @contextconfiguration(指定spring的配置文件位置) */ @runwith(springjunit4classrunner.class) @contextconfiguration(locations={"classpath:bean.xml"}) public class springhibernate03test { @autowired private icustomerservice customerservice; @test public void testfindall(){ list list = customerservice.findallcustomer(); for(object o : list){ system.out.println(o); } } @test public void testsave(){ customer c = new customer(); c.setcustname("传智学院test"); customerservice.savecustomer(c); } } 测试结果: 无论保存还是查询都运行失败! 按常理来说,我们没有配置事务,保存失败是可以理解的。为什么查询也会失败呢? 分析原因: 是由于spring的hibernatetemplate对象在使用session时,spring创建了session的代理对象,在这个过程中,spring对hibernate绑定session到当前线程的配置不认识了,所以运行失败。 2.3.2.5第五步:修改把session绑定到当前线程上 <!-- 是hibernate把session绑定到当前线程上的配置 <property name="hibernate.current_session_context_class">thread</property>--> <!-- 是spring把sesion绑定到当前线程上的配置 --> <property name="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.springsessioncontext </property> 此时再运行刚才的测试: 查询可以使用了。保存不能使用,原因是没有事务。 2.3.3配置spring的事务 2.3.3.1第一步:配置事务管理器并注入sessionfactory <!-- 配置事务管理器 --> <bean id="transactionmanager" class="org.springframework.orm.hibernate5.hibernatetransactionmanager"> <!-- 注入sessionfactory --> <property name="sessionfactory" ref="sessionfactory"></property> </bean> 2.3.3.2第二步:配置事务的通知及通知的属性 <!-- 配置事务的通知 --> <tx:advice id="txadvice" transaction-manager="transactionmanager"> <!-- 配置事务的属性 --> <tx:attributes> <tx:method name="*" read-only="false" propagation="required"/> <tx:method name="find*" read-only="true" propagation="supports"/> </tx:attributes> </tx:advice> 2.3.3.3第三步:配置aop建立切入点表达式和事务通知的关系 <!-- 配置aop --> <aop:config> <!-- 配置通用切入点表达式 --> <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/> <!-- 建立事务通知和切入点表达式的对应关系 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pt1"/> </aop:config> 再次测试: 此时保存和查询都可以正常使用了。 2.4保证struts2框架能够在web工程中独立运行 2.4.1第一步:拷贝struts2的必备jar包 要把画红线的jar包删掉,因为hibernate中有个高版本的。 2.4.2第二步:在类的类的根路径下编写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> <!-- 开启开发者模式 --> <constant name="struts.devmode" value="true"></constant> </struts> 2.4.3第三步:在web.xml中配置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> 2.4.4第四步:导入jsp页面 2.4.5第五步:修改menu.jsp <a class=style2 href="${pagecontext.request.contextpath}/customer/adduicustomer.action" target=main> - 新增客户 </a> 2.4.6第六步:在struts.xml中配置action <!-- 获取添加客户页面 --> <action name="adduicustomer" class="com.baidu.web.action.customeraction" method="adduicustomer"> <result name="adduicustomer">/jsp/customer/add.jsp</result> </action> 2.4.7第七步:编写动作类和方法 /** * 客户的动作类 */ public class customeraction extends actionsupport implements modeldriven<customer> { private customer customer = new customer(); @override public customer getmodel() { return customer; } /** * 获取添加客户页面 * @return */ public string adduicustomer(){ return "adduicustomer"; } } 2.4.8第八步:测试 运行结果:通过点击【新增客户】可以跳转到客户添加页面 2.5整合spring和struts2 2.5.1明确 a.spring整合struts2就是让spring接管action的创建 b.action是多例的,配置到spring中需要设置scope属性为多例 2.5.2整合步骤 2.5.2.1第一步:拷贝struts2-spring-plugin-2.3.24.jar到lib目录 2.5.2.2第二步:在action中使用构造函数获取service对象 public customeraction(){ applicationcontext ac = webapplicationcontextutils.getwebapplicationcontext( servletactioncontext.getservletcontext()); //由于动作类是多例的,每次都会创建容器,导致资源的浪费。一个应用应该只有一个容器 system.out.println(ac); customerservice = (icustomerservice) ac.getbean("customerservice"); } 2.5.2.3第三步:测试 运行结果:查询客户列表测试通过。保存测试通过。 2.6优化配置 2.6.1配置spring的监听器 在上面2.5.2.2小节中有这么一句: 由于动作类是多例的,每次都会创建容器,导致资源的浪费。一个应用应该只有一个容器 问题: 如何解决呢? 答案: 只要让容器在应用加载时创建,应用卸载时销毁就可以。 问题: 我们怎么知道应用何时加载了呢? 答案: servletcontext对象创建了,就表示当前应用已经被服务器加载了。 问题: 我们怎么知道servletcontext对象创建了呢? 答案: servletcontextlistener监听器可以监听到servletcontext对象的创建和销毁。 spring框架为我们提供了一个监听器:contextloaderlistener。 它是servletcontextlistener接口的实现类,负责监听servletcontext对象的创建,为我们创建容器,监听servletcontext对象的销毁,销毁容器。 我们只需要配置上即可。 contextloaderlistener在spring-web-4.2.4.release.jar中 所以我们要先导入这个jar包。 ,在web.xml中配置监听器: <listener> <listener-class> org.springframework.web.context.contextloaderlistener </listener-class> </listener> 当配置了此监听器后,就不需要使用action的构造函数了,可以把构造函数那段删除了。 此监听器只能读取web-inf目录中的名称为applicationcontext.xml的配置文件。这显然限制了我们的配置。 我们可以通过配置全局初始化参数的方式,指定spring配置文件的位置. 2.6.2配置指定spring配置文件的位置 我们把spring配置文件放到此处,需要配置全局初始化参数: <context-param> <param-name>contextconfiglocation</param-name> <param-value>classpath:config/spring/applicationcontext.xml</param-value> </context-param> 2.6.3分文件编写spring配置 我们写到这里,其实搭建环境已经基本结束了,但是发现spring的配置文件杂乱无章,使我们在找配置的时候,很难一下找到。所以我们采用分配置文件编写的方式。 2.6.3.1编写主配置文件引入其他配置文件 <?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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 引入其他spring配置文件 --> <import resource="applicationcontext-customer.xml"/> <import resource="applicationcontext-jdbc.xml"/> <import resource="applicationcontext-tx.xml"/> </beans> 2.6.3.2编写针对需求的配置文件applicationcontext-customer.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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 把资源交给spring来管理 --> <!-- 配置dao --> <bean id="customerdao" class="com.baidu.dao.impl.customerdaoimpl"> <property name="sessionfactory" ref="sessionfactory"></property> </bean> <!-- 配置service --> <bean id="customerservice" class="com.baidu.service.impl.customerserviceimpl"> <!-- 注入dao --> <property name="customerdao" ref="customerdao"></property> </bean> </beans> 2.6.3.3编写数据库连接的配置文件applicationcontext-jdbc.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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置sessionfactory --> <bean id="sessionfactory" class="org.springframework.orm.hibernate5.localsessionfactorybean"> <!-- 使用的是hibernate主配置文件中的内容,我们只需要指定hibernate配置文件的位置 --> <property name="configlocation" value="classpath:config/hibernate/hibernate.cfg.xml">/> </bean> </beans> 2.6.3.4编写事务控制的配置文件applicationcontext-tx.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: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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <!-- 配置事务管理器 --> <bean id="transactionmanager" class="org.springframework.orm.hibernate5.hibernatetransactionmanager"> <!-- 注入sessionfactory --> <property name="sessionfactory" ref="sessionfactory"></property> </bean> <!-- 配置事务的通知 --> <tx:advice id="txadvice" transaction-manager="transactionmanager"> <!-- 配置事务的属性 --> <tx:attributes> <tx:method name="*" read-only="false" propagation="required"/> <tx:method name="find*" read-only="true" propagation="supports"/> </tx:attributes> </tx:advice> <!-- 配置aop --> <aop:config> <!-- 配置通用切入点表达式 --> <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/> <!-- 建立事务通知和切入点表达式的对应关系 --> <aop:advisor advice-ref="txadvice" pointcut-ref="pt1"/> </aop:config> </beans> 2.6.4配置指定struts2配置文件位置 我们的spring和hibernate配置文件都存到了src/config/的对应包中了,只有struts2配置文件还在类的根路径下,它也可以通过配置的方式指定struts.xml的位置。配置的是过滤器的初始化参数。初始化参数的name和value都是固定写法。 <filter> <filter-name>struts2</filter-name> <filter-class> org.apache.struts2.dispatcher.ng.filter.strutsprepareandexecutefilter </filter-class> <init-param> <param-name>config</param-name> <param-value> struts-default.xml,struts-plugin.xml,config/struts/struts.xml </param-value> </init-param> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> 2.6.5分文件编写struts2配置文件 当我们后面做的模块越来越多,struts2一个配置文件写起来也会杂乱无章,所以我们也可以把struts2的配置文件分开编写。 2.6.5.1编写struts2的主配置文件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> <!-- 开启开发者模式 --> <constant name="struts.devmode" value="true"></constant> <package name="mydefault" extends="struts-default" abstract="true"> <!-- 有公共的配置就写在此处,没有就空着 --> </package> <!--引入其他struts2配置文件 --> <include file="config/struts/struts-customer.xml"></include> </struts> 2.6.5.2针对不同模块编写不同的配置文件struts-customer.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="customer" extends="mydefault" namespace="/customer"> <!-- 获取添加客户页面 --> <action name="adduicustomer" class="com.baidu.web.action.customeraction" method="adduicustomer"> <result name="adduicustomer">/jsp/customer/add.jsp</result> </action> <!-- 查询客户列表 --> <action name="findallcustomer" class=" com.baidu.web.action.customeraction" method="findallcustomer"> <result name="findallcustomer">/jsp/customer/list.jsp</result> </action> </package> </struts> 2.6.6管理action的两种方式 2.6.6.1第一种方式:让struts2自己来管理 此种方式就是在action标签的class属性中提供动作类的全限定类名。 <action name="adduicustomer" class="com.baidu.web.action.customeraction" method="adduicustomer"> <result name="adduicustomer">/jsp/customer/add.jsp</result> </action> 2.6.6.2第二种方式:让spring来管理(实际开发中采用的方式) 此种方式就是在spring配置文件中配置action,在struts2配置文件action标签的class属性里写bean的id。 spring配置文件: <!-- 配置action --> <bean id="customeraction" class="com.baidu.web.action.customeraction" scope="prototype"> <!-- 注入service --> <property name="customerservice" ref="customerservice"></property> </bean> struts2配置文件: <!-- 获取添加客户页面 --> <action name="adduicustomer" class="customeraction" method="adduicustomer"> <result name="adduicustomer">/jsp/customer/add.jsp</result> </action> 第3章基于xml的引入式整合 3.1明确 引入式整合就是把hibernate.cfg.xml中的配置都挪到spring的配置文件中 3.2配置方式 <!-- 配置sessionfactory --> <bean id="sessionfactory" class="org.springframework.orm.hibernate5.localsessionfactorybean"> <!-- 1、连接数据库的信息 --> <property name="datasource" ref="datasource"></property> <!-- 2、hibernate的基本配置 --> <property name="hibernateproperties"> <props> <!-- 数据库的方言--> <prop key="hibernate.dialect"> org.hibernate.dialect.mysqldialect </prop> <!-- 是否显示sql语句--> <prop key="hibernate.show_sql">true</prop> <!-- 是否格式化sql语句--> <prop key="hibernate.format_sql">false</prop> <!-- 采用何种方式生成数据库表结构 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 是spring把sesion绑定到当前线程上的配置 --> <prop key="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.springsessioncontext </prop> </props> </property> <!-- 3、映射文件的位置 mappingresources:配置映射文件的位置,需要写映射文件名称。 并且有几个映射文件,就要写几个<value></value>。 mappinglocations:配置映射文件的位置,需要写映射文件名称。可以使用通配符。 mappingdirectorylocations:配置映射文件的位置,直接写到包的目录即可。 --> <property name="mappinglocations"> <array> <value>classpath:com/baidu/domain/*.hbm.xml</value> </array> </property> </bean> <!-- 配置数据源 --> <bean id="datasource" class="com.mchange.v2.c3p0.combopooleddatasource"> <property name="driverclass" value="com.mysql.jdbc.driver"></property> <property name="jdbcurl" value="jdbc:mysql:///crm"></property> <property name="user" value="root"></property> <property name="password" value="1234"></property> </bean> 第4章基于注解的整合 4.1明确 a.注解整合仍然使用上面的环境,就是把xml的配置全部换成注解 b.spring的注解整合有两种方式,一种是用xml文件,一种是纯注解。 c.hibernate注解整合是把实体类映射改为jpa注解映射 4.2整合步骤-spring使用xml文件 4.2.1spring配置使用注解实现 4.2.1.1第一步:导入spring的必备jar包 之前的环境已经导入。略。 4.2.1.2第二步:在spring配置文件中导入context名称空间及约束 <?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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context" xsi:schemalocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> </beans> 4.2.1.3第三步:在spring配置文件中配置要扫描的包 <!-- 配置spring运行要扫描的包 --> <context:component-scan base-package="com.baidu"></context:component-scan> 4.2.1.4第四步:把action,service和dao都用注解配置 /** * 客户的动作类 */ @controller("customeraction") @scope("prototype") public class customeraction extends actionsupport implements modeldriven<customer> { @autowired private icustomerservice customerservice; //action中的方法不变 } /** * 客户的业务层实现类 */ @service("customerservice") public class customerserviceimpl implements icustomerservice { @autowired private icustomerdao customerdao; //service中的方法不变 } /** * 客户的持久层实现类 */ @repository("customerdao") public class customerdaoimpl implements icustomerdao { //dao中必须自己定义hibernatetemplate,不能继承hibernatedaosupport了 @autowired private hibernatetemplate hibernatetemplate; //dao中的方法不变 } 4.2.1.5第五步:在spring配置文件中配置hiernatetemplate <!-- 配置hibernatetemplate --> <bean id="hibernatetemplate" class="org.springframework.orm.hibernate5.hibernatetemplate"> <!-- 注入sessionfactory --> <property name="sessionfactory" ref="sessionfactory"></property> </bean> 4.2.1.6第六步:在spring配置文件中配置事务管理器 <!-- 配置事务管理器 --> <bean id="transactionmanager" class="org.springframework.orm.hibernate5.hibernatetransactionmanager"> <!-- 注入sessionfactory --> <property name="sessionfactory" ref="sessionfactory"></property> </bean> 4.2.1.7第七步:在spring配置文件中开启spring对注解事务的支持 <!-- 开启spring对注解事务的支持 --> <tx:annotation-driven transaction-manager="transactionmanager"/> 4.2.1.8第八步:在客户的业务层实现类上使用@transactional注解 /** * 客户的业务层实现类 */ @service("customerservice") @transactional(readonly=false,propagation=propagation.required) public class customerserviceimpl implements icustomerservice { @autowired private icustomerdao customerdao; @override @transactional(readonly=true,propagation=propagation.supports) public list<customer> findallcustomer() { return customerdao.findallcustomer(); } @override public void savecustomer(customer customer) { customerdao.savecustomer(customer); } } 4.2.2hibernate映射使用注解配置实现 4.2.2.1实体类映射注解配置 /** * 客户的实体类 * jpa规范:java 持久化规范 * 注解全都是jpa规范的。 * 导包都需要导入javax.persistence包下的 * */ @entity @table(name="cst_customer") public class customer implements serializable { @id @generatedvalue(strategy=generationtype.identity) @column(name="cust_id") private long custid; @column(name="cust_name") private string custname; @column(name="cust_source") private string custsource; @column(name="cust_industry") private string custindustry; @column(name="cust_level") private string custlevel; @column(name="cust_address") private string custaddress; @column(name="cust_phone") private string custphone; public long getcustid() { return custid; } public void setcustid(long custid) { this.custid = custid; } public string getcustname() { return custname; } public void setcustname(string custname) { this.custname = custname; } public string getcustsource() { return custsource; } public void setcustsource(string custsource) { this.custsource = custsource; } public string getcustindustry() { return custindustry; } public void setcustindustry(string custindustry) { this.custindustry = custindustry; } public string getcustlevel() { return custlevel; } public void setcustlevel(string custlevel) { this.custlevel = custlevel; } public string getcustaddress() { return custaddress; } public void setcustaddress(string custaddress) { this.custaddress = custaddress; } public string getcustphone() { return custphone; } public void setcustphone(string custphone) { this.custphone = custphone; } @override public string tostring() { return "customer [custid=" + custid + ", custname=" + custname + ", custsource=" + custsource + ", custindustry=" + custindustry + ", custlevel=" + custlevel + ", custaddress=" + custaddress + ", custphone=" + custphone + "]"; } } 4.2.2.2spring中sessionfactory配置修改 <!-- 配置sessionfactory --> <bean id="sessionfactory" class="org.springframework.orm.hibernate5.localsessionfactorybean"> <!-- 1、连接数据库的 --> <property name="datasource" ref="datasource"></property> <!-- 2、hibernate基本配置的 --> <property name="hibernateproperties"> <props> <!-- 数据库的方言--> <prop key="hibernate.dialect"> org.hibernate.dialect.mysqldialect </prop> <!-- 是否显示sql语句--> <prop key="hibernate.show_sql">true</prop> <!-- 是否格式化sql语句--> <prop key="hibernate.format_sql">false</prop> <!-- 采用何种方式生成数据库表结构 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 是spring把sesion绑定到当前线程上的配置 --> <prop key="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.springsessioncontext </prop> </props> </property> <!-- 3、指定扫描映射注解的包--> <property name="packagestoscan"> <array> <value>com.baidu.domain</value> </array> </property> </bean> 4.2.3struts2配置使用注解实现 4.2.3.1导入struts2注解的jar包 4.2.3.2使用注解配置action /** * 客户的动作类 */ @controller("customeraction") @scope("prototype") //-------以下都是struts2的注解----------- @parentpackage("struts-default")//指定当前包的父包 @namespace("/customer")//指定名称空间,访问当前action的所有方法都需要有名称空间 public class customeraction extends actionsupport implements modeldriven<customer> { private customer customer = new customer(); @autowired private icustomerservice customerservice; @override public customer getmodel() { return customer; } /** * 查询所有客户 * @return */ private list<customer> customers; //用于配置动作名称 @action(value="findallcustomer",results={ @result(name="findallcustomer", type="dispatcher", location="/jsp/customer/list.jsp") }) public string findallcustomer(){ customers = customerservice.findallcustomer(); return "findallcustomer"; } /** * 获取添加客户页面 * @return */ @action(value="adduicustomer",results={ @result(name="adduicustomer", location="/jsp/customer/add.jsp") }) public string adduicustomer(){ return "adduicustomer"; } /** * 添加客户 * @return */ @action(value="addcustomer",results={ @result(name="addcustomer", type="redirect", location="/jsp/success.jsp") }) public string addcustomer(){ customerservice.savecustomer(customer); return "addcustomer"; } public list<customer> getcustomers() { return customers; } public void setcustomers(list<customer> customers) { this.customers = customers; } spring整合struts2的底层实现原理,由spring来创建action对象 (原理在包struts2-spring-plugin-2.3.24.jar中) package com.baidu.customer.action; import com.baidu.customer.domain.customer; import com.baidu.customer.service.customerservice; import com.opensymphony.xwork2.actionsupport; import com.opensymphony.xwork2.modeldriven; /** * 客户模块 * @author administrator */ public class customeraction extends actionsupport implements modeldriven<customer>{ private customer customer = new customer(); public customer getmodel() { return customer; } /** * 跳转到新增页面 * @return * @throws exception */ public string initsave() throws exception { return "initsave"; } 这种方式是ation对象由struts2创建的 // 对象工厂,通过name自动装配对象 customerservice(底层通过jar包用常量覆盖struts2的默认配置,开启spring的对象工厂,当浏览器访问的时候 ,访问到action以后再创建customerservice对象时,用名称name在springioc容器里面找,找到以后返回到action的set方法的customerservice里面,给customerservice赋一个实现类对象值) private customerservice customerservice; public void setcustomerservice(customerservice customerservice) { this.customerservice = customerservice; } public string save() throws exception { system.out.println("web层:保存客户..."); customerservice.save(customer); return none; } }