SpringMVC+Mybatis+热部署mapper文件

SpringMVC+Mybatis+热部署mapper文件

每天都是从网上找别人分享出来的好东西纳入囊中,今天自己也想分享一下自己的一些东西给大家。

一直在用SSH框架,没办法现在的主流就是SpringMvc+Mybatis,所以也研究了一下。看了几天网上分享的精髓,恕小弟我愚昧,搞了好久才弄明白其中的奥妙,不过我觉得自己懂了还不够深刻,必须拿出来和大家分享,让大家也能看懂才是真正的懂了。

我尽量写的简单点通俗易懂,只要是有点java基础就能看懂这篇文章是我的目标。

我们老大最近让了解markDown,写标题的时候正好看到有‘切换markDown编辑器’,直接开干,之前真的一点也不了解markDown。

(奥利给,我次有内,为给呀,老铁没毛病,今天又是一个楼面,100来平方,轻松拿下,干就完了!!)不要问我这句话啥意思,最近快手上有个雷哥,因这句口头禅火了。废话是不是有点太多了?好吧,我错了步入正题!!!

###我发现一个问题,也可能是我自己的问题,就是在看别人分享出来的资源的时候,总是跟着资源一步一步做,然后突然卡壳,要不就是报错要不就是各种纠结,瞬间继续看下去的心情就没了,这里建议大家耐心点,哪里卡壳了,就好好研究一下,当你迈过这个坎后,你肯定会收获更多

##开发工具
Myeclipse2014jdk1.7tomcat7,数据库我用的是oracle,伙计们这几个东西都先给我准备好了,马上开始打仗了。什么?这些东西你都不知道?用我们老家的口头禅来说“外日他dei儿,你给我去求吧”,这是作为一个程序员必须知道的,就像你打仗需要用枪一个道理!

##愤怒感言
每次跟着网上的资料学习,都会被一大堆的各种jar问题包搞的晕头转向,我总觉得这个是最浪费时间的,而且是能让人发疯的节奏!所以,这里我就先来拯救一下正在看我文章的小伙伴们吧,谁让你我最亲呢!我这里把所有jar包先贴出来,然后附上下载地址,请小伙伴们先不要问jar包的具体用途,先下载用了再说。
jar所有需要的jar包

下载链接:http://download.csdn.net/detail/chunge48596/9709211
好了,小伙伴,我们离成功就差一步了,要不咱们先喝杯茶聊聊妹子聊聊人生吧。Set Fire to the Rain好听,你值得拥有

##项目结构
接下来我先把项目结构贴出来,有心的小伙伴可能会发现怎么看着有点眼熟?没办法,我也是从网上找的资源拼凑的,大家凑合着看吧。还想咋滴?不行咱们来打一架?哼~
项目结构

卧槽,刚才手机振动了一下,打开一看居然发工资了,我这小心脏扑通扑通的,老板:给我来个鸡蛋灌饼,加2个蛋!!!!老子有钱

##开始盖楼
在Package Explorer空白处右键 > new > Web Project

这里写图片描述

next>next>各种next,最后Finish,然后出现如下结构

这里写图片描述

###然后咱们把上面讲到的jar包全部放进项目里,第一步打开项目家大门,第二部把jar包拿起来,第三部使劲把这些jar包扔进项目家里!!!
不逗你们啦,我是这样弄的,去Workspaces找到你刚建立好的项目,然后把所有jar包放进lib目录下,我的项目路径 > D:\Workspaces2014\spring-mvc\WebRoot\WEB-INF\lib

不知道自己的Workspaces项目路径在哪?我勒个擦,我的小哥,你确定你是个程序员吗?我再教教你,谁让我就是这么好呢!!!以后给我记住了,八嘎
右键你的项目名称 > Properties > Resource 然后你看到了什么?哦~ ~ ~ ~ ~知道了,在这里啊!

这里写图片描述

###下面就是数据库连接了,建立JDBC属性文件,项目都是这样,把数据库配置独立出来,这样是极好的

右键src > new > File,名字取名叫 jdbc.properties > Finish
右键 jdbc.properties > Properties

这里写图片描述

将 jdbc.properties 文件编码修改为UTF-8

jdbc.properties 里面复制下面数据库配置,这里请注意,我用的是oracle 用其他数据库的小伙伴要注意哦!当然这里需要配置你自己的数据库配置,这里如果你不会,那么我建议去问一下旁边的老师,或者同事,请人家吃麻辣烫。你想问我啊?也行,我要喝16块钱一碗的方中山胡辣汤,嘎嘎!

jdbc.driver=oracle.jdbc.OracleDriver

#test environment
jdbc.url=jdbc\:oracle\:thin\:@192.111.111.111\:1521\:oraga1
jdbc.username=bugaosuni
jdbc.password=nicai

#jdbc.maxActive=1000
#jdbc.maxIdle=300
#jdbc.maxWait=60000
#defaultAutoCommit=false
#removeAbandoned=true
#removeAbandonedTimeout=600
#jdbc.validationQuery=select 1 from dual
#jdbc.testOnBorrow=true

只是一个简单的一个SpringMvc例子,所以上面很多数据库连接池的配置我都先注释掉了,想要强大的伙伴自己去研究研究吧!

###创建log4j.properties文件,里面的注释异常的详细,不多说了,直接贴出代码
###记得把把文件格式转换成utf-8

### Log4j配置 ###
### 与Spring结合需要在web.xml中指定此文件位置,并添加监听器 ###
#定义log4j的输出级别和输出目的地(目的地可以自定义名称,和后面的对应)
#[ level ] , appenderName1 , appenderName2
log4j.rootLogger=DEBUG,console,file

