之前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框架的搭建,其实在真正的企业级开发中,做了这些是远远不够的,接下来我还要在这个框架中融入其他的东西!