zoukankan      html  css  js  c++  java
  • SSM框架(1):使用Maven搭建SSM项目实践

    一、推荐阅读

    1. MyBatis(1)——快速入门
    2. MyBatis(2)——MyBatis 深入学习
    3. Maven整合SSM框架

    二、实践中的问题 - SpringSpringMVC

    问题一:@Service 和 @Resource注解的误用 

    两个注解的作用:
    @Service("XXX"):用在类上。相当于将这个类定义为一个bean,bean的名称为XXX; @Resource(name="xxx"):用在类的引用型属性上。当需要在某个类中定义一个属性,并且该属性是一个已在的bean,要为该属性赋值或注入时在该属性上一行使用@Resource(name="XXX")注解,相当于为该属性注入一个名称为xxx的bean。
    • 知识扩展:

      Spring不但支持自己定义的@Autowired注解,还支持几个由JSR-250规范定义的注解,它们分别是@Resource、@PostConstruct以及@PreDestroy。 

      @Resource的作用相当于@Autowired,只不过@Autowired按byType自动注入,而@Resource默认按 byName自动注入罢了。@Resource有两个属性是比较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。

      @Resource装配顺序

    1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
    2. 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常
    3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常
    4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配

    三、实践中的问题 - MyBatis

    问题一:MyBatis动态代理实例化DAO接口时报错,提示无法实例化扫描类 MapperScannerConigurer

    报错信息如下:
     Error creating bean with name 'org.mybatis.spring.mapper.MapperScannerConfigurer#0'
    //解决办法:在配置bena:MapperScannerConigurer时,使用参数sqlSessionFactoryBeanName来设置工厂类实例
    <!-- 配置扫描DAO 接口包,动态实现DAO接口实例,注入到Spring容器中进行管理 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 注入SqlSession工厂对象:SqlSessionFactoryBean -->
    <!--<property name="sqlSessionFactory" ref="sqlSessionFactory"/>-->
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!-- 指定要扫描的DAO接口所在包 -->
    <property name="basePackage" value="com.newbie.dao"/>
    </bean>
    <!-- 配置工厂对象: SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--注入数据库连接池 -->
    <property name="dataSource" ref="dataSource"/>
    <!--扫描com.newbie.domain包,使用类的别名(默认首字母小写) -->
    <property name="typeAliasesPackage" value="com.newbie.domain"/>
    <!-- 扫描sqlMapper配置文件:userMapper.xml-->
    <property name="mapperLocations" value="classpath:mapper/*.xml"/>
    </bean>
    原因分析:
      MapperScannerConigurer实际是在解析加载bean定义阶段实例化的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类,但是,此时PropertyPlaceholderConfigurer还没来得及替换定义中的变量数据,导致把表达式当作字符串复制了。
    
    解决办法:
    第一种方式:在配置bena:MapperScannerConigurer时,使用参数sqlSessionFactoryBeanName来设置工厂类实例.原理:使用sqlSessionFactoryBeanName注入,不会立即初始化sqlSessionFactory, 所以不会引发提前初始化问题。
        即:
      修改 property name="sqlSessionFactory" ref="sqlSessionFactory" 
      改为 property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"
    
    第二种:直接删掉。原理:在配置bena:MapperScannerConigurer时,不配置sqlSessionFactory,由容器自动注入依赖。

    问题二:动态实例接口IUserDAO时,接口中的selectAll()方法没有实现

    报错信息:
    org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.newbie.dao.IUserDAO.selectAll
    原因分析:
    检查UserMapper.xml文件中的mapper配置信息,发现namespace="***"属性值不是IUserDAO的全类名。
    
    解决办法:
    修改namespace属性值,改为namespace="com.newbie.dao.IUserDAO"
    <!-- mapper配置文件,其中namespace指定要动态实例的DAO接口全局类名称 -->
    <mapper namespace="com.newbie.dao.IUserDAO">
    • 知识扩展:Invalid bound statement (not found)错误的原因是:接口IUserDAO 和 配置文件UserMapper.xml之间匹配有问题。

      排查步骤:

        (1)检查配置的UserMapper.xml的路径是否正确;

        (2)检查UserMapper.xml 所在的package名称 和 接口IUserDAO 所在的包名称是否相同;

        (3)接口IUserDAO中的方法,在配置文件UserMapper.xml 中是否存在;

        (4)接口IUserDAO中的方法返回值是Lis<User>,而UserMapper.xml中对应的select节点是否配置有ResultMap;

       

  • 相关阅读:
    在Centos 7下编译openwrt+njit-client
    开博随笔
    Chapter 6. Statements
    Chapter 4. Arrays and Pointers
    Chapter 3. Library Types
    Chapter 2.  Variables and Basic Types
    关于stm32不常用的中断,如何添加, 比如timer10 timer11等
    keil 报错 expected an identifier
    案例分析 串口的地不要接到电源上 会烧掉
    案例分析 CAN OPEN 调试记录 进度
  • 原文地址:https://www.cnblogs.com/newbie27/p/10817951.html
Copyright © 2011-2022 走看看