#-----------------------------------#
#1 定义日志输出目的地为控制台
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
####可以灵活地指定日志输出格式,下面一行是指定具体的格式 ###
#%c: 输出日志信息所属的类目,通常就是所在类的全名
#%m: 输出代码中指定的消息,产生的日志具体信息 
#%n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#-----------------------------------#
#2 文件大小到达指定尺寸的时候产生一个新的文件 
log4j.appender.file = org.apache.log4j.RollingFileAppender
#日志文件输出目录
log4j.appender.file.File=logs/ssm.log
#定义文件最大大小
log4j.appender.file.MaxFileSize=10mb
###输出日志信息###
#最低级别
log4j.appender.file.Threshold=ERROR
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#-----------------------------------#
#4 mybatis 输出SQL语句部分
log4j.logger.org.mybatis=DEBUG
#log4j.logger.cn.tibet.cas.dao=DEBUG
#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG#
#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG#
#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG#
#log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG 

###建立spring-mybatis.xml配置文件,很重要的一步哦,同学们要给我竖起耳朵听着,瞪大眼睛看着

右键src > new > File,名字取名叫 spring-mybatis.xml > Finish,记得看一下文件编码格式,不是UTF-8的修改一下
spring-mybatis.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:mybatis="http://mybatis.org/schema/mybatis-spring"  
       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://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd  
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  
      
 	<!-- 自动扫描,base-package指向了alibaba下面的所有包,扫描所有类的注解 -->  
    <context:component-scan base-package="com.alibaba" /> 
    
    <!-- 引入配置文件,这里注意properties文件最好还是放在src下面吧,本来放在WEB-INF下面搞了好久都报错 -->  
    <context:property-placeholder location="classpath:jdbc.properties" />
      
    <!--数据库连接-->  
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">   
        <property name="driverClassName" value="${jdbc.driver}" />
        <property name="url" value="${jdbc.url}" />  
        <property name="username" value="${jdbc.username}"/>  
        <property name="password" value="${jdbc.password}"/>  
     	<!--  
     	配置初始化大小、最小、最大 
        <property name="initialSize"><value>1</value></property>  
        <property name="maxActive"><value>5</value></property>  
        <property name="minIdle"><value>1</value></property>  
       	配置获取连接等待超时的时间  
        <property name="maxWait"><value>60000</value></property>  
       	配置监控统计拦截的filters  
        <property name="filters"><value>stat</value></property>  
       	配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒  
        <property name="timeBetweenEvictionRunsMillis"><value>60000</value></property>  
       	配置一个连接在池中最小生存的时间,单位是毫秒  
        <property name="minEvictableIdleTimeMillis"><value>300000</value></property> 
        -->  
    </bean>  
      
    <!-- spring和MyBatis整合,不需要mybatis的配置映射文件 -->  
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <!-- 自动扫描mapping.xml文件 -->  
        <property name="mapperLocations" value="classpath:com/alibaba/mapper/*.xml"></property>  
    </bean>  
  
    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->  
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.alibaba.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>  
    </bean>  
  
    <!-- (事务管理)transaction manager, use JtaTransactionManager for global tx -->  
    <bean id="transactionManager"  
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean>
    
</beans> 

###上面的步骤完成后,我们用MyBatis Generator自动创建代码(dao,entity,mapper),这步很牛逼,当你实战的时候能为你省下不少时间,跟网上的大神学的

在D盘,或者随便哪个盘里面创建一个文件夹,名字自取。文件夹里面的内容如下:这里写图片描述

属实操蛋了,写完预览了一下,发现博客都看不清楚包的名字,我在列一下包名和文件名:
generatorConfig.xml
mybatis-3.2.7.jar
mybatis-generator-core-1.3.2.jar
mysql-connector-java-5.1.25-bin.jar
ojdbc14.jar

generatorConfig.xml内容如下

<?xml version="1.0" encoding="UTF-8"?>    
<!DOCTYPE generatorConfiguration    
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"    
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">    
<generatorConfiguration>
	<!-- 注意注释的前后都是有空格的,不然会报错 -->
	<!-- oracle数据库驱动 -->
    <classPathEntry location="ojdbc14.jar"/>
	
	<!-- mysql数据库驱动,我用的是oracle驱动 -->
	<!-- <classPathEntry location="mysql-connector-java-5.1.25-bin.jar"/> -->
	
    <context id="DB2Tables"  targetRuntime="MyBatis3">
        <commentGenerator>
            <property name="suppressDate" value="true"/>
			<!-- 是否去除自动生成的注释true:是:false:否 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
		<!-- oralce数据库链接URL,用户名、密码 -->
        <jdbcConnection driverClass="oracle.jdbc.driver.OracleDriver" connectionURL="jdbc:oracle:thin:@192.168.38.207:1521:oradev" userId="xxd_v6_test" password="xxd_v6_test">
		
		<!-- mysql数据库链接URL,用户名、密码 -->
		<!-- <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://122.122.2.1/db_124" userId="test" password="test"> -->
		
        </jdbcConnection>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
		<!-- 生成模型的包名和位置 -->
        <javaModelGenerator targetPackage="test.domain" targetProject="src">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
		<!-- 生成映射文件的包名和位置 -->
        <sqlMapGenerator targetPackage="test.mapping" targetProject="src">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
		<!-- 生成DAO的包名和位置 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="test.IDao" targetProject="src">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
		<!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名 -->
        <table tableName="industry" domainObjectName="industry" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>
</generatorConfiguration>

以上这些都弄好之后,用控制台进入当前目录下,按照我的步骤来:

1、按Ctrl + r 输入 cmd 回车,进入控制台
2、输入 d: 回车(这里取决于你的文件夹在哪个盘里)
3、输入 cd 文件夹名字 回车(注意cd后面有个空格)
4、输入 Java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite回车

然后稍等一下,出现以下提示及表示成功
这里写图片描述

这里要注意,如果执行报错,可能是因为 generatorConfig.xml 编码格式不对,用记事本打开generatorConfig.xml然后另存为ANSI格式,覆盖之前的generatorConfig.xml,再进行执行命令
然后你就可以去看看src文件夹里面的东西了,这里需要注意下生成的mapper文件,里面好像有点重复了,耐心点看看是否重复了,有重复就把重复的部分去掉即可

##接下来我们进行测试我们的代码是否能成功运行
将生成的文件复制到我们的项目里面,如下图:

这里写图片描述

不是说贴进来就行了,肯定会报错,把错误改改,就是一些包的位置和引入错误,改好之后需要注意一下mapper.xml文件,我接下来给伙伴们说一下mapper.xml文件各种关键字对应的位置和意思

