之前Spring和SpringMVC已经整合成功了,现在开始整合MyBatis。
先在数据库中创建emp表:
DROP TABLE IF EXISTS `emp`; CREATE TABLE `emp` ( `id` varchar(64) NOT NULL, `name` varchar(100) NOT NULL, `age` int(11) DEFAULT NULL, `gender` int(11) DEFAULT NULL, `birthday` datetime DEFAULT NULL, `hiredate` datetime DEFAULT NULL, `job` varchar(10) DEFAULT NULL, `hobbies` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
在之前的spring-context.xml开始添加配置
1、配置注解扫描,扫描service包下的注解,主要是为了之后可以将@Service注解的类注入到Controller层进行使用
<!-- 开启注解扫描 start --> <context:annotation-config /> <context:component-scan base-package="com.sdusz.framework.ssm" use-default-filters="false"> <context:include-filter type="regex" expression="com.sdusz.framework.ssm.service*.*" /> </context:component-scan> <!-- 开启注解扫描 end -->
2、配置读取properties的bean,读取到的所有properties配置文件中的所有键值对,之后要用到其中的值只需要${key}即可使用
<!-- 加载properties配置文件 start --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="locations"> <list> <value>classpath:config/jdbc.properties</value> </list> </property> <!-- <property name="ignoreUnresolvablePlaceholders" value="true" /> --> </bean> <!-- 加载properties配置文件 end -->
3、配置数据源:这里我选择使用阿里的druid数据源,第一安全性高,第二异常的处理比其他数据源更为强大,第三由于阿里公司的业务偏向大数据,数据源设计自然也吸取了大数据高并发的一些理念进行设计,而且经过前人实践证明,执行效率确实是目前主流数据源中最高的。
<!-- 配置druid数据源 start --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="driverClassName" value="${jdbc.driverClassName}" /> <property name="filters" value="${jdbc.filters}" /> <property name="maxActive" value="${jdbc.maxActive}" /> <property name="initialSize" value="${jdbc.initialSize}" /> <property name="maxWait" value="${jdbc.maxWait}" /> <property name="minIdle" value="${jdbc.minIdle}" /> <property name="timeBetweenEvictionRunsMillis" value="${jdbc.timeBetweenEvictionRunsMillis}" /> <property name="minEvictableIdleTimeMillis" value="${jdbc.minEvictableIdleTimeMillis}" /> <property name="validationQuery" value="${jdbc.validationQuery}" /> <property name="testWhileIdle" value="${jdbc.testWhileIdle}" /> <property name="testOnBorrow" value="${jdbc.testOnBorrow}" /> <property name="testOnReturn" value="${jdbc.testOnReturn}" /> <property name="poolPreparedStatements" value="${jdbc.poolPreparedStatements}" /> <property name="maxOpenPreparedStatements" value="${jdbc.maxOpenPreparedStatements}" /> <property name="removeAbandoned" value="${jdbc.removeAbandoned}" /> <property name="removeAbandonedTimeout" value="${jdbc.removeAbandonedTimeout}" /> <property name="logAbandoned" value="${jdbc.logAbandoned}" /> </bean> <!-- 配置druid数据源 end -->
上面的bean中property对应的值,就是从jdbc.properties配置文件中读取的,jdbc.properties配置文件的内容如下:
####druid数据源配置 #链接字符串 jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8 #数据库驱动类名 jdbc.driverClassName=com.mysql.jdbc.Driver #用户名 jdbc.username=root #密码 jdbc.password=root #属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:监控统计用的filter:stat 日志用的filter:log4j 防御sql注入的filter:wall jdbc.filters=stat #最大连接池数量 jdbc.maxActive=20 #初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时 jdbc.initialSize=10 #获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配useUnfairLock属性为true使用非公平锁。 jdbc.maxWait=60000 #最小连接池数量 jdbc.minIdle=10 #有两个含义:1) Destroy线程会检测连接的间隔时间2) testWhileIdle的判断依据,详细看testWhileIdle属性的说明 jdbc.timeBetweenEvictionRunsMillis=60000 #一个连接在池中最小生存的时间,单位是毫秒 jdbc.minEvictableIdleTimeMillis=300000 #用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。 jdbc.validationQuery=SELECT 'x' #建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 jdbc.testWhileIdle=true #申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 jdbc.testOnBorrow=false #归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能 jdbc.testOnReturn=false #在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100 jdbc.maxOpenPreparedStatements=20 #是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql5.5以下的版本中没有PSCache功能,建议关闭掉。5.5及以上版本有PSCache,建议开启。要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。 jdbc.poolPreparedStatements=true #打开removeAbandoned功能 jdbc.removeAbandoned=true #1800秒,也就是30分钟 jdbc.removeAbandonedTimeout=1800 #关闭abanded连接时输出错误日志 jdbc.logAbandoned=true
4、配置MyBatis的SqlSssionFactory,mapperLocations配置为扫描src/main/mybatis目录下的所有.xml文件,就是所有的MyBatis的mapper.xml文件,另外设置mybatis的全局配置文件路径,这个可以不用配置,这样就使用默认配置。
<!-- 配置sqlSessionFactory start--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <!-- 自动扫描mapper文件 --> <property name="mapperLocations" value="classpath:mybatis/*.xml"></property> <!-- mybatis全局配置文件 --> <property name="configLocation" value="classpath:config/mybatis-config.xml"></property> </bean> <!-- 配置sqlSessionFactory end-->
mybatis-config.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> <settings> <!-- 配置全局性 cache 的 ( 开 / 关) default:true --> <setting name="cacheEnabled" value="false"/> <!-- 是否使用 懒加载 关联对象同 hibernate中的延迟加载 一样default:true --> <!-- <setting name="lazyLoadingEnabled" value="true"/> --> <!-- [当对象使用延迟加载时 属性的加载取决于能被引用到的那些延迟属性,否则,按需加载(需要的是时候才去加载)] --> <setting name="aggressiveLazyLoading" value="true"/> <!-- 是否允许单条sql 返回多个数据集(取决于驱动的兼容性) default:true --> <setting name="multipleResultSetsEnabled" value="true"/> <!-- 是否可以使用列的别名 (取决于驱动的兼容性) default:true--> <setting name="useColumnLabel" value="true"/> <!--允许JDBC 生成主键。需要驱动器支持。如果设为了true,这个设置将强制使用被生成的主键,有一些驱动器不兼容不过仍然可以执行。default:false--> <setting name="useGeneratedKeys" value="false"/> <!--指定 MyBatis 如何自动映射 数据基表的列 NONE:不隐射 PARTIAL:部分FULL:全部--> <setting name="autoMappingBehavior" value="PARTIAL"/> <!-- 这是默认的执行类型 SIMPLE :简单 REUSE:执行器可能重复使用prepared statements 语句 BATCH:执行器可以重复执行语句和批量更新 --> <setting name="defaultExecutorType" value="SIMPLE"/> <!-- 设置驱动等待数据响应的超时数默认没有设置--> <setting name="defaultStatementTimeout" value="25000"/> <!--是否启用 行内嵌套语句defaut:false--> <setting name="safeRowBoundsEnabled" value="false"/> <!-- [是否 启用数据中 A_column 自动映射 到 java类中驼峰命名的属性 default:fasle] --> <setting name="mapUnderscoreToCamelCase" value="false"/> <!-- 设置本地缓存范围 session:就会有数据的共享statement:语句范围 (这样就不会有数据的共享 ) defalut:session --> <setting name="localCacheScope" value="SESSION"/> <!-- 设置但JDBC类型为空时,某些驱动程序 要指定值,default:OTHER --> <setting name="jdbcTypeForNull" value="NULL"/> <!-- 设置触发延迟加载的方法--> <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings> </configuration>
5、配置扫描dao接口所在的包
<!-- 扫描Dao接口所在的包名 start --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.sdusz.framework.ssm.mapper" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- 扫描Dao接口所在的包名 end -->
6、配置JdbcTemplate,本来集成了mybatis,为何还要jdbcTemplate呢?原因是mybatis的批量处理效率不高,而且不同数据库,写法也略有差异,使用更接近底层jdbc的jdbcTemplate进行批量操作,可以提升性能。
<!-- jdbcTemplate start --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg name="dataSource" ref="dataSource"/> </bean> <!-- jdbcTemplate end -->
7、配置数据源事务切面,进行事务管理,我将事务的回滚配置在service层,对于异常,进行回滚,如果有异常,不要捕获,直接网上抛,到时用一个统一的拦截器进行处理即可,对于需要用事务进行控制的方法,方法的命名一定要以下面事务切面中给出的前缀命名,当然,也可自己添加其它的。
<!-- 数据源事务管理器start --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 数据源事务管理器end --> <!-- 事务切面 start--> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" propagation="REQUIRED" read-only="true" /> <tx:method name="count*" propagation="REQUIRED" read-only="true" /> <tx:method name="find*" propagation="REQUIRED" read-only="true" /> <tx:method name="list*" propagation="REQUIRED" read-only="true" /> <tx:method name="search*" propagation="REQUIRED" read-only="true" /> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="insert*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="delete*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="modify*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="edit*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <!-- 批量操作最好用jdbcTemplate --> <tx:method name="batch*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice> <!-- 事务切面 end --> <!-- 事务aop切入点 start--> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* com.sdusz.framework.ssm.service.*.*(..)) " /> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" /> </aop:config> <!-- 事务aop切入点 end-->
下面进行测试
1、在com.sdusz.framework.ssm.entity添加反向生成的Emp.java类,对应数据库中的EMP表
package com.sdusz.framework.ssm.entity; import java.io.Serializable; import java.util.Date; import com.alibaba.fastjson.JSON; /** * 文件名称: com.sdusz.framework.ssm.entity.Emp.java * 初始作者: shenmengqi * 创建日期: 2016年3月18日 * 功能说明: 测试实体-员工实体类 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * Copyright (c) 2010-2011 .All rights reserved. */ public class Emp implements Serializable { /** * 序列化版本号 */ private static final long serialVersionUID = 1L; /** * 实体对应的数据库表名 */ public static final String TABLE_NAME = "emp"; /** * id */ private String id; /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 性别 */ private Integer gender; /** * 生日 */ private Date birthday; /** * 入职日期 */ private Date hiredate; /** * 工作 */ private String job; /** * 爱好 */ private String hobbies; /** * 方法描述: 获取年龄 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:31:17 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * Integer 年龄 */ public Integer getAge() { return age; } /** * 方法描述: 获取生日 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:31:40 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * Date 生日 */ public Date getBirthday() { return birthday; } /** * 方法描述: 获取性别 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:31:57 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * Integer 性别 */ public Integer getGender() { return gender; } /** * 方法描述: 获取入职日期 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:32:17 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * Date 入职日期 */ public Date getHiredate() { return hiredate; } /** * 方法描述: 获取爱好 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:32:37 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * String 爱好 */ public String getHobbies() { return hobbies; } /** * 方法描述: 获取id * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:33:02 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * String id */ public String getId() { return id; } /** * 方法描述: 获取工作 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:33:20 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * String 工作 */ public String getJob() { return job; } /** * 方法描述: 获取姓名 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:33:37 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return * String 姓名 */ public String getName() { return name; } /** * 方法描述: 设置年龄 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:33:54 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param age * 年龄 */ public void setAge(Integer age) { this.age = age; } /** * 方法描述: 设置生日 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:34:09 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param birthday * 生日 */ public void setBirthday(Date birthday) { this.birthday = birthday; } /** * 方法描述: 设置性别 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:34:30 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param gender * 性别 */ public void setGender(Integer gender) { this.gender = gender; } /** * 方法描述: 设置入职日期 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:34:56 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param hiredate * 入职日期 */ public void setHiredate(Date hiredate) { this.hiredate = hiredate; } /** * 方法描述: 设置爱好 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:35:16 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param hobbies * 爱好 */ public void setHobbies(String hobbies) { this.hobbies = hobbies; } /** * 方法描述: 设置id * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:35:37 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param id * id */ public void setId(String id) { this.id = id; } /** * 方法描述: 设置工作 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:35:53 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param job * 工作 */ public void setJob(String job) { this.job = job; } /** * 方法描述: 设置姓名 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:36:10 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param name * 姓名 */ public void setName(String name) { this.name = name; } /** * 方法描述: 重写toString()方法 * 初始作者: shenmengqi * 创建日期: 2016年3月22日-下午2:14:07 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ */ @Override public String toString() { return JSON.toJSONString(this); } }
2、com.sdusz.framework.ssm.mapper添加反向生成的EmpMapper.java类,删去其中的默认方法,添加自己需要的方法
package com.sdusz.framework.ssm.mapper; import org.apache.ibatis.annotations.Param; import com.sdusz.framework.ssm.entity.Emp; /** * 文件名称: com.sdusz.framework.ssm.mapper.EmpMapper.java * 初始作者: shenmengqi * 创建日期: 2016年3月18日 * 功能说明: 员工mapper * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * Copyright (c) 2010-2011 .All rights reserved. */ public interface EmpMapper { /** * 方法描述: 通过id获取员工信息 * 初始作者: shenmengqi * 创建日期: 2016年3月17日-下午1:45:04 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param id * 主键 * @return * Emp 员工实体 */ Emp selectEmpById(@Param("id") String id); }
3、在src/main/resources下的mybatis目录下添加反向生成的EmpMapper.xml文件,删除其中的无用内容,添加自己的语句,对应每个语句的id即为EmpMapper.java中每个方法的方法名
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <!-- 员工mapper --> <mapper namespace="com.sdusz.framework.ssm.mapper.EmpMapper" > <!-- 通过id获取员工信息--> <select id="selectEmpById" parameterType="java.lang.String" resultType="com.sdusz.framework.ssm.entity.Emp"> select * from emp where id=#{id,jdbcType=BIGINT} </select> </mapper>
4、com.sdusz.framework.ssm.service添加EmpService.java接口
package com.sdusz.framework.ssm.service; import com.sdusz.framework.ssm.entity.Emp; /** * 文件名称: com.sdusz.framework.ssm.service.EmpService.java * 初始作者: shenmengqi * 创建日期: 2016年3月18日 * 功能说明: 员工service * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * Copyright (c) 2010-2011 .All rights reserved. */ public interface EmpService { /** * 方法描述: 批量添加员工信息,用jdbc,另一方面为了测试事务的有效性 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:49:09 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return int * 插入成功的数量 * @throws Exception * 异常 */ int batchAddEmp() throws Exception; /** * 方法描述: 通过id获取员工信息 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:49:55 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param id * 员工id * @return * Emp 员工实体 */ Emp getEmpById(String id); }
5、com.sdusz.framework.ssm.serviceImpl添加EmpServiceImpl.java类,实现EmpService接口,对于JdbcTemplate还有EmpMapper直接使用@Autowired进行注入,第二个方法直接通过id获取员工信息,第一个方法使用JdbcTemplate批量插入员工信息(这里我没用批量插入的api,为了观察更清晰,用循环进行插入,看某一条出错,其余是否会回滚),顺便可以测试异常事务切面异常情况是否会进行回滚
package com.sdusz.framework.ssm.serviceImpl; import java.util.Date; import java.util.Random; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.jdbc.core.JdbcTemplate; import com.sdusz.framework.ssm.entity.Emp; import com.sdusz.framework.ssm.mapper.EmpMapper; import com.sdusz.framework.ssm.service.EmpService; import com.sdusz.framework.ssm.util.UUIDUtils; /** * 文件名称: com.sdusz.framework.ssm.serviceImpl.EmpServiceImpl.java * 初始作者: shenmengqi * 创建日期: 2016年3月18日 * 功能说明: 员工service实现类 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * Copyright (c) 2010-2011 .All rights reserved. */ public class EmpServiceImpl implements EmpService { /** * log4j日志对象 */ private static final Logger log = Logger.getLogger(EmpServiceImpl.class); /** * 员工mapper */ @Autowired private EmpMapper empMapper; /** * jdbcTemplate */ @Autowired private JdbcTemplate jdbcTemplate; /** * 方法描述: 用jdbcTemplate循环插入员工信息,一方面测试jdbcTemplate,另一方面测试事务有效性 * 初始作者: shenmengqi * 创建日期: 2016年3月17日-下午2:03:11 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @throws Exception * 异常对象 */ @Override public int batchAddEmp() throws Exception { int r = 0; for (int i = 0; i < new Random().nextInt(5); i++) { // log.info("开始插入第" + (i + 1) + "条"); Emp e = new Emp(); e.setId(UUIDUtils.get32UUID()); e.setName("name" + i); e.setJob("job" + i); e.setHobbies("hobbies" + i); e.setGender(new Random().nextInt(1)); e.setAge(new Random().nextInt(30)); e.setBirthday(new Date()); e.setHiredate(new Date()); // if (i == 7) { // log.error("出错了,回滚!"); // throw new Exception("出错了!"); // } int rr = jdbcTemplate.update("insert into emp values(?,?,?,?,?,?,?,?)", new Object[] { e.getId(), e.getName(), e.getAge(), e.getGender(), e.getBirthday(), e.getHiredate(), e.getJob(), e.getHobbies() }); if (rr == 1) { r++; } // log.info("第" + (i + 1) + "条插入成功"); } return r; } /** * 方法描述: 通过id获取员工信息,有缓存 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:51:55 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ */ @Override @Cacheable(value = "empCache", key = "#id+'~cache'", condition = "#id=='1406'") public Emp getEmpById(String id) { System.out.println("调用了getEmpById() 方法"); return empMapper.selectEmpById(id); } }
6、com.sdusz.framework.ssm.controller中添加EmpController.java类,EmpService使用@Resource进行注入,一般Controller层只是一个负责转发的层,所以,业务逻辑能在Service层处理就尽量在Service层处理,每一层必要的日志记录也是需要的。Controller遇到异常也不要捕获,向上抛出由统一的异常拦截器进行处理。
package com.sdusz.framework.ssm.controller; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.sdusz.framework.ssm.entity.Emp; import com.sdusz.framework.ssm.service.EmpService; /** * 文件名称: com.sdusz.framework.ssm.controller.EmpController.java * 初始作者: shenmengqi * 创建日期: 2016年3月18日 * 功能说明: 测试类,员工信息控制器 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * Copyright (c) 2010-2011 .All rights reserved. */ @Controller @RequestMapping("emp") public class EmpController { /** * 员工信息service */ @Resource private EmpService empService; /** * 方法描述: 批量添加员工信息 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:18:35 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @return int * 插入成功的记录数 * @throws Exception * 异常 */ @RequestMapping("/addEmps") @ResponseBody public int addEmps() throws Exception { return empService.batchAddEmp(); } /** * 方法描述: 通过id获取员工信息 * 初始作者: shenmengqi * 创建日期: 2016年3月18日-上午9:20:10 * 开始版本: 2.0.0 * ================================================= * 修改记录: * 修改作者 日期 修改内容 * ================================================ * * @param id * 员工id * @return * Emp 员工实体 */ @RequestMapping("/getEmpById") @ResponseBody public Emp getEmpById(@RequestParam String id) { return empService.getEmpById(id); } }
7、依次访问上面两个接口
http://ip:port/工程名/interfaces/emp/addEmps
先访问,如果批量插入成功返回影响的行数则表示jdbcTemplate可用
修改service实现类代码,制造异常,再测试,看是否回滚成功
http://ip:port/工程名/interfaces/emp/getEmpById?id=1406
直接返回员工信息json对象,则表示成功
至此就完成了一个简单Spring+SpringMVC+MyBatis框架的搭建,其实在真正的企业级开发中,做了这些是远远不够的,接下来我还要在这个框架中融入其他的东西!