springmvc + mybatis + mysql搭建感想

这是我的第一篇博客,其实很早就打算写了,一直没能动手,可能是自己太懒了。空话不说了,这篇博客的目的主要是记录下这两天搭建过程中遇到的问题

一年多来一直在做游戏服务器,web的东西很久没搞了,最近公司手上的事情不多,所以抽空准备弄一个springmvc的web项目。以前在上一家公司用过一段时间,不过那都是大神搭建的,自己也就是复制粘贴试了下水,没多大的感觉。公司网络限制,没法使用maven,也没建内部仓库(这是我想吐槽的地方),所以只有一个jar包一个jar包的下载。第一次找下来大概需要30多个jar包。开始搭建web环境,现在使用的eclipse不支持web开发,只有自己手动搭建。开始出现问题:

一、开始的时候未使用任何框架,就是一个简单的servlet,想看看项目的流程走动
1.jar包的放置位置。
开始把ja程引用的时候毫无问题,但是通过命令行打了war包以后,项目无法正常运行,没有办法只有把jar包放到WEB-INF/lib下面。ok,可以正常启动了。tomcat的启动默认是寻找WEB-INF下面的web.xml和lib下面的jar包。

2.项目输入路径和打war的路径
我的项目名叫JavaWeb,classpath的输出路径<classpathentry kind="output" path="webapp/WEB-INF/classes"/>。开始的时候我直接/JavaWeb目录下,通过dos运用命令进行的打包(jar -cvf JavaWeb.war*)大家发现问题了吗?接的看后面,将打好的jar包直接拷贝到tomcat的webapps下面,启动tomcat,项目启动失败。再仔细看
看classpath的输出路径根目录是webapp。将当前路径指向webapp再重新打包。ok,正常运行。

二、开始我们的springmvc搭建吧,项目继续延用上面的结构,引用一系列的jar包,在这里简单描述下我遇见的问题,其他的不便一一描述

项目结构基本如下


需要的jar包如下,有些jar包是此次不需要的,不影响运行



1.web.xml的配置

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/applicationContent.xml
        </param-value>
    </context-param>

  <servlet>
  <servlet-name>SpringMVC</servlet-name>
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:/applicationContent_web.xml
            </param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
  <servlet-name>SpringMVC</servlet-name>
  <url-pattern>/</url-pattern>
 </servlet-mapping>
 
</web-app>

将servlet交给spring进行管理。引入spring的配置文件,默认是servlet-name + [-servlet].xml 也就是这里的SpringMVC-servlet.xml,如果不使用默认的,则需要加入这段代码
 <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>
                classpath:/applicationContent_web.xml
            </param-value>
  </init-param>


加载其他配置文件
<context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:/applicationContent.xml
        </param-value>
</context-param>
此文件主要配置的数据库相关的


2.applicationContent_web.xml.xml文件中的主要内容
    <!-- 注解驱动 -->
    <mvc:annotation-driven />
    <context:annotation-config />
    <!-- 扫描包 -->
    <context:component-scan base-package="com.ktios" />
    
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />

    <!-- ViewResolver -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="viewClass"
            value="org.springframework.web.servlet.view.JstlView" />
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp" />
    </bean>


3.applicationContent.xml中的主要内容

<context:property-placeholder location="classpath:/resource/database.properties"
        ignore-unresolvable="true" />

    <aop:aspectj-autoproxy />
    <context:annotation-config />
    <!-- 扫描包 -->
    <context:component-scan base-package="com.ktios" />
    <context:component-scan base-package="resource.mybatis" />

    <!-- <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
        destroy-method="close"> -->
    <bean id="dataSource" class="com.jolbox.bonecp.BoneCPDataSource"
        destroy-method="close">
    <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close"> -->
        <property name="driverClass" value="${jdbc.driverClassName}" />
        <property name="jdbcUrl" value="${jdbc.url}" />
        <!-- <property name="driverClassName" value="${jdbc.driverClassName}" />  
        <property name="url" value="${jdbc.url}" />   -->
        <property name="username" value="${jdbc.username}" />  
        <property name="password" value="${jdbc.password}" />  
    </bean>

    <!-- MyBatis -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.ktios.enity" />
        <property name="mapperLocations" value="classpath:/resource/mybatis/*Mapper.xml" />
    </bean>
    <!-- 扫描mapper接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ktios.dao" />
        <property name="annotationClass" value="com.ktios.dao.annotation.MyBatisRepository" />
    </bean>

    <!-- Transaction -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 采用注解方式的事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