<?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">
<!-- 这里的namespace对应的是dao -->
<mapper namespace="com.alibaba.dao.industryMapper">
  <!-- type对应的是实体类;我用的是oracle数据库,数字类型字段要用NUMERIC这个类型,用NUMBER这个类型会报错 -->	
  <resultMap id="BaseResultMap" type="com.alibaba.entity.industry">
    <id column="ID" jdbcType="DECIMAL" property="id" />
    <result column="CATEGORY_LEVEL" jdbcType="DECIMAL" property="categoryLevel" />
    <result column="PARENT_ID" jdbcType="DECIMAL" property="parentId" />
    <result column="CATEGORY_NAME" jdbcType="VARCHAR" property="categoryName" />
    <result column="CATEGORY_EXPLAIN" jdbcType="VARCHAR" property="categoryExplain" />
    <result column="PROFIT_MARGIN" jdbcType="DECIMAL" property="profitMargin" />
    <result column="CREATE_DATE" jdbcType="DATE" property="createDate" />
    <result column="UPDATE_DATE" jdbcType="DATE" property="updateDate" />
    <result column="REMARK" jdbcType="VARCHAR" property="remark" />
  </resultMap>
  <!-- Base_Column_List就相当于你需要查询的字段,完全可以用select * 来替代啊,不太明白这里为什么会自动生成此项 -->
  <sql id="Base_Column_List">
    ID, CATEGORY_LEVEL, PARENT_ID, CATEGORY_NAME, CATEGORY_EXPLAIN, PROFIT_MARGIN, CREATE_DATE, 
    UPDATE_DATE, REMARK
  </sql>
  <!-- id就是dao里面定义的方法,要保持一致,这里注意,我把parameterType中的Long改成了Integer -->
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from INDUSTRY
    where ID = #{id,jdbcType=DECIMAL}
  </select>
  
  
</mapper>

太费劲了,我只贴出来一部分代码,后面那些更新和删除就不贴出来了,就简单的给大家演示一下查询,我相信在我的调教下,这个查询会了之后,其他的比葫芦画瓢,你绝对能学会~

###接下来我们就可以进行测试了,创建test、service、serviceImpl三个文件,下面贴出来代码

这里写图片描述

###industryService:

package com.alibaba.service;

import com.alibaba.entity.industry;

public interface industryService {
	//根据ID查询行业信息
	public industry selectByPrimaryKey(Integer id);
	
}

###industryServiceImpl:

package com.alibaba.service.serviceImpl;

import javax.annotation.Resource;
import org.springframework.stereotype.Service;
import com.alibaba.dao.industryMapper;
import com.alibaba.entity.industry;
import com.alibaba.service.industryService;

@Service
public class industryServiceImpl implements industryService{
	@Resource
	private industryMapper industryDao;
	
	//根据id查询行业信息
	public industry selectByPrimaryKey(Integer id){
		return industryDao.selectByPrimaryKey(id);
	}
}

###test:

package com.alibaba.controller;

import javax.annotation.Resource;
import org.apache.log4j.Logger;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.alibaba.entity.industry;
import com.alibaba.service.industryService;

@RunWith(SpringJUnit4ClassRunner.class)     //表示继承了SpringJUnit4ClassRunner类 
@ContextConfiguration(locations = {"classpath:spring-mybatis.xml"}) 
public class test {
	private static Logger logger = Logger.getLogger(test.class); 
	@Resource
	private industryService iService;
	@Test
	public void test2(){
		industry i = iService.selectByPrimaryKey(3);
		System.out.println("行业说明:"+i.getCategoryExplain());
		logger.info("行业说明:"+i.getCategoryExplain());
	}
}

一切准备就绪,打开test文件,右键 > Run As > JUnit Test,看控制台有没有输出你的数据,有数据,说明说明你已炼成葵花宝典第一式

这里写图片描述

##下面创建spring-mvc.xml文件,SpringMvc的核心
###直接贴出配置

<?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:p="http://www.springframework.org/schema/p"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:mvc="http://www.springframework.org/schema/mvc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans    
                        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd    
                        http://www.springframework.org/schema/context    
                        http://www.springframework.org/schema/context/spring-context-3.1.xsd    
                        http://www.springframework.org/schema/mvc    
                        http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> 
                         
    <!-- 自动扫描该包,使SpringMVC认为包下用了@controller注解的类是控制器 -->  
    <context:component-scan base-package="com.alibaba.controller" />  
    <!--避免IE执行AJAX时,返回JSON出现下载文件 -->  
    <bean id="mappingJacksonHttpMessageConverter"  
        class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">  
        <property name="supportedMediaTypes">  
            <list>  
                <value>text/html;charset=UTF-8</value>  
            </list>  
        </property>  
    </bean>  
    <!-- 启动SpringMVC的注解功能,完成请求和注解POJO的映射 -->  
    <bean  
        class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">  
        <property name="messageConverters">  
            <list>  
                <ref bean="mappingJacksonHttpMessageConverter" /> <!-- JSON转换器 -->  
            </list>  
        </property>  
    </bean>  
    <!-- 定义跳转的文件的前后缀 ,视图模式配置-->  
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <!-- 这里的配置我的理解是controller方法返回一个字符串,然后在WEB-INFO/pages/里面找与方法名对应的jsp-->  
        <property name="prefix" value="/WEB-INF/pages/" />  
        <property name="suffix" value=".jsp" />  
    </bean>  
      
    <!-- 配置文件上传,如果没有使用文件上传可以不用配置,当然如果不配,那么配置文件中也不必引入上传组件包 -->  
    <bean id="multipartResolver"    
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
        <!-- 默认编码 -->  
        <property name="defaultEncoding" value="utf-8" />    
        <!-- 文件大小最大值 -->  
        <property name="maxUploadSize" value="10485760000" />    
        <!-- 内存中的最大值 -->  
        <property name="maxInMemorySize" value="40960" />    
    </bean>   
  
</beans>  

###在WEB-INF下创建web.xml,配置如下:

