1、基本概念
ssm:spring+springMVC+mybatis
2、開發環境
Eclipse mars + jdk1.7 + maven + tomcat7
3、使用maven構建web項目
3.1、首先,創建一個maven object
3.2、創建一個新的路徑、next
3.3、選擇 maven-archetype-webapp next
3.4 輸入artifact id 這個是項目的唯一標識 實際對應項目的名稱 group id一般是公司,組織的名稱反寫,groupid+artifactid就保證了一個項目的唯一性。
4.1、在pom.xml文件中引入jar包,各個包是干嘛的 都有說明,此處不在贅述。
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 3 <modelVersion>4.0.0</modelVersion> 4 <groupId>com.hbst.www</groupId> 5 <artifactId>BaseSsm_3</artifactId> 6 <packaging>war</packaging> 7 <version>0.0.1-SNAPSHOT</version> 8 <name>BaseSsm_3 Maven Webapp</name> 9 <url>http://maven.apache.org</url> 10 <properties> 11 <!-- spring版本號 --> 12 <spring.version>4.0.2.RELEASE</spring.version> 13 <!-- mybatis版本號 --> 14 <mybatis.version>3.2.6</mybatis.version> 15 <!-- log4j日志文件管理包版本 --> 16 <slf4j.version>1.7.7</slf4j.version> 17 <log4j.version>1.2.17</log4j.version> 18 </properties> 19 20 21 <dependencies> 22 <dependency> 23 <groupId>junit</groupId> 24 <artifactId>junit</artifactId> 25 <version>3.8.1</version> 26 <scope>test</scope> 27 </dependency> 28 29 <!-- spring核心包 --> 30 <dependency> 31 <groupId>org.springframework</groupId> 32 <artifactId>spring-core</artifactId> 33 <version>${spring.version}</version> 34 </dependency> 35 36 <dependency> 37 <groupId>org.springframework</groupId> 38 <artifactId>spring-web</artifactId> 39 <version>${spring.version}</version> 40 </dependency> 41 <dependency> 42 <groupId>org.springframework</groupId> 43 <artifactId>spring-oxm</artifactId> 44 <version>${spring.version}</version> 45 </dependency> 46 <dependency> 47 <groupId>org.springframework</groupId> 48 <artifactId>spring-tx</artifactId> 49 <version>${spring.version}</version> 50 </dependency> 51 52 <dependency> 53 <groupId>org.springframework</groupId> 54 <artifactId>spring-jdbc</artifactId> 55 <version>${spring.version}</version> 56 </dependency> 57 58 <dependency> 59 <groupId>org.springframework</groupId> 60 <artifactId>spring-webmvc</artifactId> 61 <version>${spring.version}</version> 62 </dependency> 63 <dependency> 64 <groupId>org.springframework</groupId> 65 <artifactId>spring-aop</artifactId> 66 <version>${spring.version}</version> 67 </dependency> 68 69 <dependency> 70 <groupId>org.springframework</groupId> 71 <artifactId>spring-context-support</artifactId> 72 <version>${spring.version}</version> 73 </dependency> 74 75 <dependency> 76 <groupId>org.springframework</groupId> 77 <artifactId>spring-test</artifactId> 78 <version>${spring.version}</version> 79 </dependency> 80 <!-- mybatis核心包 --> 81 <dependency> 82 <groupId>org.mybatis</groupId> 83 <artifactId>mybatis</artifactId> 84 <version>${mybatis.version}</version> 85 </dependency> 86 <!-- mybatis/spring包 --> 87 <dependency> 88 <groupId>org.mybatis</groupId> 89 <artifactId>mybatis-spring</artifactId> 90 <version>1.2.2</version> 91 </dependency> 92 93 <!-- 導入java ee jar 包 --> 94 <dependency> 95 <groupId>javax</groupId> 96 <artifactId>javaee-api</artifactId> 97 <version>7.0</version> 98 </dependency> 99 100 <!-- 導入Mysql數據庫鏈接jar包 --> 101 <dependency> 102 <groupId>mysql</groupId> 103 <artifactId>mysql-connector-java</artifactId> 104 <version>5.1.36</version> 105 </dependency> 106 <!-- 導入dbcp的jar包,用來在applicationContext.xml中配置數據庫 --> 107 <dependency> 108 <groupId>commons-dbcp</groupId> 109 <artifactId>commons-dbcp</artifactId> 110 <version>1.2.2</version> 111 </dependency> 112 113 <!-- JSTL標簽類 --> 114 <dependency> 115 <groupId>jstl</groupId> 116 <artifactId>jstl</artifactId> 117 <version>1.2</version> 118 </dependency> 119 <!-- 日志文件管理包 --> 120 <!-- log start --> 121 <dependency> 122 <groupId>log4j</groupId> 123 <artifactId>log4j</artifactId> 124 <version>${log4j.version}</version> 125 </dependency> 126 127 128 <!-- servlet api --> 129 <dependency> 130 <groupId>javax.servlet</groupId> 131 <artifactId>javax.servlet-api</artifactId> 132 <version>3.0.1</version> 133 <scope>provided</scope> 134 </dependency> 135 136 <!-- 格式化對象,方便輸出日志 --> 137 <dependency> 138 <groupId>com.alibaba</groupId> 139 <artifactId>fastjson</artifactId> 140 <version>1.1.41</version> 141 </dependency> 142 143 144 <dependency> 145 <groupId>org.slf4j</groupId> 146 <artifactId>slf4j-api</artifactId> 147 <version>${slf4j.version}</version> 148 </dependency> 149 150 <dependency> 151 <groupId>org.slf4j</groupId> 152 <artifactId>slf4j-log4j12</artifactId> 153 <version>${slf4j.version}</version> 154 </dependency> 155 <!-- log end --> 156 <!-- 映入JSON --> 157 <dependency> 158 <groupId>org.codehaus.jackson</groupId> 159 <artifactId>jackson-mapper-asl</artifactId> 160 <version>1.9.13</version> 161 </dependency> 162 <!-- 上傳組件包 --> 163 <dependency> 164 <groupId>commons-fileupload</groupId> 165 <artifactId>commons-fileupload</artifactId> 166 <version>1.3.1</version> 167 </dependency> 168 <dependency> 169 <groupId>commons-io</groupId> 170 <artifactId>commons-io</artifactId> 171 <version>2.4</version> 172 </dependency> 173 <dependency> 174 <groupId>commons-codec</groupId> 175 <artifactId>commons-codec</artifactId> 176 <version>1.9</version> 177 </dependency> 178 </dependencies> 179 <build> 180 <finalName>BaseSsm_3</finalName> 181 </build> 182 </project>
4.2、Spring與MyBatis的整合
此次整合,並沒有使用mapper接口 而是使用sqlSessionTemplate接口來實現,使用mapper接口開發,會對每張表分別生成一個model,dao和一個mapper.xml,造成文件數過多。
4.2.1、SqlSessionTemplate
SqlSessionTemplate是MyBatis-spring的核心。這個類負責管理MyBatis的SqlSession,調用MyBatis的SQL方法。SqlSessionTemplate是線程安全的,可以被多個DAO所共享使用。
當調用SQL方法時,包含從映射器getMapper()方法返回的方法,SqlSessionTemplate將會保證使用的SqlSession是和當前Spring的事務相關的。此外,它管理session的生命周期,包含必要的關閉,提交或回滾操作。
SqlSessionTemplate實現了SqlSession,這就是說要對MyBatis的SqlSession進行簡易替換。
SqlSessionTemplate通常是被用來替代默認的MyBatis實現的DefaultSqlSession,因為它不能參與到Spring的事務中也不能被注入,因為它是線程不安全的。相同應用程序中兩個類之間的轉換可能會引起數據一致性的問題。
SqlSessionTemplate對象可以使用SqlSessionFactory作為構造方法的參數來創建。
4.2.2、介紹完基本概念,現在開始正式整合,首先創建jdbc.propreties文件 (文件編碼修改為 utf-8 )
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/db3
jdbc.username=root
jdbc.password=123456
jdbc.minIdle=30
jdbc.maxIdle=80
jdbc.maxWait=60000
jdbc.maxActive=80
jdbc.initialSize=20
jdbc.testWhileIdle=true
jdbc.testOnBorrow=false
jdbc.testOnReturn=false
jdbc.validationQuery=select 1
jdbc.validationQueryTimeout=1
jdbc.timeBetweenEvictionRunsMillis=600000
jdbc.numTestsPerEvictionRun=40
4.2.3、建立spring-mybatis.xml配置文件
這個文件就是用來完成spring和mybatis的整合的。這里面也沒多少行配置,主要的就是 自動掃描,自動注入,配置數據庫 。
<?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:context="http://www.springframework.org/schema/context" 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-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd"> <!-- 自動掃描 --> <context:component-scan base-package="com.hbst.basessm_3" /> <!-- proxy-target-class="true"強制使用CGLib代理,為false則spring會自動選擇 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <!-- 引入jdbc配置文件 --> <context:property-placeholder location="classpath:config/jdbc/jdbc.properties" /> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 隊列中的最小等待數 --> <property name="minIdle" value="${jdbc.minIdle}"></property> <!-- 隊列中的最大等待數 --> <property name="maxIdle" value="${jdbc.maxIdle}"></property> <!-- 最長等待時間,單位毫秒 --> <property name="maxWait" value="${jdbc.maxWait}"></property> <!-- 最大活躍數 --> <property name="maxActive" value="${jdbc.maxActive}"></property> <property name="initialSize" value="${jdbc.initialSize}"></property> <property name="testWhileIdle" value="${jdbc.testWhileIdle}"></property> <property name="testOnBorrow" value="${jdbc.testOnBorrow}"></property> <property name="testOnReturn" value="${jdbc.testOnReturn}"></property> <property name="validationQuery" value="${jdbc.validationQuery}" /> <property name="validationQueryTimeout" value="${jdbc.validationQueryTimeout}"></property> <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}"></property> <property name="numTestsPerEvictionRun" value="${jdbc.numTestsPerEvictionRun}"></property> </bean> <!-- 配置MyBitas SqlSessionFactoryBean --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="configLocation" value="classpath:config/mybatis/typeAliasMapper.xml" /> <property name="mapperLocations" value="classpath:config/mybatis/mappers/*/*Mapper.xml" /> <property name="dataSource" ref="dataSource" /> </bean> <!-- 配置SqlSessionTemplate --> <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype"> <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" /> </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/cn/hnust/mapping/*.xml"></property> --> <!-- </bean> --> <!-- DAO接口所在包名,Spring會自動查找其下的類 --> <!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> --> <!-- <property name="basePackage" value="com.cn.hnust.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> <!-- 使用注解的方式配置事務 --> <tx:annotation-driven transaction-manager="transactionManager" /> </beans>
4.2.4、我在上面配置 SqlSessionTemplate 的時候 指定了一個 typeAliasMapper.xml,這個文件用來配置實體別名,下面我們來創建它,他指定了一個分頁攔截插件,代碼會貼在最后,這里不再給出
<?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> <typeAlias alias="user" type="com.hbst.basessm_3.pojo.User"/> </typeAliases> <!-- mybatis 分頁攔截 --> <plugins> <plugin interceptor="com.hbst.basessm_3.dao.plugin.PageInterceptor"/> </plugins> </configuration>
4.2.5、創建spring配置文件applicationContext.xml 引入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:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.0.xsd"> <!-- 采用注釋的方式配置bean --> <context:annotation-config /> <task:annotation-driven/> <context:component-scan base-package="com.hbst.basessm_3" /> <!-- proxy-target-class="true"強制使用CGLib代理,為false則spring會自動選擇,否則事務不生效 --> <aop:aspectj-autoproxy proxy-target-class="true" /> <import resource="classpath:config/spring/spring-mybatis.xml" /> <!-- 模板引擎 --> <bean id="velocityEngine" class="org.springframework.ui.velocity.VelocityEngineFactoryBean" /> <!-- 異步線程 --> <bean id="taskExecutor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"> <property name="corePoolSize" value="10" /> <property name="maxPoolSize" value="30" /> </bean> </beans>
5、至此,spring和mybatis整合完成,下面整合springMVC 我這里創建spring-servlet.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> <mvc:annotation-driven /> <context:component-scan base-package="com.hbst.basessm_3" /> <bean id="defaultViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="contentType" value="text/html" /> <property name="prefix" value="/" /> <property name="suffix" value=".jsp" /> </bean> <!-- rest json related... start --> <bean id="mappingJacksonHttpMessageConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"> <property name="supportedMediaTypes"> <list> <value>application/json;charset=UTF-8</value> </list> </property> </bean> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> <property name="messageConverters"> <list> <ref bean="mappingJacksonHttpMessageConverter"/> </list> </property> </bean> <!-- rest json related... end --> </beans>
6、配置日志管理,創建log4j.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration SYSTEM "../dtd/log4j.dtd"> <!-- ========================== 自定義輸出格式說明================================ --> <!-- %p 輸出優先級,即DEBUG,INFO,WARN,ERROR,FATAL --> <!-- %r 輸出自應用啟動到輸出該log信息耗費的毫秒數 --> <!-- %c 輸出所屬的類目,通常就是所在類的全名 --> <!-- %t 輸出產生該日志事件的線程名 --> <!-- %n 輸出一個回車換行符,Windows平台為“/r/n”,Unix平台為“/n” --> <!-- %d 輸出日志時間點的日期或時間,默認格式為ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},輸出類似:2002年10月18日 22:10:28,921 --> <!-- %l 輸出日志事件的發生位置,包括類目名、發生的線程,以及在代碼中的行數。舉例:Testlog4.main(TestLog4.java:10) --> <!-- ========================================================================== --> <!-- ========================== 輸出方式說明================================ --> <!-- Log4j提供的appender有以下幾種: --> <!-- org.apache.log4j.ConsoleAppender(控制台), --> <!-- org.apache.log4j.FileAppender(文件), --> <!-- org.apache.log4j.DailyRollingFileAppender(每天產生一個日志文件), --> <!-- org.apache.log4j.RollingFileAppender(文件大小到達指定尺寸的時候產生一個新的文件), --> <!-- org.apache.log4j.WriterAppender(將日志信息以流格式發送到任意指定的地方) --> <!-- ========================================================================== --> <!--Threshold是個全局的過濾器,他將把低於所設置的level的信息過濾不顯示出來 --> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" debug="true" threshold="debug"> <!-- 控制台打印日志 --> <appender name="console" class="org.apache.log4j.ConsoleAppender"> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} | %t | %-5p | %c%m%n" /> </layout> </appender> <!-- 輸出到日志文件 --> <appender name="filelog_appender" class="org.apache.log4j.RollingFileAppender"> <!-- 設置File參數:日志輸出文件名 --> <param name="File" value="${BaseSsm_1.root}/log/BaseSsm_3_debug.log" /> <!-- 設置是否在重新啟動服務時,在原有日志的基礎添加新日志 --> <param name="Append" value="false" /> <!-- 設置文件大小 --> <param name="MaxFileSize" value="10MB" /> <!-- 設置文件備份 --> <param name="MaxBackupIndex" value="300" /> <!-- 設置輸出文件項目和格式 --> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} | %t | %-5p | %c %m%n" /> </layout> </appender> <category name="org.apache.log4j"> <priority value="warn" /> </category> <logger name="org.springframework"> <!-- <level value="info" /> --> <level value="debug" /> </logger> <logger name="com.opensymphony.xwork2"> <!-- <level value="info" /> --> <level value="debug" /> </logger> <!-- org.apache.axis2 | org.apache.struts2 --> <logger name="org.apache.axis2"> <level value="info" /> </logger> <logger name="org.apache.axiom"> <level value="warn" /> </logger> <logger name="org.apache.struts2"> <!-- <level value="info" /> --> <level value="debug" /> </logger> <logger name="org.apache.struts2.json"> <level value="debug" /> </logger> <logger name="org.apache.ibatis"> <level value="debug" /> </logger> <logger name="org.mybatis"> <level value="debug" /> </logger> <logger name="java.sql"> <level value="debug" /> </logger> <root> <priority value="debug" /> <appender-ref ref="console" /> <appender-ref ref="filelog_appender" /> </root> </log4j:configuration>
7、配置web.xml 在web.xm中引入spring配置文件、springMVC的配置文件和log4j.xml文件
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <display-name>Archetype Created Web Application</display-name> <!-- RequestContextListener --> <listener> <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class> </listener> <!-- 指定Web根目錄 --> <context-param> <param-name>webAppRootKey</param-name> <param-value>BaseSsm_1.root</param-value> </context-param> <!-- FMT i18n Begin --> <context-param> <param-name>javax.servlet.jsp.jstl.fmt.localizationContext</param-name> <param-value>i18n/lang_messages</param-value> </context-param> <filter> <filter-name>SetCharacterEncoding</filter-name> <filter-class>com.hbst.basessm_1.util.filter.SetCharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>SetCharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- FMT i18n End --> <!-- 字符集過濾器 --> <filter> <filter-name>CharacterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 日志管理配置 --> <listener> <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class> </listener> <context-param> <param-name>log4jConfigLocation</param-name> <param-value>classpath:log4j.xml</param-value> </context-param> <!-- 60s 檢測日志配置 文件變化 --> <context-param> <param-name>log4jRefreshInterval</param-name> <param-value>60000</param-value> </context-param> <!-- Spring管理配置 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 加載Spring配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:config/spring/applicationContext.xml </param-value> </context-param> <!-- Spring MVC配置 --> <servlet> <servlet-name>Dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <!-- 自定義spring mvc的配置文件名稱和路徑 --> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:config/spring/spring-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- spring mvc 請求后綴 --> <servlet-mapping> <servlet-name>Dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app>
8、最后的目錄結構是這樣的,源代碼已經提交github,有需要的可以下載源碼看看,我這里提交的項目是basessm_1,跟basessm_3的結構是一樣的,只需要修改下配置文件即可。
github地址是 https://github.com/1428977695/BaseSsm_3/tree/master/BaseSsm_1
9、測試,我這里使用basessm_1來測試
9.1、將項目部署到tomcat上,打開瀏覽器http://localhost:8080/BaseSsm_1
9.2、出現helloword,說明項目已經啟動成功了,下面我們進行數據交互測試,
首先創建數據庫,我這里創建user表 就兩個字段 將這兩個字段的值 顯示在頁面上
9.3、創建實體
9.4、創建mapper文件
9.5、配置實體別名映射
9.6、創建接口
9.7、創建實現類
9.8、這里將幾個基礎的類如baseDao.java PageInterceptor.java文件也放上來
9.8.1、接口IBaseDao
package com.hbst.basessm_1.dao; import java.util.List; import java.util.Map; public interface IBaseDao { /** * @Author:Dean * @Description:保存 * @param statement * SQLID * @param parameter * 參數 * @return boolean true 成功,false 失敗 * @Date 2015年12月31日 */ public boolean insert(String statement, Object parameter); /** * @Author:Dean * @Description:更新 * @param statement * SQLID * @param parameter * 參數 * @return boolean true 成功,false 失敗 * @Date 2015年12月31日 */ public boolean update(String statement, Object parameter); /** * @Author:Dean * @Description:刪除 * @param statement * SQLID * @param parameter * 參數 * @return boolean true 成功,false 失敗 * @Date 2015年12月31日 */ public boolean delete(String statement, Object parameter); /** * @Author:Dean * @Description:查詢單條數據 * @param statement * SQLID * @param parameter * 參數 * @return Object * @Date 2015年12月31日 */ public Object findOneByCustom(String statement, Object parameter); /** * @param <T> * @Author:Dean * @Description: 查詢集合列表 * @param statement * SQLID * @param parameter * 參數 * @return List<Object> * @Date 2015年12月31日 */ public <T> List<T> findListByCustom(String statement, Object parameter); /** * @param <T> * @Author:Dean * @Description: 分頁查詢 * @param statement * SQLID * @param parameter * 參數 * @return List<Object> * @Date 2015年12月31日 */ public Map<String,Object> findPageByCustom(String statement, Object parameter); }
9.8.2、實現類basedao
package com.hbst.basessm_1.dao.impl; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.beanutils.PropertyUtils; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.ExecutorException; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.ParameterMapping; import org.apache.ibatis.mapping.ParameterMode; import org.apache.ibatis.reflection.MetaObject; import org.apache.ibatis.reflection.property.PropertyTokenizer; import org.apache.ibatis.scripting.xmltags.ForEachSqlNode; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.type.TypeHandler; import org.apache.ibatis.type.TypeHandlerRegistry; import org.mybatis.spring.SqlSessionTemplate; import org.mybatis.spring.SqlSessionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Repository; import com.hbst.basessm_1.dao.IBaseDao; import com.hbst.basessm_1.util.constant.CodeConstant; import com.hbst.basessm_1.util.exception.BusinessException; import net.sf.json.JSONObject; @Repository("baseDao") public class BaseDao implements IBaseDao { @Autowired private SqlSessionTemplate sqlSessionTemplate; private long ROW_NUMBER = 0; private long ZERO = 0; public boolean insert(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } ROW_NUMBER = sqlSessionTemplate.insert(statement, parameter); return ROW_NUMBER > ZERO ? true : false; } public boolean update(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } ROW_NUMBER = sqlSessionTemplate.update(statement, parameter); return ROW_NUMBER > ZERO ? true : false; } public boolean delete(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } ROW_NUMBER = sqlSessionTemplate.delete(statement, parameter); return ROW_NUMBER > ZERO ? true : false; } public Object findOneByCustom(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } return sqlSessionTemplate.selectOne(statement, parameter); } public <T> List<T> findListByCustom(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } return sqlSessionTemplate.selectList(statement, parameter); } @SuppressWarnings("unchecked") public Map<String,Object> findPageByCustom(String statement, Object parameter) { if (null == parameter || null == statement) { throw new IllegalArgumentException(" Parameter Is Null."); } HashMap<String,Object> retMap = new HashMap<String,Object>(); //是否為分頁查詢 JSONObject jsonObject = JSONObject.fromObject(parameter); if (!(jsonObject.containsKey("pageNO") && null != jsonObject.get("pageNO") && jsonObject.containsKey("records") && null != jsonObject.get("records"))) { throw new BusinessException(CodeConstant.PARAMS_ERROR); } Integer pageNO = (Integer) jsonObject.get("pageNO") ; Integer records = (Integer) jsonObject.get("records"); if(pageNO!=null && pageNO>0 && records!=null && records>0){ retMap.put("recordsTotal", this.getTotalCount(statement, parameter)); retMap.put("data",sqlSessionTemplate.selectList(statement, parameter)); return retMap; } retMap.put("data",sqlSessionTemplate.selectList(statement, parameter)); return retMap; } /** * get total count * * @param sqlSession * @param statementName * @param values * @return */ private Integer getTotalCount(String statementName, Object values) { Map parameterMap = toParameterMap(values); Integer count = 0; try { MappedStatement mst = sqlSessionTemplate.getSqlSessionFactory() .getConfiguration().getMappedStatement(statementName); BoundSql boundSql = mst.getBoundSql(parameterMap); String sql = " select count(*) total_count from (" + boundSql.getSql() + ") as total"; Connection con = SqlSessionUtils .getSqlSession(sqlSessionTemplate.getSqlSessionFactory(), sqlSessionTemplate.getExecutorType(),sqlSessionTemplate.getPersistenceExceptionTranslator()) .getConnection(); PreparedStatement pstmt = con.prepareStatement(sql); // BoundSql countBS = new // BoundSql(mst.getConfiguration(),sql,boundSql.getParameterMappings(),parameterMap); setParameters(pstmt, mst, boundSql, parameterMap); ResultSet rs = pstmt.executeQuery(); if (rs.next()) { count = rs.getInt("total_count"); } rs.close(); con.close(); pstmt.close(); } catch (Exception e) { count = 0; e.printStackTrace(); throw new RuntimeException(e); } return count; } /** * 對SQL參數(?)設值,參考org.apache.ibatis.executor.parameter. * DefaultParameterHandler * * @param ps * @param mappedStatement * @param boundSql * @param parameterObject * @throws SQLException */ private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException { ErrorContext.instance().activity("setting parameters") .object(mappedStatement.getParameterMap().getId()); List<ParameterMapping> parameterMappings = boundSql .getParameterMappings(); if (parameterMappings != null) { Configuration configuration = mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry = configuration .getTypeHandlerRegistry(); MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); PropertyTokenizer prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (typeHandlerRegistry .hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName .startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); if (value != null) { value = configuration.newMetaObject(value) .getValue( propertyName.substring(prop .getName().length())); } } else { value = metaObject == null ? null : metaObject .getValue(propertyName); } TypeHandler typeHandler = parameterMapping.getTypeHandler(); if (typeHandler == null) { throw new ExecutorException( "There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId()); } typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType()); } } } } protected Map toParameterMap(Object parameter) { if (parameter == null) { return new HashMap(); } if (parameter instanceof Map) { return (Map<?, ?>) parameter; } else { try { return PropertyUtils.describe(parameter); } catch (Exception e) { e.printStackTrace(); return null; } } } }
9.8.3、分頁攔截器
package com.hbst.basessm_1.dao.plugin;
import java.sql.Connection;
import java.sql.Statement;
import java.util.Properties;
import org.apache.ibatis.executor.resultset.ResultSetHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;
import net.sf.json.JSONObject;
/**
* @author tangguilin
* 分頁攔截器
*/
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class}),
@Signature(type = ResultSetHandler.class, method = "handleResultSets", args = {Statement.class})
})
public class PageInterceptor implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
if (invocation.getTarget() instanceof StatementHandler) {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
//獲取參數對象
DefaultParameterHandler parameterHander=(DefaultParameterHandler) metaStatementHandler.getValue("delegate.parameterHandler");
Object parameterObject = parameterHander.getParameterObject();
JSONObject jsonParameter = JSONObject.fromObject(parameterObject);
//是否分頁
if(jsonParameter!=null && jsonParameter.has("pageNO")){
Integer pageNO = jsonParameter.getInt("pageNO");
Integer records = jsonParameter.getInt("records");
BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
String sql = boundSql.getSql();
StringBuffer sb=new StringBuffer();
sb.append(sql);
sb.append(" limit ").append((pageNO-1)*records).append(" , ").append(records);
metaStatementHandler.setValue("delegate.boundSql.sql", sb.toString());
}
}
return invocation.proceed();
}
/**
* 攔截類型StatementHandler
*/
public Object plugin(Object target) {
if (target instanceof StatementHandler) {
return Plugin.wrap(target, this);
} else {
return target;
}
}
public void setProperties(Properties properties) {
}
}
9.8.4、返回碼文件
package com.hbst.basessm_1.util.constant;
/**
* 返回碼
*
* @author lanshiyan description: code碼為6位 每兩位為一個級別分別代表不同的意思 前兩位:級別 00 系統級別 01
*/
public interface CodeConstant {
/****************************************************************************/
/************************ BEGIN 00系統級別公共錯誤碼 *************************/
/****************************************************************************/
/**
* 成功
*/
public static final String SUCCESS = "000000";
/**
* 參數驗證錯誤碼
*/
public static final String PARAMS_ERROR = "000001";
public static final String PARAMS_ERROR_DESCRIPTION = "Invalid method required parameter";
/**
* 系統異常錯誤碼
*/
public static final String SYSTEM_ERROR = "000002";
public static final String SYSTEM_ERROR_DESCRIPTION = "Unknow system exception";
/****************************************************************************/
/************************ BEGIN 01業務級別登錄錯誤碼 **************************/
/****************************************************************************/
// ===========================================================================
// BEGIN 00公共錯誤碼
// ===========================================================================
/**
* 用戶名密碼錯誤
*/
public static final String USERNAME_PWD_ERROR = "010001";
/**
* 參數為空
*/
public static final String PARARM_IS_EMPTY = "010002";
/**
* 不存在此用戶
*/
public static final String SYSTEM_USER_NOT_EXISTS = "010003";
public static final String SYSTEM_USER_NOT_EXISTS_DESCRIPTION = "User not exists or bad user ID";
/**
* 密碼復雜度不符合要求
*/
public static final String SYSTEM_BAD_PASSWORD_COMPLEXITY = "010004";
public static final String SYSTEM_BAD_PASSWORD_COMPLEXITY_DESCRIPTION = "Invalid password of complexity";
/**
* 舊密碼錯誤
*/
public static final String SYSTEM_BAD_OLD_PASSWORD = "010005";
public static final String SYSTEM_BAD_OLD_PASSWORD_DESCRIPTION = "Invalid old password";
}
9.8.5、返回實體文件
package com.hbst.basessm_1.util.entity;
import java.io.Serializable;
/**
* 返回消息實體對象定義
*
* @author Dean 20160912
*/
public class ResultMessage implements Serializable {
private static final long serialVersionUID = 1L;
// 成功或失敗的錯誤碼,成功時返回000000
private String code;
// 失敗時返回的錯誤消息
private String codeDesc;
// 當需要返回值時返回值對象,如果是查詢列表,則返回queryList對象
private Object data;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getCodeDesc() {
return codeDesc;
}
public void setCodeDesc(String codeDesc) {
this.codeDesc = codeDesc;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public static long getSerialversionuid() {
return serialVersionUID;
}
@Override
public String toString() {
return "ResultMessage [code=" + code + ", codeDes=" + codeDesc + ", data=" + data + "]";
}
}
9.8.6、系統自定義異常類
package com.hbst.basessm_1.util.exception;
import com.hbst.basessm_1.util.baseUtil.ResourceUtils;
import com.hbst.basessm_1.util.constant.CodeConstant;
/**
* 系統自定義異常類。
*
*
*
*/
public class BusinessException extends RuntimeException {
private static final long serialVersionUID = 1L;
/**
* 錯誤碼。
*/
private String errorCode;
/**
* 問題
*/
private String errorDes;
/**
* 指定錯誤碼與錯誤描述的異常。
*
* @param errorCode
* 錯誤碼
* @param msg
* 異常信息
*/
public BusinessException(String errorCode, String msg) {
super(msg);
this.errorCode = errorCode;
this.errorDes = msg;
}
/**
* 指定錯誤碼與錯誤描述的異常。
*
* @param errorCode
* 錯誤碼
* @param msg
* 異常信息
*/
public BusinessException(String errorCode) {
super(ResourceUtils.getResultCodeDesc(errorCode));
this.errorCode = errorCode;
this.errorDes = (ResourceUtils.getResultCodeDesc(errorCode));
}
/**
* 未定義異常。
*/
public BusinessException() {
super(ResourceUtils.getResultCodeDesc(CodeConstant.SYSTEM_ERROR));
this.errorCode = CodeConstant.SYSTEM_ERROR;
}
public String getErrorDes() {
return errorDes;
}
public void setErrorDes(String errorDes) {
this.errorDes = errorDes;
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
}
9.9、現在創建controller
9.10、在index.jsp中加入jquery.js,用jq的ajax方法去請求后台
9.11、刷新頁面,點擊按鈕,會出現數據庫里面插入的值。
10、到這里 ssm基礎框架的整合,已經前后台交互就算完成。