zoukankan      html  css  js  c++  java
  • SSH框架之Spring+Struts2+Hibernate整合篇

    回顾 -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;
                }
    
            }
  • 相关阅读:
    Spark开发环境搭建(IDEA、Scala、SVN、SBT)
    Spark源码系列:RDD repartition、coalesce 对比
    Scala:类和对象
    申请MS的FastCounter
    code generation part1some OOrelated topic! not completed
    [book]ADO.NET实用指南
    如果FC能把blog的WEB VIEW与AGG VIEW统计起来就方便多了
    Dell 1704
    O'Reilly .NET Framework Essentials, 2nd Edition
    单用户blog系统(一)
  • 原文地址:https://www.cnblogs.com/haizai/p/11568801.html
Copyright © 2011-2022 走看看