<?xml version="1.0" encoding="UTF-8"?>  
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
    xmlns="http://java.sun.com/xml/ns/javaee"  
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"  
    version="3.0">  
    <display-name>Archetype Created Web Application</display-name>  
    
    <!-- Spring和mybatis的配置文件 -->  
    <context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:spring-mybatis.xml</param-value>  
    </context-param>  
    <!-- 编码过滤器 -->  
    <filter>  
        <filter-name>encodingFilter</filter-name>  
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>  
        <async-supported>true</async-supported>  
        <init-param>  
            <param-name>encoding</param-name>  
            <param-value>UTF-8</param-value>  
        </init-param>  
    </filter>  
    <filter-mapping>  
        <filter-name>encodingFilter</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    <!-- Spring监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
    </listener>  
    
    <!-- 防止Spring内存溢出监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener> 
    
    <!-- Spring MVC servlet -->  
    <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:spring-mvc.xml</param-value>  
        </init-param>  
        <load-on-startup>1</load-on-startup>  
        <async-supported>true</async-supported>  
    </servlet>  
    <servlet-mapping>  
        <servlet-name>SpringMVC</servlet-name>  
        <!-- 此处如果用“/”表示拦截所有请求,包括静态资源(js,css,jpg,)需要过滤掉这些静态资源的拦截;
        	    此处配置成*.do,那么就只会拦截后缀为.do的请求,不会拦截静态资源,也不用配置过滤静态资源,推荐使用 -->  
        <url-pattern>*.do</url-pattern>  
    </servlet-mapping> 
     
    <welcome-file-list>  
        <welcome-file>/index.jsp</welcome-file>  
    </welcome-file-list> 
</web-app>  

###在controller包里创建industryController(名字自定义):

package com.alibaba.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import com.alibaba.entity.industry;
import com.alibaba.service.industryService;

@Controller
@RequestMapping("/industry")
public class industryController {
	private static Logger logger = Logger.getLogger(industryController.class); 
	private industry indu;
	@Resource 
	private industryService iservice;
	
	@RequestMapping("/queryIndustry")
	public String queryIndustryById(HttpServletRequest request,String id){
		/*接收前台传过来的参数,可以直接接收,不需要任何多余的代码,就直接在方法的参数里面定义好就行,牛逼思密达*/
		/*这里需要注意,如果参数只有一个,url传过来的参数名称和controller方法里面的参数名称不对应也能接收到值;如果是多个参数,那就必须一一对应,不然会接收不到值*/
		indu = iservice.selectByPrimaryKey(Integer.parseInt(id));
		request.getSession().setAttribute("industry", indu);
		return "showIndustry";
	}
}

###index.jsp,如下:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    <a href="industry/queryIndustry.do?id=3">点击查询行业信息</a>
  </body>
</html>

###在WEB-INF下创建pages文件夹,然后创建showIndustry.jsp,名字不是随便起的,跟你controller方法返回的字符串要对应
这里写图片描述

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
	<meta http-equiv="pragma" content="no-cache">
	<meta http-equiv="cache-control" content="no-cache">
	<meta http-equiv="expires" content="0">    
	<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
	<meta http-equiv="description" content="This is my page">
	<!--
	<link rel="stylesheet" type="text/css" href="styles.css">
	-->
  </head>
  
  <body>
    <table align="center" border="1">
    	<tr>
    		<td>行业名称</td>
    		<td>${industry.categoryName }</td>
    	</tr>
    	<tr>
    		<td>行业说明</td>
    		<td>${industry.categoryExplain }</td>
    	</tr>
    </table>
  </body>
</html>

##差不多要结束了,我们把项目部署到tomcat7下,然后运行项目

这里写图片描述

打开浏览器,输入:http://localhost:8080/spring-mvc

这里写图片描述

“点击查询行业信息”

这里写图片描述

#大功告成,艾玛,真累,到这里SpringMvc伙伴们就差不多学会了,我建议大家还是多看几遍过程,哪个地方不会去搜一下,或者你只需要一碗胡辣汤贿赂贿赂我,我就勉为其难的给你讲讲撒,哈哈,开个玩笑啦

#已经学会的同学可能会发现一个问题,就是每次我们修改一下mapper文件,就需要重启一下项目。
#项目小了还好,如果以后项目大了,修改一下mapper,重启一下项目,这尼玛蛋都碎一地了
#所以,又费老鼻子劲去找方法,最终功夫不负有心人,接下来,就给大家讲讲自动加载mapper文件的方法
#这个东西挺有意思,只要发现任何mapper文件被修改,就会重新加载被修改的mapper文件,**只加载被修改的mapper文件,只加载被修改的mapper文件,只加载被修改的mapper文件重要的事情说三遍!!!**网上还有些方法也能实现自动加载mapper文件,不过我觉得麻烦,而且每次修改一个mapper文件,就需要重新加载所有的mapper文件,效率上也不会太好,废话不多说,直接开始

##在src下创建util包,然后创建一个类,名字:MapperRefresh

这里写图片描述

然后把下面这一大坨代码贴进MapperRefresh.java,里面的代码说实话我也没怎么看,说不定也看不懂,先拿起来用吧

package com.alibaba.util;

import java.io.File;  
import java.io.FileInputStream;  
import java.io.FileNotFoundException;  
import java.io.InputStream;  
import java.lang.reflect.Field;  
import java.util.ArrayList;  
import java.util.HashMap;  
import java.util.List;  
import java.util.Map;  
import java.util.Properties;  
import java.util.Set;  
  
import org.apache.commons.lang3.StringUtils;  
import org.apache.ibatis.builder.xml.XMLMapperBuilder;  
import org.apache.ibatis.executor.ErrorContext;  
import org.apache.ibatis.session.Configuration;  
import org.apache.log4j.Logger;  
import org.springframework.core.NestedIOException;  
import org.springframework.core.io.Resource;  
  
import com.google.common.collect.Sets;  
  
/** 
 * 刷新MyBatis Mapper XML 线程 
 * @author ThinkGem 这个是原著的作者,我只是直接拿来用了,原著莫怪
 * @version 2016-5-29 
 */  
