回顧 -Hibernate框架 ORM: 對象關(guān)系映射.把數據庫表和JavaBean通過(guò)映射的配置文件映射起來(lái), 操作JavaBean對象,通過(guò)映射的配置文件生成SQL語(yǔ)句,自動(dòng)執行.操作數據庫. 1: 類(lèi)名.hbm.xml 映射配置文件. 2: hibernate.cfg.xml 核心配置文件. 3: 使用Hibernate提供的API操作. Struts2框架 : 和客戶(hù)端進(jìn)行交互 1. 在web.xml配置過(guò)濾器. 2. struts.xml配置文件. Spring框架 1. applicationContext.xml配置 2. 核心IOC和AOP 3. 事務(wù)管理. CustomerAction類(lèi) 在struts.xml配置中配置的 1. Action對象由Struts2框架創(chuàng )建的. CustomerAction:創(chuàng )建CustomerAction對象,由Struts2框架創(chuàng )建的 ---> Spring的IOC容器中對象,找customerService對象,默認按名稱(chēng)找的. 2. Action對象也可以由Spring框架類(lèi)創(chuàng )建 <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整合說(shuō)明 a.獨立式整合指的是三個(gè)框架都使用自己的配置文件。 b.引入式整合指的是hibernate主配置文件中的內容都配置到spring配置文件中 c.在整合過(guò)程中,確保每步都運行成功,然后在繼續往下做。 d.整合中使用的案例是客戶(hù)的保存和列表查詢(xún)操作。 e.后面的三種整合方式都基于1.2中的環(huán)境準備。 1.2環(huán)境準備 1.2.1第一步:創(chuàng )建java web工程 此處使用Servlet2.5規范。 1.2.2第二步:創(chuàng )建數據庫和表結構 create database crm; use crm; /*創(chuàng )建客戶(hù)表*/ CREATE TABLE `cst_customer` ( `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客戶(hù)編號(主鍵)', `cust_name` varchar(32) NOT NULL COMMENT '客戶(hù)名稱(chēng)(公司名稱(chēng))', `cust_source` varchar(32) DEFAULT NULL COMMENT '客戶(hù)信息來(lái)源', `cust_industry` varchar(32) DEFAULT NULL COMMENT '客戶(hù)所屬行業(yè)', `cust_level` varchar(32) DEFAULT NULL COMMENT '客戶(hù)級別', `cust_address` varchar(128) DEFAULT NULL COMMENT '客戶(hù)聯(lián)系地址', `cust_phone` varchar(64) DEFAULT NULL COMMENT '客戶(hù)聯(lián)系電話(huà)', PRIMARY KEY (`cust_id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; 1.2.3第三步:編寫(xiě)實(shí)體類(lèi) /** * 客戶(hù)的實(shí)體類(lèi)(數據模型) */ 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第四步:編寫(xiě)業(yè)務(wù)層接口和實(shí)現類(lèi) /** * 客戶(hù)的業(yè)務(wù)層接口 */ public interface ICustomerService { /** * 查詢(xún)所有客戶(hù) * @return */ List<Customer> findAllCustomer(); /** * @param customer */ void saveCustomer(Customer customer); } /** * 客戶(hù)的業(yè)務(wù)層實(shí)現類(lèi) */ 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第六步:創(chuàng )建持久層接口 /** * 客戶(hù)的持久層接口 */ public interface ICustomerDao { /** * 查詢(xún)所有客戶(hù) * @return */ List<Customer> findAllCustomer(); /** * 保存客戶(hù) * @param customer */ void saveCustomer(Customer customer); } 注意:做上述操作時(shí),并不需要導入任何jar包。 第2章基于XML的獨立式整合 2.1保證spring框架在web工程中獨立運行 2.1.1第一步:拷貝spring的ioc,aop和事務(wù)控制三組jar包 2.1.2第二步:編寫(xiě)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第三步:把業(yè)務(wù)層和持久層配置到文件中 <!-- 把資源交給spring來(lái)管理 --> <!-- 配置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> 持久層實(shí)現類(lèi)代碼: 此時(shí)不要做任何操作,就輸出一句話(huà)。目的是測試spring框架搭建的結果。 /** * 客戶(hù)的持久層實(shí)現類(lèi) */ public class CustomerDaoImpl implements ICustomerDao { @Override public List<Customer> findAllCustomer() { System.out.println("查詢(xún)了所有用戶(hù)"); return null; } @Override public void saveCustomer(Customer customer) { System.out.println("保存了用戶(hù)"); } } 2.1.4第四步:測試spring能否獨立運行 /** * 測試類(lèi),測試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第二步:編寫(xiě)實(shí)體類(lèi)的映射文件 <?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第三步:編寫(xiě)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語(yǔ)句--> <property name="hibernate.show_sql">true</property> <!-- 是否格式化sql語(yǔ)句--> <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綁定到當前線(xiàn)程上的配置--> <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第四步:編寫(xiě)測試類(lèi)-測試保存客戶(hù) /** * hibernate的測試類(lèi) * 保證hibernate框架可以獨立運行 */ public class Hibernate02Test { @Test public void testFindAll(){ //1.讀取配置文件 Configuration cfg = new Configuration(); cfg.configure(); //2.根據配置文件獲取SessionFactory SessionFactory factory = cfg.buildSessionFactory(); //3.根據SessionFactory獲取一個(gè)Session Session s = factory.getCurrentSession(); //4.開(kāi)啟事務(wù) Transaction tx = s.beginTransaction(); //5.執行操作 Query query = s.createQuery("from Customer"); List list = query.list(); for(Object o : list){ System.out.println(o); } //6.提交事務(wù) tx.commit(); //7.釋放資源 factory.close(); } @Test public void testSave(){ Customer c = new Customer(); c.setCustName("傳智專(zhuān)修學(xué)院"); //1.讀取配置文件 Configuration cfg = new Configuration(); cfg.configure(); //2.根據配置文件獲取SessionFactory SessionFactory factory = cfg.buildSessionFactory(); //3.根據SessionFactory獲取一個(gè)Session Session s = factory.getCurrentSession(); //4.開(kāi)啟事務(wù) Transaction tx = s.beginTransaction(); //5.執行操作 s.save(c); //6.提交事務(wù) tx.commit(); //7.釋放資源 factory.close(); } } 2.3整合spring和hibernate框架 2.3.1明確 a.Spring和Hibernate的整合就是spring接管SessionFactory的創(chuàng )建 b.Spring針對Hiberante的操作有一個(gè)封裝的對象HibernateTemplate c.和JdbcTemplate一樣,HibernateTemplate也有一個(gè)HibernateDaoSupport d.HibernateTemplate和HibernateDaoSupport都在spring-orm-4.2.4.RELEASE.jar中 e.我們Dao采用繼承HiberanteDaoSupport的方式編寫(xiě),它一樣不能用于注解配置。 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 /** * 客戶(hù)的持久層實(shí)現類(lèi) */ 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的測試類(lèi) * spring整合Junit * 第一步:拷貝jar包 * spring-junit-4.2.4.jar * 第二步:使用注解替換運行器(原來(lái)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("傳智學(xué)院test"); customerService.saveCustomer(c); } } 測試結果: 無(wú)論保存還是查詢(xún)都運行失??! 按常理來(lái)說(shuō),我們沒(méi)有配置事務(wù),保存失敗是可以理解的。為什么查詢(xún)也會(huì )失敗呢? 分析原因: 是由于spring的HibernateTemplate對象在使用Session時(shí),spring創(chuàng )建了Session的代理對象,在這個(gè)過(guò)程中,spring對hibernate綁定Session到當前線(xiàn)程的配置不認識了,所以運行失敗。 2.3.2.5第五步:修改把Session綁定到當前線(xiàn)程上 <!-- 是hibernate把session綁定到當前線(xiàn)程上的配置 <property name="hibernate.current_session_context_class">thread</property>--> <!-- 是spring把sesion綁定到當前線(xiàn)程上的配置 --> <property name="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.SpringSessionContext </property> 此時(shí)再運行剛才的測試: 查詢(xún)可以使用了。保存不能使用,原因是沒(méi)有事務(wù)。 2.3.3配置Spring的事務(wù) 2.3.3.1第一步:配置事務(wù)管理器并注入SessionFactory <!-- 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <!-- 注入SessionFactory --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> 2.3.3.2第二步:配置事務(wù)的通知及通知的屬性 <!-- 配置事務(wù)的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置事務(wù)的屬性 --> <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建立切入點(diǎn)表達式和事務(wù)通知的關(guān)系 <!-- 配置aop --> <aop:config> <!-- 配置通用切入點(diǎn)表達式 --> <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/> <!-- 建立事務(wù)通知和切入點(diǎn)表達式的對應關(guān)系 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/> </aop:config> 再次測試: 此時(shí)保存和查詢(xún)都可以正常使用了。 2.4保證struts2框架能夠在web工程中獨立運行 2.4.1第一步:拷貝struts2的必備jar包 要把畫(huà)紅線(xiàn)的jar包刪掉,因為hibernate中有個(gè)高版本的。 2.4.2第二步:在類(lèi)的類(lèi)的根路徑下編寫(xiě)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> <!-- 開(kāi)啟開(kāi)發(fā)者模式 --> <constant name="struts.devMode" value="true"></constant> </struts> 2.4.3第三步:在web.xml中配置struts2的核心過(guò)濾器 <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頁(yè)面 2.4.5第五步:修改menu.jsp <A class=style2 href="${pageContext.request.contextPath}/customer/addUICustomer.action" target=main> - 新增客戶(hù) </A> 2.4.6第六步:在struts.xml中配置action <!-- 獲取添加客戶(hù)頁(yè)面 --> <action name="addUICustomer" class="com.baidu.web.action.CustomerAction" method="addUICustomer"> <result name="addUICustomer">/jsp/customer/add.jsp</result> </action> 2.4.7第七步:編寫(xiě)動(dòng)作類(lèi)和方法 /** * 客戶(hù)的動(dòng)作類(lèi) */ public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { private Customer customer = new Customer(); @Override public Customer getModel() { return customer; } /** * 獲取添加客戶(hù)頁(yè)面 * @return */ public String addUICustomer(){ return "addUICustomer"; } } 2.4.8第八步:測試 運行結果:通過(guò)點(diǎn)擊【新增客戶(hù)】可以跳轉到客戶(hù)添加頁(yè)面 2.5整合spring和struts2 2.5.1明確 a.spring整合struts2就是讓spring接管action的創(chuàng )建 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()); //由于動(dòng)作類(lèi)是多例的,每次都會(huì )創(chuàng )建容器,導致資源的浪費。一個(gè)應用應該只有一個(gè)容器 System.out.println(ac); customerService = (ICustomerService) ac.getBean("customerService"); } 2.5.2.3第三步:測試 運行結果:查詢(xún)客戶(hù)列表測試通過(guò)。保存測試通過(guò)。 2.6優(yōu)化配置 2.6.1配置spring的監聽(tīng)器 在上面2.5.2.2小節中有這么一句: 由于動(dòng)作類(lèi)是多例的,每次都會(huì )創(chuàng )建容器,導致資源的浪費。一個(gè)應用應該只有一個(gè)容器 問(wèn)題: 如何解決呢? 答案: 只要讓容器在應用加載時(shí)創(chuàng )建,應用卸載時(shí)銷(xiāo)毀就可以。 問(wèn)題: 我們怎么知道應用何時(shí)加載了呢? 答案: ServletContext對象創(chuàng )建了,就表示當前應用已經(jīng)被服務(wù)器加載了。 問(wèn)題: 我們怎么知道ServletContext對象創(chuàng )建了呢? 答案: ServletContextListener監聽(tīng)器可以監聽(tīng)到ServletContext對象的創(chuàng )建和銷(xiāo)毀。 Spring框架為我們提供了一個(gè)監聽(tīng)器:ContextLoaderListener。 它是ServletContextListener接口的實(shí)現類(lèi),負責監聽(tīng)ServletContext對象的創(chuàng )建,為我們創(chuàng )建容器,監聽(tīng)ServletContext對象的銷(xiāo)毀,銷(xiāo)毀容器。 我們只需要配置上即可。 ContextLoaderListener在spring-web-4.2.4.RELEASE.jar中 所以我們要先導入這個(gè)jar包。 ,在web.xml中配置監聽(tīng)器: <listener> <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> </listener> 當配置了此監聽(tīng)器后,就不需要使用Action的構造函數了,可以把構造函數那段刪除了。 此監聽(tīng)器只能讀取WEB-INF目錄中的名稱(chēng)為applicationContext.xml的配置文件。這顯然限制了我們的配置。 我們可以通過(guò)配置全局初始化參數的方式,指定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分文件編寫(xiě)spring配置 我們寫(xiě)到這里,其實(shí)搭建環(huán)境已經(jīng)基本結束了,但是發(fā)現spring的配置文件雜亂無(wú)章,使我們在找配置的時(shí)候,很難一下找到。所以我們采用分配置文件編寫(xiě)的方式。 2.6.3.1編寫(xiě)主配置文件引入其他配置文件 <?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編寫(xiě)針對需求的配置文件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來(lái)管理 --> <!-- 配置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編寫(xiě)數據庫連接的配置文件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編寫(xiě)事務(wù)控制的配置文件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"> <!-- 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <!-- 注入SessionFactory --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!-- 配置事務(wù)的通知 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <!-- 配置事務(wù)的屬性 --> <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> <!-- 配置通用切入點(diǎn)表達式 --> <aop:pointcut expression="execution(* com.baidu.service.impl.*.*(..))" id="pt1"/> <!-- 建立事務(wù)通知和切入點(diǎn)表達式的對應關(guān)系 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pt1"/> </aop:config> </beans> 2.6.4配置指定struts2配置文件位置 我們的spring和hibernate配置文件都存到了src/config/的對應包中了,只有struts2配置文件還在類(lèi)的根路徑下,它也可以通過(guò)配置的方式指定struts.xml的位置。配置的是過(guò)濾器的初始化參數。初始化參數的name和value都是固定寫(xiě)法。 <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分文件編寫(xiě)struts2配置文件 當我們后面做的模塊越來(lái)越多,struts2一個(gè)配置文件寫(xiě)起來(lái)也會(huì )雜亂無(wú)章,所以我們也可以把struts2的配置文件分開(kāi)編寫(xiě)。 2.6.5.1編寫(xiě)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> <!-- 開(kāi)啟開(kāi)發(fā)者模式 --> <constant name="struts.devMode" value="true"></constant> <package name="myDefault" extends="struts-default" abstract="true"> <!-- 有公共的配置就寫(xiě)在此處,沒(méi)有就空著(zhù) --> </package> <!--引入其他struts2配置文件 --> <include file="config/struts/struts-customer.xml"></include> </struts> 2.6.5.2針對不同模塊編寫(xiě)不同的配置文件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"> <!-- 獲取添加客戶(hù)頁(yè)面 --> <action name="addUICustomer" class="com.baidu.web.action.customerAction" method="addUICustomer"> <result name="addUICustomer">/jsp/customer/add.jsp</result> </action> <!-- 查詢(xún)客戶(hù)列表 --> <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自己來(lái)管理 此種方式就是在action標簽的class屬性中提供動(dòng)作類(lèi)的全限定類(lèi)名。 <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來(lái)管理(實(shí)際開(kāi)發(fā)中采用的方式) 此種方式就是在spring配置文件中配置Action,在struts2配置文件action標簽的class屬性里寫(xiě)bean的id。 spring配置文件: <!-- 配置Action --> <bean id="customerAction" class="com.baidu.web.action.CustomerAction" scope="prototype"> <!-- 注入service --> <property name="customerService" ref="customerService"></property> </bean> struts2配置文件: <!-- 獲取添加客戶(hù)頁(yè)面 --> <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語(yǔ)句--> <prop key="hibernate.show_sql">true</prop> <!-- 是否格式化sql語(yǔ)句--> <prop key="hibernate.format_sql">false</prop> <!-- 采用何種方式生成數據庫表結構 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 是spring把sesion綁定到當前線(xiàn)程上的配置 --> <prop key="hibernate.current_session_context_class"> org.springframework.orm.hibernate5.SpringSessionContext </prop> </props> </property> <!-- 3、映射文件的位置 mappingResources:配置映射文件的位置,需要寫(xiě)映射文件名稱(chēng)。 并且有幾個(gè)映射文件,就要寫(xiě)幾個(gè)<value></value>。 mappingLocations:配置映射文件的位置,需要寫(xiě)映射文件名稱(chēng)??梢允褂猛ㄅ浞?。 mappingDirectoryLocations:配置映射文件的位置,直接寫(xiě)到包的目錄即可。 --> <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.注解整合仍然使用上面的環(huán)境,就是把xml的配置全部換成注解 b.spring的注解整合有兩種方式,一種是用xml文件,一種是純注解。 c.hibernate注解整合是把實(shí)體類(lèi)映射改為JPA注解映射 4.2整合步驟-spring使用xml文件 4.2.1spring配置使用注解實(shí)現 4.2.1.1第一步:導入spring的必備jar包 之前的環(huán)境已經(jīng)導入。略。 4.2.1.2第二步:在spring配置文件中導入context名稱(chēng)空間及約束 <?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都用注解配置 /** * 客戶(hù)的動(dòng)作類(lèi) */ @Controller("customerAction") @Scope("prototype") public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { @Autowired private ICustomerService customerService; //action中的方法不變 } /** * 客戶(hù)的業(yè)務(wù)層實(shí)現類(lèi) */ @Service("customerService") public class CustomerServiceImpl implements ICustomerService { @Autowired private ICustomerDao customerDao; //service中的方法不變 } /** * 客戶(hù)的持久層實(shí)現類(lèi) */ @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配置文件中配置事務(wù)管理器 <!-- 配置事務(wù)管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <!-- 注入SessionFactory --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> 4.2.1.7第七步:在spring配置文件中開(kāi)啟spring對注解事務(wù)的支持 <!-- 開(kāi)啟spring對注解事務(wù)的支持 --> <tx:annotation-driven transaction-manager="transactionManager"/> 4.2.1.8第八步:在客戶(hù)的業(yè)務(wù)層實(shí)現類(lèi)上使用@Transactional注解 /** * 客戶(hù)的業(yè)務(wù)層實(shí)現類(lèi) */ @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映射使用注解配置實(shí)現 4.2.2.1實(shí)體類(lèi)映射注解配置 /** * 客戶(hù)的實(shí)體類(lèi) * 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語(yǔ)句--> <prop key="hibernate.show_sql">true</prop> <!-- 是否格式化sql語(yǔ)句--> <prop key="hibernate.format_sql">false</prop> <!-- 采用何種方式生成數據庫表結構 --> <prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 是spring把sesion綁定到當前線(xiàn)程上的配置 --> <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配置使用注解實(shí)現 4.2.3.1導入struts2注解的jar包 4.2.3.2使用注解配置Action /** * 客戶(hù)的動(dòng)作類(lèi) */ @Controller("customerAction") @Scope("prototype") //-------以下都是struts2的注解----------- @ParentPackage("struts-default")//指定當前包的父包 @Namespace("/customer")//指定名稱(chēng)空間,訪(fǎng)問(wèn)當前action的所有方法都需要有名稱(chēng)空間 public class CustomerAction extends ActionSupport implements ModelDriven<Customer> { private Customer customer = new Customer(); @Autowired private ICustomerService customerService; @Override public Customer getModel() { return customer; } /** * 查詢(xún)所有客戶(hù) * @return */ private List<Customer> customers; //用于配置動(dòng)作名稱(chēng) @Action(value="findAllCustomer",results={ @Result(name="findAllCustomer", type="dispatcher", location="/jsp/customer/list.jsp") }) public String findAllCustomer(){ customers = customerService.findAllCustomer(); return "findAllCustomer"; } /** * 獲取添加客戶(hù)頁(yè)面 * @return */ @Action(value="addUICustomer",results={ @Result(name="addUICustomer", location="/jsp/customer/add.jsp") }) public String addUICustomer(){ return "addUICustomer"; } /** * 添加客戶(hù) * @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的底層實(shí)現原理,由Spring來(lái)創(chuàng )建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; /** * 客戶(hù)模塊 * @author Administrator */ public class CustomerAction extends ActionSupport implements ModelDriven<Customer>{ private Customer customer = new Customer(); public Customer getModel() { return customer; } /** * 跳轉到新增頁(yè)面 * @return * @throws Exception */ public String initSave() throws Exception { return "initSave"; } 這種方式是ation對象由struts2創(chuàng )建的 // 對象工廠(chǎng),通過(guò)name自動(dòng)裝配對象 customerService(底層通過(guò)jar包用常量覆蓋struts2的默認配置,開(kāi)啟spring的對象工廠(chǎng),當瀏覽器訪(fǎng)問(wèn)的時(shí)候 ,訪(fǎng)問(wèn)到action以后再創(chuàng )建CustomerService對象時(shí),用名稱(chēng)name在SpringIOC容器里面找,找到以后返回到Action的set方法的CustomerService里面,給CustomerService賦一個(gè)實(shí)現類(lèi)對象值) private CustomerService customerService; public void setCustomerService(CustomerService customerService) { this.customerService = customerService; } public String save() throws Exception { System.out.println("WEB層:保存客戶(hù)..."); customerService.save(customer); return NONE; } }
聯(lián)系客服