zoukankan      html  css  js  c++  java
  • ssm框架整合笔记-2-简化配置

    1、添加Dao层相关包,接口和实现类

    image

    DeptDao.java

    package cn.itcast.scm.dao;
    
    import cn.itcast.scm.entity.Dept;
    
    public interface DeptDao {
        public Dept selectDept(Integer deptId);
    
        public int insertDept(Dept dept);
    }

    DeptDaoImpl.java

    package cn.itcast.scm.dao.impl;
    
    import javax.annotation.Resource;
    
    import org.mybatis.spring.SqlSessionTemplate;
    import org.springframework.stereotype.Repository;
    
    import cn.itcast.scm.dao.DeptDao;
    import cn.itcast.scm.entity.Dept;
    
    @Repository("deptDao")
    public class DeptDaoImpl implements DeptDao {
        @Resource
        private SqlSessionTemplate sqlSessionTemplate;
    
        /**
         * 根据部门编号查询部门信息
         * 
         * @param deptId 部门编号
         * @return 部门信息
         */
        public Dept selectDept(Integer deptId) {
            Dept dept = sqlSessionTemplate.selectOne(
                    "cn.itcast.scm.entity.DeptMapper.selectDept", deptId);
            return dept;
        }
    
        /**
         * 添加部门信息
         * 
         * @param dept 部门信息
         * @return 添加成功的记录数
         */
        public int insertDept(Dept dept) {
            System.out.println("------dao.dept:" + dept);
            return sqlSessionTemplate.insert(
                    "cn.itcast.scm.entity.DeptMapper.insertDept", dept);
        }
    
    }

    2、添加业务层相关包,接口和实现类

    image

    2.1编写接口与实现类,实现类用@Service进行注解。

    DeptService.java

    package cn.itcast.scm.service;
    
    import cn.itcast.scm.entity.Dept;
    
    public interface DeptService {
        public Dept selectDept(Integer deptId);
    
        public int insertDept(Dept dept) throws Exception;
    }

    DeptServiceImpl.java

    package cn.itcast.scm.service.impl;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Service;
    
    import cn.itcast.scm.dao.DeptDao;
    import cn.itcast.scm.entity.Dept;
    import cn.itcast.scm.service.DeptService;
    @Service
    public class DeptServiceImpl implements DeptService{
        @Resource
        DeptDao deptDao;
        @Override
        public Dept selectDept(Integer deptId) {
            return deptDao.selectDept(deptId);
        }
    
        @Override
        public int insertDept(Dept dept) throws Exception{
            return deptDao.insertDept(dept);
        }
    
    }

    2.2修改各层调用

    控制器类通过业务层接口调用业务层,业务层再通过dao接口

    2.2.1 修改DeptAction.java 控制器

    package cn.itcast.scm.action;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import cn.itcast.scm.entity.Dept;
    import cn.itcast.scm.service.DeptService;
    
    @Controller
    @RequestMapping(value = "/dept")
    public class DeptAction {
        @Resource
        private DeptService deptService;
    
        public DeptAction() {
            System.out.println("DeptAction初始化。。。");
        }
    
        @RequestMapping(value = "/select")
        public void select(Integer deptId) {
            System.out.println(deptService.selectDept(deptId));
        }
    
        @RequestMapping(value = "/insert")
        public String insert(Dept dept) {
            try {
                System.out.println("---action.dept:" + dept);
                deptService.insertDept(dept);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "forward:/jsp/main.jsp";
        }
    
    }

    2.2.2 修改service层,DeptServiceImpl.java

    package cn.itcast.scm.service.impl;
    
    import javax.annotation.Resource;
    
    import org.springframework.stereotype.Service;
    
    import cn.itcast.scm.dao.DeptDao;
    import cn.itcast.scm.entity.Dept;
    import cn.itcast.scm.service.DeptService;
    @Service
    public class DeptServiceImpl implements DeptService{
        @Resource
        DeptDao deptDao;
        @Override
        public Dept selectDept(Integer deptId) {
            return deptDao.selectDept(deptId);
        }
    
        @Override
        public int insertDept(Dept dept) throws Exception{
            int i =deptDao.insertDept(dept);
            /**
             * try catch的异常错误,如果applicationConte不配置rollback-for="Exception",这种情况不回滚
             */
            Class.forName("cn.itcast.aaaa");//需要try catch的异常错误(方法上抛出了异常,此处不try catch)
            return deptDao.insertDept(dept);
        }
    
    }

    通过上面调整,即可正常测试代码了。下面配置好applicationContext.xml和spring-mvc.xml,来说明一个关于异常回滚的知识点。

    3、修改applicationContext.xml与spring-mvc.xml文件

    3.1 applicationContext.xml和spring-mvc.xml正确配置service和controller,可以测试异常回滚。例如在service层的异常,代码如下:

    3.1.1 修改applicationContext.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:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
    
        
        <!-- 配置数据源,记得去掉myBatis-config.xml的数据源相关配置 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">            
            <property name="driverClass" value="com.mysql.jdbc.Driver" />
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8" />
            <property name="user" value="root" />
            <property name="password" value="root" />        
        </bean>
        <!-- 配置session工厂 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configLocation" value="classpath:myBatis-config.xml" />
        </bean>
        
        <!-- 配置SessionTemplate,已封装了繁琐的数据操作-->
        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>        
        </bean>
        
        <!-- 配置事务管理器,管理数据源事务处理-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
        <!-- 配置事务通知 -->
        <tx:advice id="advice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 默认只处理运行时异常,可加rollback-for="Exception/Throwable"等处理所有异常或包括错误 -->
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>
        <!-- 配置切面织入的范围,把事务边界定在service层 -->
        <aop:config>
            <aop:advisor advice-ref="advice" pointcut="execution(* cn.itcast.scm.service.impl.*.*(..))"/>
        </aop:config>
        
        <!-- 自动扫描组件,要把controller去除,他们是在spring-mvc.xml中配置,如果不去除会影响事务管理。 -->
        
    <context:component-scan base-package="cn.itcast"> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/> </context:component-scan>
        
       
    </beans>

    3.1.2 修改spring-mvc.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:mvc="http://www.springframework.org/schema/mvc"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
        ">
        <!-- 同时开启json格式的支持 (可省) -->
        <mvc:annotation-driven></mvc:annotation-driven>
        
        <!-- 扫描所有的controller 但是不扫描service -->
        
    <context:component-scan base-package="cn.itcast"> <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/> </context:component-scan>
    </beans>

    3.2 知识点:applicationConte.xml中配置事务通知时,配置属性rollback-for,rollback-for="Exception/Throwable"可以处理所有异常或包括错误。

    <!-- 配置事务通知 -->
        <tx:advice id="advice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 默认只处理运行时异常,可加rollback-for="Exception/Throwable"等处理所有异常或包括错误 -->
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>

    3.2.1如果不配置rollback-for="Exception",默认只会回滚运行时异常,例如上面在service层代码中:

    public int insertDept(Dept dept) throws Exception{
            int i =deptDao.insertDept(dept);
            /**
             * 运行时异常,applicationContext.xml中不配置rollback-for="Exception",默认可正常回滚
             */
            Integer.parseInt("aa");
            
            return deptDao.insertDept(dept);
        }

    3.2.2 去掉applicationContext.xml中rollback-for="Exception",对于错误不会回滚,如下配置和service层代码

    <!-- 配置事务通知 -->
        <tx:advice id="advice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 默认只处理运行时异常,可加rollback-for="Exception/Throwable"等处理所有异常或包括错误 -->
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>

    代码DeptServiceImpl.java

    public int insertDept(Dept dept) throws Exception{
            int i =deptDao.insertDept(dept);
            /**
             * try catch的异常错误,如果applicationContext.xml不配置rollback-for="Exception",这种情况不回滚
             */
            Class.forName("cn.itcast.aaaa");//需要try catch的异常错误(方法上抛出了异常,此处不try catch)
            return deptDao.insertDept(dept);
        }

    因此,一般都在applicationContext.xml配置rollback-for="Exception",处理所有异常。

    4.在service层@Autowired(按类型搜索)方式注入dao接口,spring将其转换成bean注入,

       并将Entity的映射文件Mapper.xml文件移至dao的包下,并修改文件中的namespace为dao接口的全限定名。

       在调整applicationContext.xml,配置转换器。具体操作如下:

    4.1 删除dao接口的实现类,删除如下图:

    image

    4.2 测试类也删除(TestDeptDao.java),因为没有了dao接口的实现类,这里测试代码无法调用DeptDaoImpl了。

    4.3 调整dao接口和Entity的映射文件Mapper.xml中的包名为dao接口的全限定名(cn.itcast.scm.dao.DeptDao)

    4.3.1 service层使用@Autowired自动装配dao接口,将被spring自动转换成bean;

    package cn.itcast.scm.service.impl;
    
    import javax.annotation.Resource;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import cn.itcast.scm.dao.DeptDao;
    import cn.itcast.scm.entity.Dept;
    import cn.itcast.scm.service.DeptService;
    @Service
    public class DeptServiceImpl implements DeptService{
        /**
         * 原来@Resource spring通过名称搜索,在此处仍用@Resource的划,spring先通过名称匹配,
         * 如果未找到再根据类型搜索
         * 此处,规范使用@Autowired,spring直接根据类型匹配(因为dao已经没有实现类了),提高效率;
         * spring会自动为其生成一个代理
         */
        @Autowired
        DeptDao deptDao;
        
        @Override
        public Dept selectDept(Integer deptId) {
            return deptDao.selectDept(deptId);
        }
    
        @Override
        public int insertDept(Dept dept) throws Exception{
            int i =deptDao.insertDept(dept);
            /**
             * try catch的异常错误,如果applicationConte不配置rollback-for="Exception",这种情况不回滚
             */
            Class.forName("cn.itcast.aaaa");//需要try catch的异常错误(方法上抛出了异常,此处不try catch)
            return deptDao.insertDept(dept);
        }
    
    }

    4.3.2 移动实体Entity的映射文件Mapper.xml到dao包下,并修改文件内的包名(<mapper namespace="cn.itcast.scm.dao.DeptDao">)

    <?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="cn.itcast.scm.dao.DeptDao">
        <resultMap type="Dept" id="deptResultMap">
            <id property="deptId" column="dept_id" />
            <result property="deptName" column="dept_name" />
            <result property="deptAddress" column="dept_address" />
        </resultMap>
        <!-- id和命名空间用来定位SQL语句,parameterType表示参数的类型,resultMap返回类型 -->
        <select id="selectDept" parameterType="Integer" resultMap="deptResultMap">
            <!--参数的写法#{deptID} -->
            select dept_id,dept_name,dept_address from dept where dept_id=#{deptID}
        </select>
    
        <insert id="insertDept" parameterType="Dept">
            insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress});
        </insert>
    
    </mapper>

    4.3.3 同时删除myBatis-config.xml中对Mapper的配置

    <?xml version="1.0" encoding="UTF-8" ?> 
    <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 通过别名简化对类的使用 -->
        <typeAliases>
            <!-- 通过package, 可以直接指定package的名字, mybatis会自动扫描你指定包下面的javabean,
                  并且默认设置一个别名,默认的名字为非限定类名来作为它的别名。 -->
            <package name="cn.itcast.scm.entity"/>
            
        </typeAliases>
    
    </configuration>

    4.4 在applicationContext.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:tx="http://www.springframework.org/schema/tx"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-3.2.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">
    
        
        <!-- 配置数据源,记得去掉myBatis-config.xml的数据源相关配置 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">            
            <property name="driverClass" value="com.mysql.jdbc.Driver" />
            <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=UTF-8" />
            <property name="user" value="root" />
            <property name="password" value="root" />        
        </bean>
        <!-- 配置session工厂 -->
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="configLocation" value="classpath:myBatis-config.xml" />
            <!--配置扫描式加载SQL映射文件,记得去掉mybatis-config配置-->
            
    <property name="mapperLocations" value="classpath:cn/itcast/scm/dao/*.xml"/>
        </bean>
        
        <!-- 配置事务管理器,管理数据源事务处理-->
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
        <!-- 配置事务通知 -->
        <tx:advice id="advice" transaction-manager="transactionManager">
            <tx:attributes>
                <!-- 默认只处理运行时异常,可加rollback-for="Exception/Throwable"等处理所有异常或包括错误 -->
                <tx:method name="insert*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
                <tx:method name="*" propagation="SUPPORTS"/>
            </tx:attributes>
        </tx:advice>
        <!-- 配置切面织入的范围,把事务边界定在service层 -->
        <aop:config>
            <aop:advisor advice-ref="advice" pointcut="execution(* cn.itcast.scm.service.impl.*.*(..))"/>
        </aop:config>
        
        <!-- 自动扫描组件,要把controller去除,他们是在spring-mvc.xml中配置,如果不去除会影响事务管理。 -->
        <context:component-scan base-package="cn.itcast">
            <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
        </context:component-scan>
        
        <!-- 配置SessionTemplate,已封装了繁琐的数据操作-->
        <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
            <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>        
        </bean>
        
        <!-- 配置 转换器,对于在basePackage设置的包(包括子包)下的接口类,
            如果在Mapper.xml文件中定义过,将被转换成spring的BEAN,生成代理
            在调用 的地方通过@Autowired方式将可以注入接口实例
         -->
        
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> <property name="basePackage" value="cn.itcast.scm.dao"/> </bean>
    </beans>

     

    5.运行程序,在index.jsp,提交表单进行数据插入的测试。

    项目结构截图:

    image

     

     

     

  • 相关阅读:
    SQL SERVER全面优化
    Mysql常见问题及优化
    Mysql相关问答
    Activiti动态设置办理人扩展
    Activiti流程编辑器针对自定义用户角色表优化改造
    taskService 流程任务组件
    activiti 工作流 动态 设置 指定 节点任务人、责任人、组 的实现方式
    千万级规模高性能、高并发的网络架构经验分享
    B树,B+树,红黑树应用场景AVL树,红黑树,B树,B+树,Trie树
    Mybatis源码分析
  • 原文地址:https://www.cnblogs.com/zzfon/p/5244950.html
Copyright © 2011-2022 走看看