public class MapperRefresh implements java.lang.Runnable {  
  
    public static Logger log = Logger.getLogger(MapperRefresh.class);  
  
    private static String filename = "/mybatis-refresh.properties";  
    private static Properties prop = new Properties();  
  
    private static boolean enabled;         // 是否启用Mapper刷新线程功能  
    private static boolean refresh;         // 刷新启用后,是否启动了刷新线程  
      
    private Set<String> location;         // Mapper实际资源路径  
      
    private Resource[] mapperLocations;     // Mapper资源路径  
    private Configuration configuration;        // MyBatis配置对象  
      
    private Long beforeTime = 0L;           // 上一次刷新时间  
    private static int delaySeconds;        // 延迟刷新秒数  
    private static int sleepSeconds;        // 休眠时间  
    private static String mappingPath;      // xml文件夹匹配字符串,需要根据需要修改  
  
    static {  
          
        try {  
            prop.load(MapperRefresh.class.getResourceAsStream(filename));  
        } catch (Exception e) {  
            e.printStackTrace();  
            System.out.println("Load mybatis-refresh “"+filename+"” file error.");  
        }  
  
        enabled = "true".equalsIgnoreCase(getPropString("enabled"));  
          
        delaySeconds = getPropInt("delaySeconds");  
        sleepSeconds = getPropInt("sleepSeconds");  
        mappingPath = getPropString("mappingPath");  
  
        delaySeconds = delaySeconds == 0 ? 50 : delaySeconds;  
        sleepSeconds = sleepSeconds == 0 ? 3 : sleepSeconds;  
        mappingPath = StringUtils.isBlank(mappingPath) ? "mappings" : mappingPath;  
  
        log.debug("[enabled] " + enabled);  
        log.debug("[delaySeconds] " + delaySeconds);  
        log.debug("[sleepSeconds] " + sleepSeconds);  
        log.debug("[mappingPath] " + mappingPath);  
    }  
  
    public static boolean isRefresh() {  
        return refresh;  
    }  
  
    public MapperRefresh(Resource[] mapperLocations, Configuration configuration) {  
        this.mapperLocations = mapperLocations;  
        this.configuration = configuration;  
    }  
  
    @Override  
    public void run() {  
  
        beforeTime = System.currentTimeMillis();  
  
        log.debug("[location] " + location);  
        log.debug("[configuration] " + configuration);  
  
        if (enabled) {  
            // 启动刷新线程  
            final MapperRefresh runnable = this;  
            new Thread(new java.lang.Runnable() {  
                @Override  
                public void run() {  
                      
                    if (location == null){  
                        location = Sets.newHashSet();  
                        log.debug("MapperLocation's length:" + mapperLocations.length);  
                        for (Resource mapperLocation : mapperLocations) {  
                            String s = mapperLocation.toString().replaceAll("\\\\", "/");  
                            s = s.substring("file [".length(), s.lastIndexOf(mappingPath) + mappingPath.length());  
                            if (!location.contains(s)) {  
                                location.add(s);  
                                log.debug("Location:" + s);  
                            }  
                        }  
                        log.debug("Locarion's size:" + location.size());  
                    }  
  
                    try {  
                        Thread.sleep(delaySeconds * 1000);  
                    } catch (InterruptedException e2) {  
                        e2.printStackTrace();  
                    }  
                    refresh = true;  
  
                    System.out.println("========= Enabled refresh mybatis mapper =========");  
  
                    while (true) {  
                        try {  
                            for (String s : location) {  
                                runnable.refresh(s, beforeTime);  
                            }  
                        } catch (Exception e1) {  
                            e1.printStackTrace();  
                        }  
                        try {  
                            Thread.sleep(sleepSeconds * 1000);  
                        } catch (InterruptedException e) {  
                            e.printStackTrace();  
                        }  
  
                    }  
                }  
            }, "MyBatis-Mapper-Refresh").start();  
        }  
    }  
  
    /** 
     * 执行刷新 
     * @param filePath 刷新目录 
     * @param beforeTime 上次刷新时间 
     * @throws NestedIOException 解析异常 
     * @throws FileNotFoundException 文件未找到 
     * @author ThinkGem 
     */  
    @SuppressWarnings({ "rawtypes", "unchecked" })  
    private void refresh(String filePath, Long beforeTime) throws Exception {  
  
        // 本次刷新时间  
        Long refrehTime = System.currentTimeMillis();  
  
        // 获取需要刷新的Mapper文件列表  
        List<File> fileList = this.getRefreshFile(new File(filePath), beforeTime);  
        if (fileList.size() > 0) {  
            log.debug("Refresh file: " + fileList.size());  
        }  
        for (int i = 0; i < fileList.size(); i++) {  
            InputStream inputStream = new FileInputStream(fileList.get(i));  
            String resource = fileList.get(i).getAbsolutePath();  
            try {  
                  
                // 清理原有资源,更新为自己的StrictMap方便,增量重新加载  
                String[] mapFieldNames = new String[]{  
                    "mappedStatements", "caches",  
                    "resultMaps", "parameterMaps",  
                    "keyGenerators", "sqlFragments"  
                };  
                for (String fieldName : mapFieldNames){  
                    Field field = configuration.getClass().getDeclaredField(fieldName);  
                    field.setAccessible(true);  
                    Map map = ((Map)field.get(configuration));  
                    if (!(map instanceof StrictMap)){  
                        Map newMap = new StrictMap(StringUtils.capitalize(fieldName) + "collection");  
                        for (Object key : map.keySet()){  
                            try {  
                                newMap.put(key, map.get(key));  
                            }catch(IllegalArgumentException ex){  
                                newMap.put(key, ex.getMessage());  
                            }  
                        }  
                        field.set(configuration, newMap);  
                    }  
                }  
                  
                // 清理已加载的资源标识,方便让它重新加载。  
                Field loadedResourcesField = configuration.getClass().getDeclaredField("loadedResources");  
                loadedResourcesField.setAccessible(true);  
                Set loadedResourcesSet = ((Set)loadedResourcesField.get(configuration));  
                loadedResourcesSet.remove(resource);  
                  
                //重新编译加载资源文件。  
                XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(inputStream, configuration,   
                        resource, configuration.getSqlFragments());  
                xmlMapperBuilder.parse();  
            } catch (Exception e) {  
                throw new NestedIOException("Failed to parse mapping resource: '" + resource + "'", e);  
            } finally {  
                ErrorContext.instance().reset();  
            }  
            System.out.println("Refresh file: " + mappingPath + StringUtils.substringAfterLast(fileList.get(i).getAbsolutePath(), mappingPath));  
            if (log.isDebugEnabled()) {  
                log.debug("Refresh file: " + fileList.get(i).getAbsolutePath());  
                log.debug("Refresh filename: " + fileList.get(i).getName());  
            }  
        }  
        // 如果刷新了文件,则修改刷新时间,否则不修改  
        if (fileList.size() > 0) {  
            this.beforeTime = refrehTime;  
        }  
    }  
      