4.以上基本配置已经完成,打war包,运行。报错了
org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.ktios.dao.UserInfoMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
看意思好像是mapper没有完成注入。辗转反侧,最终发现是web.xml中忘记加入
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

其作用如下:
如果您想要在自己所定义的Servlet类别中使用Spring的容器功能
ContextLoaderListener的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。

5.重新打包,执行,依旧报错
 这次感觉奇怪了,tomcat启动后未发现任何错误,项目首页也正常访问,但是涉及数据库操作的访问浏览器一直转圈,拿不到任何返回,坑爹啊!!!!!!好歹给个错吧!!
初步估计是数据库配置的问题,自己写链接,设置配置,数据库可以正常链接,乖乖检查了很久,依旧不行,怀疑是使用 com.jolbox.bonecp.BoneCPDataSource连接池的问题。
换成org.apache.commons.dbcp.BasicDataSource试一下,问题出现了,如下:

java.lang.ClassNotFoundException: ${jdbc.driverClassName}

org.apache.commons.dbcp.SQLNestedException: Cannot load JDBC driver class '${jdbc.driverClassName}'

坑爹,将jdbc.driverClassName直接当成字符串加载了,是什么原因导致这样的事情发生的呢?答案如下:

在spring里使用org.mybatis.spring.mapper.MapperScannerConfigurer 进行自动扫描的时候,设置了sqlSessionFactory 的话,可能会导致PropertyPlaceholderConfigurer失效,也就是用${jdbc.driverClassName}这样之类的表达式,将无法获取到properties文件里的内容。 导致这一原因是因为,MapperScannerConigurer实际是在解析加载bean定义阶段的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类,这个时候,PropertyPlaceholderConfigurer还没来得及替换定义中的变量,导致把表达式当作字符串复制了。

解决方案:
改用sqlSessionFactoryBeanName注入就没有问题(不要使用sqlSessionFactory属性注入,使用sqlSessionFactoryBeanName注入),因为这时不会立即初始化sqlSessionFactory,传入的只是名字,非bean,所以不会引发提前初始化问题。。

<!-- MyBatis -->
    <bean id="mSqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="typeAliasesPackage" value="com.ktios.enity" />
        <property name="mapperLocations" value="classpath:/resource/mybatis/*Mapper.xml" />
    </bean>
<!-- 扫描mapper接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.ktios.dao" />
        <property name="annotationClass" value="com.ktios.dao.annotation.MyBatisRepository" />
        <property name="sqlSessionFactoryBeanName" value="mSqlSessionFactory" />
    </bean>

6.好了重启启动项目,ok成功运行。再次将数据库连接池换成com.jolbox.bonecp.BoneCPDataSource,也可以正常使用了,坑爹的!!!!!!!!此处需要主要两个链接池的属性有所差异
使用org.apache.commons.dbcp.BasicDataSource时需要如下配置:
    <property name="driverClassName" value="${jdbc.driverClassName}" />  
    <property name="url" value="${jdbc.url}" />

7.最后再简单说说classpath和classpath*的问题
classpath就是代表项目的根目录(不知道对不对,但是感觉我的这个项目就是这样的)
比如说此项目对database.properties的引用。 直接使用classpath:/database.properties 不能找到文件,classpath*:/database.properties可以找到

好了,本文结束了,感想大家的拜读!!!其实整个过程中还有许多小插曲,比如说jar包的缺少。。。。。。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值