    /** 
     * 获取需要刷新的文件列表 
     * @param dir 目录 
     * @param beforeTime 上次刷新时间 
     * @return 刷新文件列表 
     */  
    private List<File> getRefreshFile(File dir, Long beforeTime) {  
        List<File> fileList = new ArrayList<File>();  
  
        File[] files = dir.listFiles();  
        if (files != null) {  
            for (int i = 0; i < files.length; i++) {  
                File file = files[i];  
                if (file.isDirectory()) {  
                    fileList.addAll(this.getRefreshFile(file, beforeTime));  
                } else if (file.isFile()) {  
                    if (this.checkFile(file, beforeTime)) {  
                        fileList.add(file);  
                    }  
                } else {  
                    System.out.println("Error file." + file.getName());  
                }  
            }  
        }  
        return fileList;  
    }  
  
    /** 
     * 判断文件是否需要刷新 
     * @param file 文件 
     * @param beforeTime 上次刷新时间 
     * @return 需要刷新返回true,否则返回false 
     */  
    private boolean checkFile(File file, Long beforeTime) {  
        if (file.lastModified() > beforeTime) {  
            return true;  
        }  
        return false;  
    }  
  
    /** 
     * 获取整数属性 
     * @param key 
     * @return 
     */  
    private static int getPropInt(String key) {  
        int i = 0;  
        try {  
            i = Integer.parseInt(getPropString(key));  
        } catch (Exception e) {  
        }  
        return i;  
    }  
  
    /** 
     * 获取字符串属性 
     * @param key 
     * @return 
     */  
    private static String getPropString(String key) {  
        return prop == null ? null : prop.getProperty(key);  
    }  
  
    /** 
     * 重写 org.apache.ibatis.session.Configuration.StrictMap 类 
     * 来自 MyBatis3.4.0版本,修改 put 方法,允许反复 put更新。 
     */  
    public static class StrictMap<V> extends HashMap<String, V> {  
  
        private static final long serialVersionUID = -4950446264854982944L;  
        private String name;  
  
        public StrictMap(String name, int initialCapacity, float loadFactor) {  
            super(initialCapacity, loadFactor);  
            this.name = name;  
        }  
  
        public StrictMap(String name, int initialCapacity) {  
            super(initialCapacity);  
            this.name = name;  
        }  
  
        public StrictMap(String name) {  
            super();  
            this.name = name;  
        }  
  
        public StrictMap(String name, Map<String, ? extends V> m) {  
            super(m);  
            this.name = name;  
        }  
  
        @SuppressWarnings("unchecked")  
        public V put(String key, V value) {  
            // ThinkGem 如果现在状态为刷新,则刷新(先删除后添加)  
            if (MapperRefresh.isRefresh()) {  
                remove(key);  
                MapperRefresh.log.debug("refresh key:" + key.substring(key.lastIndexOf(".") + 1));  
            }  
            // ThinkGem end  
            if (containsKey(key)) {  
                throw new IllegalArgumentException(name + " already contains value for " + key);  
            }  
            if (key.contains(".")) {  
                final String shortKey = getShortName(key);  
                if (super.get(shortKey) == null) {  
                    super.put(shortKey, value);  
                } else {  
                    super.put(shortKey, (V) new Ambiguity(shortKey));  
                }  
            }  
            return super.put(key, value);  
        }  
  
        public V get(Object key) {  
            V value = super.get(key);  
            if (value == null) {  
                throw new IllegalArgumentException(name + " does not contain value for " + key);  
            }  
            if (value instanceof Ambiguity) {  
                throw new IllegalArgumentException(((Ambiguity) value).getSubject() + " is ambiguous in " + name  
                        + " (try using the full name including the namespace, or rename one of the entries)");  
            }  
            return value;  
        }  
  
        private String getShortName(String key) {  
            final String[] keyparts = key.split("\\.");  
            return keyparts[keyparts.length - 1];  
        }  
  
        protected static class Ambiguity {  
            private String subject;  
  
            public Ambiguity(String subject) {  
                this.subject = subject;  
            }  
  
            public String getSubject() {  
                return subject;  
            }  
        }  
    }  
}  

MyBatis有几个不太好的地方,是当实体类别名重名的时候,Mapper XML有错误的时候,系统启动时会一直等待无法正常启动(其实是加载失败后又重新加载,进入了死循环),这里重写下SqlSessionFactoryBean.java文件,解决这个问题,在这个文件里也加入启动上面写的线程类:

1、修改实体类重名的时候抛出并打印异常,否则系统会一直递归造成无法启动。
2、MapperXML有错误的时候抛出并打印异常,否则系统会一直递归造成无法启动。
3、加入启动MapperRefresh.java线程服务。

我下面会把SqlSessionFactoryBean.java所涉及到需要修改的地方会标注出来。这里童鞋们可能会问去哪里找SqlSessionFactoryBean.java这个文件,我在这里卡壳了,这里也给大家说一下,这个类是在mybatis-spring-1.2.2.jar这个包里面,是一个class文件。

这不是坑人吗,怎么改这个SqlSessionFactoryBean.class文件?我的具体的思路就是,先把这个class文件反编译成java文件,然后再去修改这个java文件,然后再把这个java文件编译成class文件,然后再放进mybatis-spring-1.2.2.jar包里替换掉之前的SqlSessionFactoryBean.class

我自己看着都绕,我来一步一步教大家吧
1、去找一个反编译软件,很多反编译软件,我这里用的是jd-gui.exe
下载地址:http://download.csdn.net/detail/eyebrows_cs/5277552

2、把下载好的jd-gui.exe打开,然后把mybatis-spring-1.2.2.jar拖到里面,找到SqlSessionFactoryBean.class这个文件,呈现在你面前的就是一个反编译过来的java文件了

这里写图片描述

3、修改这个java文件,然后再编译成class文件,这步我一开始没想明白怎么弄,最后用了一个笨方法。在你的项目下新建一个包:右键src > new Package

这里写图片描述

点击Finish,然后再包下面建一个类,名字就叫:SqlSessionFactoryBean

4、把下面这一大坨代码,复制到SqlSessionFactoryBean.java里面,下面这一大坨代码,我在改动的地方都加上了“修改处”三个字!!!

package org.mybatis.spring;

import java.io.IOException;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.ibatis.builder.xml.XMLConfigBuilder;
import org.apache.ibatis.builder.xml.XMLMapperBuilder;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.reflection.factory.ObjectFactory;
import org.apache.ibatis.reflection.wrapper.ObjectWrapperFactory;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.TransactionFactory;
import org.apache.ibatis.type.TypeAliasRegistry;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.core.NestedIOException;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import com.alibaba.util.MapperRefresh;

public class SqlSessionFactoryBean
  implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent>
{
  private static final Log logger = LogFactory.getLog(SqlSessionFactoryBean.class);
  private Resource configLocation;
  private Resource[] mapperLocations;
  private DataSource dataSource;
  private TransactionFactory transactionFactory;
  private Properties configurationProperties;
  private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  private SqlSessionFactory sqlSessionFactory;
  private String environment = SqlSessionFactoryBean.class.getSimpleName();
  private boolean failFast;
  private Interceptor[] plugins;
  private TypeHandler<?>[] typeHandlers;
  private String typeHandlersPackage;
  private Class<?>[] typeAliases;
  private String typeAliasesPackage;
  private Class<?> typeAliasesSuperType;
  private DatabaseIdProvider databaseIdProvider;
  private ObjectFactory objectFactory;
  private ObjectWrapperFactory objectWrapperFactory;

  public void setObjectFactory(ObjectFactory objectFactory)
  {
    this.objectFactory = objectFactory;
  }

  public void setObjectWrapperFactory(ObjectWrapperFactory objectWrapperFactory)
  {
    this.objectWrapperFactory = objectWrapperFactory;
  }

  public DatabaseIdProvider getDatabaseIdProvider()
  {
    return this.databaseIdProvider;
  }

  public void setDatabaseIdProvider(DatabaseIdProvider databaseIdProvider)
  {
    this.databaseIdProvider = databaseIdProvider;
  }

  public void setPlugins(Interceptor[] plugins)
  {
    this.plugins = plugins;
  }

  public void setTypeAliasesPackage(String typeAliasesPackage)
  {
    this.typeAliasesPackage = typeAliasesPackage;
  }

  public void setTypeAliasesSuperType(Class<?> typeAliasesSuperType)
  {
    this.typeAliasesSuperType = typeAliasesSuperType;
  }

  public void setTypeHandlersPackage(String typeHandlersPackage)
  {
    this.typeHandlersPackage = typeHandlersPackage;
  }

  public void setTypeHandlers(TypeHandler<?>[] typeHandlers)
  {
    this.typeHandlers = typeHandlers;
  }

  public void setTypeAliases(Class<?>[] typeAliases)
  {
    this.typeAliases = typeAliases;
  }

  public void setFailFast(boolean failFast)
  {
    this.failFast = failFast;
  }

  public void setConfigLocation(Resource configLocation)
  {
    this.configLocation = configLocation;
  }

  public void setMapperLocations(Resource[] mapperLocations)
  {
    this.mapperLocations = mapperLocations;
  }

  public void setConfigurationProperties(Properties sqlSessionFactoryProperties)
  {
    this.configurationProperties = sqlSessionFactoryProperties;
  }

  public void setDataSource(DataSource dataSource)
  {
    if ((dataSource instanceof TransactionAwareDataSourceProxy))
    {
      this.dataSource = ((TransactionAwareDataSourceProxy)dataSource).getTargetDataSource();
    }
    else this.dataSource = dataSource;
  }

  public void setSqlSessionFactoryBuilder(SqlSessionFactoryBuilder sqlSessionFactoryBuilder)
  {
    this.sqlSessionFactoryBuilder = sqlSessionFactoryBuilder;
  }

  public void setTransactionFactory(TransactionFactory transactionFactory)
  {
    this.transactionFactory = transactionFactory;
  }

  public void setEnvironment(String environment)
  {
    this.environment = environment;
  }

  public void afterPropertiesSet()
    throws Exception
  {
    Assert.notNull(this.dataSource, "Property 'dataSource' is required");
    Assert.notNull(this.sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");

    this.sqlSessionFactory = buildSqlSessionFactory();
  }

  protected SqlSessionFactory buildSqlSessionFactory()
    throws IOException
  {
    XMLConfigBuilder xmlConfigBuilder = null;
    Configuration configuration;
    if (this.configLocation != null) {
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();
    } else {
      if (logger.isDebugEnabled()) {
        logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
      }
      configuration = new Configuration();
      configuration.setVariables(this.configurationProperties);
    }

    if (this.objectFactory != null) {
      configuration.setObjectFactory(this.objectFactory);
    }

    if (this.objectWrapperFactory != null) {
      configuration.setObjectWrapperFactory(this.objectWrapperFactory);
    }

    if (StringUtils.hasLength(this.typeAliasesPackage)) {
      String[] typeAliasPackageArray = StringUtils.tokenizeToStringArray(this.typeAliasesPackage, ",; \t\n");

      for (String packageToScan : typeAliasPackageArray) {
    	
    	  	// 修改处:ThinkGem 修改实体类重名的时候抛出并打印异常,否则系统会一直递归造成无法启动
	  		try {
	  			configuration.getTypeAliasRegistry().registerAliases(packageToScan,
	  					typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
	  		} catch (Exception ex) {
	  			logger.error("Scanned package: '" + packageToScan + "' for aliases", ex);
	  			throw new NestedIOException("Scanned package: '" + packageToScan + "' for aliases", ex);
	  		} finally {
	  			ErrorContext.instance().reset();
	  		}
	  		// 修改处:ThinkGem end
  		
        if (logger.isDebugEnabled()) {
          logger.debug("Scanned package: '" + packageToScan + "' for aliases");
        }
      }
    }

    if (!ObjectUtils.isEmpty(this.typeAliases)) {
      for (Class typeAlias : this.typeAliases) {
        configuration.getTypeAliasRegistry().registerAlias(typeAlias);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered type alias: '" + typeAlias + "'");
        }
      }
    }

    if (!ObjectUtils.isEmpty(this.plugins)) {
      for (Interceptor plugin : this.plugins) {
        configuration.addInterceptor(plugin);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered plugin: '" + plugin + "'");
        }
      }
    }

    if (StringUtils.hasLength(this.typeHandlersPackage)) {
      String[] typeHandlersPackageArray = StringUtils.tokenizeToStringArray(this.typeHandlersPackage, ",; \t\n");

      for (String packageToScan : typeHandlersPackageArray) {
        configuration.getTypeHandlerRegistry().register(packageToScan);
        if (logger.isDebugEnabled()) {
          logger.debug("Scanned package: '" + packageToScan + "' for type handlers");
        }
      }
    }

    if (!ObjectUtils.isEmpty(this.typeHandlers)) {
      for (TypeHandler typeHandler : this.typeHandlers) {
        configuration.getTypeHandlerRegistry().register(typeHandler);
        if (logger.isDebugEnabled()) {
          logger.debug("Registered type handler: '" + typeHandler + "'");
        }
      }
    }

    if (xmlConfigBuilder != null) {
      try {
        xmlConfigBuilder.parse();

        if (logger.isDebugEnabled())
          logger.debug("Parsed configuration file: '" + this.configLocation + "'");
      }
      catch (Exception ex) {
        throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);
      } finally {
        ErrorContext.instance().reset();
      }
    }

    if (this.transactionFactory == null) {
      this.transactionFactory = new SpringManagedTransactionFactory();
    }

    Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);
    configuration.setEnvironment(environment);

    if (this.databaseIdProvider != null) {
      try {
        configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
      } catch (SQLException e) {
        throw new NestedIOException("Failed getting a databaseId", e);
      }
    }

    if (!ObjectUtils.isEmpty(this.mapperLocations)) {
      for (Resource mapperLocation : this.mapperLocations) {
        if (mapperLocation == null) {
          continue;
        }
        try
        {
          XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(), configuration, mapperLocation.toString(), configuration.getSqlFragments());

          xmlMapperBuilder.parse();
        } catch (Exception e) {
        	
        	// 修改处:ThinkGem MapperXML有错误的时候抛出并打印异常,否则系统会一直递归造成无法启动
        	logger.error("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        	
          throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
        } finally {
          ErrorContext.instance().reset();
        }

        if (logger.isDebugEnabled()) {
          logger.debug("Parsed mapper file: '" + mapperLocation + "'");
        }
      }
      
      // 修改处:ThinkGem 启动刷新MapperXML定时器(有助于开发者调试)。
      new MapperRefresh(this.mapperLocations, configuration).run();
      
    }
    else if (logger.isDebugEnabled()) {
      logger.debug("Property 'mapperLocations' was not specified or no matching resources found");
    }

    return this.sqlSessionFactoryBuilder.build(configuration);
  }

  public SqlSessionFactory getObject()
    throws Exception
  {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }

    return this.sqlSessionFactory;
  }

  public Class<? extends SqlSessionFactory> getObjectType()
  {
    return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
  }

  public boolean isSingleton()
  {
    return true;
  }

  public void onApplicationEvent(ApplicationEvent event)
  {
    if ((this.failFast) && ((event instanceof ContextRefreshedEvent)))
    {
      this.sqlSessionFactory.getConfiguration().getMappedStatementNames();
    }
  }
}

5、接下来我们就需要把这个SqlSessionFactoryBean.java文件编译成class文件,然后再复制到mybatis-spring-1.2.2.jar包里面
重新部署你的项目 Servers > Tomcat 7.x > 右键你的项目 Remove deployment 然后再 Add Deployment…你的项目

去Tomcat 7的根目录找到对应的SqlSessionFactoryBean.class文件复制出来
这里写图片描述

这里记得检查一下编译过的class文件是否正确,将你编译好的SqlSessionFactoryBean.class文件再次拖入jd-gui.exe,看看是不是和上面写的代码对应!!!!这步很重要,我之前编译成功之后,检查发现文件都不对了,记得必须检查一下

检查无误之后,把SqlSessionFactoryBean.class复制到mybatis-spring-1.2.2.jar(是你本地项目中的jar)包中,替换原来的class文件

6、一切准备就绪,还剩下最后一个属性文件, 创建mybatis-refresh.properties文件,记得把文件格式改成UTF-8
这里写图片描述

打开文件,把下面的内容复制进去

#是否开启刷新线程
enabled=true
#延迟启动刷新程序的秒数
delaySeconds=60  
#刷新扫描间隔的时长秒数
sleepSeconds=3
#扫描Mapper文件的资源路径
mappingPath=mapper

7、一切准备就绪,准备起飞火箭,这里需要注意,如果启动项目报错,那就把项目下咱们刚才新建的那个SqlSessionFactoryBean.java文件重命名一下,或者直接删除即可,它已经没有利用价值了

8、启动项目,然后随便修改一个mapper.xml文件,然后稍等片刻,在控制台出现如下输出,就表示你成功啦

这里写图片描述

这样就不用重启项目,也能加载到你修改的mapper.xml文件了

好了,一切都结束了,下班了,88童鞋们

这里写图片描述

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值