一文上手MyBatis

1 原生MyBatis

1.1 Maven导入依赖

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

1.2 表结构

CREATE TABLE `tbl_employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(50) DEFAULT NULL,
`email` varchar(50) DEFAULT NULL,
`gender` int(11) DEFAULT NULL,
`d_id` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1004 DEFAULT CHARSET=utf8;

1.3 实体

public class Employee {
private Integer id;
private String lastName;
private String email;
private Integer gender;

1.4 配置 mybatis-config.xml 主配置文件

在classpath下新建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>
<!-- 环境们 -->
<environments default="development">
<!-- 具体的环境 -->
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mytest" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>
<!-- 引入SQL映射文件 -->
<mappers>
<mapper resource="EmployeeMapper.xml" />
</mappers>

</configuration>

1.5 HelloWorld

1.5.1 配置mapper文件

Classpath下新建 EmployeeMapper.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">

<!-- 配置SQL映射
namespace: 名称空间.
1. 随便写
2. Mapper接口开发,不能随便写,按照规定来写。
-->
<mapper namespace="suibian">
<!--
<select>: 定义查询语句
id: <select>的唯一标识
resultType: 结果集的映射类型。
#{id}: 获取参数值
-->
<select id="selectEmployee"
resultType="com.hongyu.mybatis.beans.Employee">
<!-- select * from tbl_employee where id = #{id} -->
select id, last_name lastName, email, gender from tbl_employee where id = #{id}
</select>
</mapper>

1.5.2 后台测试方法

    @Test
public void testSqlSessionFactory() throws IOException {

String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory
= new SqlSessionFactoryBuilder().build(inputStream);
System.out.println(sqlSessionFactory);

SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(sqlSession);

try {
// 第一个参数就是唯一标识,即映射文件中的namespace.查询标签的ID
// 第二个参数sql语句中的占位参数
Employee employee = sqlSession.selectOne("suibian.selectEmployee", 1003);
System.out.println(employee);
}finally {
sqlSession.close();
}
}

1.6 Mapper.xml文件与DAO结合使用

1.6.1 说明

在mybatis里,mapper就相当于是DAO的概念

绑定Mapper.xml与DAO文件,namespace写成DAO的全类名,查询标签的id写成DAO中方法的名字。

1.6.2 EmployeeMapper.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">

<!-- 配置SQL映射
namespace: 名称空间.
1. 随便写
2. Mapper接口开发,不能随便写,按照规定来写。
-->
<mapper namespace="com.hongyu.mybatis.dao.EmployeeDao">
<!--
<select>: 定义查询语句
id: <select>的唯一标识
resultType: 结果集的映射类型。
#{id}: 获取参数值
-->
<!-- public Employee getEmployeeById(Integer id); -->
<!-- id值必须和Dao接口的方法名一致 -->
<select id="getEmployeeById"
resultType="com.hongyu.mybatis.beans.Employee">
select id, last_name lastName, email, gender from tbl_employee where id = #{id}
</select>
</mapper>

1.6.3 EmployeeDao接口

package com.hongyu.mybatis.dao;
import com.hongyu.mybatis.beans.Employee;
public interface EmployeeDao {
public Employee getEmployeeById(Integer id);
}

1.6.4 后台测试方法

    @Test
public void testMapperInterface() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
System.out.println(sqlSessionFactory);
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(sqlSession);
try {
EmployeeDao dao = sqlSession.getMapper(EmployeeDao.class);
Employee employee = dao.getEmployeeById(1003);
System.out.println(employee);
}finally {
sqlSession.close();
}
}

1.7 mybatis-config.xml高级

1.7.1 单独配置属性

<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver" />
</properties>

<!-- 环境们 -->
<environments default="development">
<!-- 具体的环境 -->
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="jdbc:mysql://localhost:3306/mytest" />
<property name="username" value="root" />
<property name="password" value="admin" />
</dataSource>
</environment>
</environments>

1.7.2 将数据库配置整个抽出去

1.7.2.1 新建db.properties文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytest
jdbc.username=root
jdbc.password=admin

1.7.2.2 修改mybatis配置文件

<properties resource="db.properties" />

<!-- 环境们 -->
<environments default="development">
<!-- 具体的环境 -->
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>

1.7.3 设置项

1.7.3.1 设置表名下划线,实体是驼峰命名法的映射

<!-- 设置项 -->
<settings>
<!-- 设置下划线到驼峰的映射,表名可以是下划线的方式,实体是驼峰的,可自动映射,例如:last_name和lastName -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

false则不映射

1.7.4 设置别名

1.7.4.1 设置某个类的别名

<!-- 设置别名 -->
<typeAliases>
<!-- alias 不写的话, 默认的别名就是不带包名的类名,别名不区分大小写 -->
<typeAlias type="com.hongyu.mybatis.beans.Employee" alias="employee" />

</typeAliases>

映射文件中直接使用别名

<select id="getEmployeeById" resultType="employee">
select id, last_name , email, gender from tbl_employee where id = #{id}
</select>

1.7.4.2 为某个包及子包下的类批量取默认别名

<!-- 设置别名 -->
<typeAliases>
<!-- alias 不写的话, 默认的别名就是不带包名的类名,别名不区分大小写 -->
<package name="com.hongyu.mybatis.beans" />
</typeAliases>

如果不想用默认的别名,可以使用注解 @Alias(“employeeEntity”) 指定自定义别名,前提是必须配置 package包指定标签

import org.apache.ibatis.type.Alias;
@Alias("employeeEntity")
public class Employee {

1.7.5 mybatis预制了很多别名

Mybatis已经为很多基本类型取好了别名,例如:map、hashmap、list、int、integer等等。

建议使用全类名,比较清晰

1.7.6 批量声明映射文件

批量声明要求Mapper.xml必须与DAO文件同位置,且同名

<!-- 引入SQL映射文件 -->
<mappers>
<!--<mapper resource="EmployeeMapper.xml" />-->
<package name="com.hongyu.mybatis.dao" />
</mappers>

Dao文件改名为: com.hongyu.mybatis.dao.EmployeeMapper

Mapper文件增加包名:com/hongyu/mybatis/dao/EmployeeMapper.xml

1.8 增、删、改的实现

1.8.1 新增

// 新建
public void addEmployee(Employee employee);

<!-- public void addEmployee(Employee employee);
parameterType指定参数类型,可以省略不配置,可以自动识别 -->
<insert id="addEmployee"
parameterType="com.hongyu.mybatis.beans.Employee">
INSERT INTO tbl_employee(last_name, email, gender) VALUE (#{lastName}, #{email}, #{gender})
</insert>

1.8.2 更新

// 修改
public void updateEmployee(Employee employee);

<!-- public void updateEmployee(Employee employee); -->
<update id="updateEmployee" >
UPDATE tbl_employee SET last_name=#{lastName}, email=#{email}, gender=#{gender} WHERE id=#{id}
</update>

1.8.3 删除

// 删除
public void deleteEmployee(Integer id);

<!-- public void deleteEmployee(Integer id); -->
<delete id="deleteEmployee" >
DELETE FROM tbl_employee WHERE id=#{id}
</delete>

1.9 得到增、删、改操作的返回值

修改DAO接口的返回值即可,Integer或boolean都可以
// 新建
public Integer addEmployee(Employee employee);

// 修改
public Integer updateEmployee(Employee employee);

// 删除
public Integer deleteEmployee(Integer id);

1.10 数据自增的数据,获得主键的值

Insert标签中增加属性useGeneratedKeys、keyProperty就可以,keyProperty=”id” 这里的id是表的主键值,不是实体的

<insert id="addEmployee" parameterType="com.hongyu.mybatis.beans.Employee"
useGeneratedKeys="true" keyProperty="id"
>
INSERT INTO tbl_employee(last_name, email, gender) VALUE (#{lastName}, #{email}, #{gender})
</insert>

这样配置后,执行新增后,实体中就有id的值了

1.11 参数传递

1.11.1 单个普通参数

就是参数是1个,而且是基本类型,可以 #{随便写},因为mybatis不会进行任何处理。

例如:

<!-- public Employee getEmployeeById(Integer id); -->
<!-- id值必须和Dao接口的方法名一致 -->
<select id="getEmployeeById" resultType="employeeEntity">
select id, last_name , email, gender from tbl_employee where id = #{aaa}
</select>

1.11.2 多个参数

多个参数只允许 #{arg0}, #{arg1} 或 #{param1}, #{param2}

public Employee getEmployeeByIdAndLastName(Integer id, String lastName);

<!-- public Employee getEmployeeByIdAndLastName(Integer id, String lastName); -->
<select id="getEmployeeByIdAndLastName" resultType="employeeEntity">
select id, last_name , email, gender from tbl_employee where id = #{arg0} AND last_name=#{arg1}
</select>

1.11.3 命名参数

就是对多个参数的优化,使用@Param注解

public Employee getEmployeeByIdAndLastName(@Param("id") Integer id, 
@Param("lastName") String lastName);


<!-- public Employee getEmployeeByIdAndLastName(Integer id, String lastName); -->
<select id="getEmployeeByIdAndLastName" resultType="employeeEntity">
select id, last_name , email, gender from tbl_employee where id = #{id} AND last_name=#{lastName}
</select>

1.11.4 POJO参数

直接写Entity的属性值就可以,参见1.8增删改

如果传了两个pojo,需要使用上一节的命名参数@Param注解,例如:emp,则参数写成 #{emp.id}

1.11.5 Map参数

参数按Map传的写

public Employee getEmployeeByMap(Map<String, Object> map);

<!-- public Employee getEmployeeByMap(Map<String, Object> map); -->
<select id="getEmployeeByMap" resultType="employeeEntity">
select id, last_name , email, gender from tbl_employee where id = #{id} AND last_name=#{lastName}
</select>

测试程序:

Map<String, Object> map = new HashMap<>();
map.put("id", 1003);
map.put("lastName", "婷婷");
Employee employee = dao.getEmployeeByMap(map);

1.11.6 List或Array参数

也会封装成Map,数组的key是array,List的key是list

#{array} #{list}

1.12 ${}的使用

#{} 是在sql中设置?,然后传入参数

是 直 接 替 换 s q l 语 句 中 的 地 方 , {} 是直接替换sql语句中的地方, sql{}可以写表名,也可以写字段名,这个是#{}做不到的

1.13 高级查询

1.13.1 查询多条记录返回List

// 查询多条语句返回List集合

public List getEmps();

<!-- public List<Employee> getEmps(); -->
<select id="getEmps" resultType="employeeEntity">
select id, last_name , email, gender from tbl_employee
</select>

注意:即使返回的是List,但resultType需要填写List中对象的类型

1.13.2 查询1条记录返回Map

结果的Map,key是查询的字段名,value是值

{gender=1, last_name=刚哥, id=1001, email=gg@1.com}

// 查询1条记录返回Map集合
public Map<String, Object> getEmpByIdReturnMap(Integer id);

<!-- public Map<String, Object> getEmpByIdReturnMap(Integer id); -->
<select id="getEmpByIdReturnMap" resultType="map" >
select id, last_name , email, gender from tbl_employee where id = #{id}
</select>

1.13.3 查询多条数据返回Map

需要借助注解@MapKey,指定Map的key

// 查询多条数据返回Map
@MapKey("id")
public Map<Integer, Employee> getEmpsReturnMap();

<!-- public Map<Integer, Employee> getEmpsReturnMap(); -->
<select id="getEmpsReturnMap"
resultType="com.hongyu.mybatis.beans.Employee">
select id, last_name , email, gender from tbl_employee
</select>

1.14 自定义映射

1.14.1 单表

public Employee getEmployeeById(Integer id);

<!-- public Employee getEmployeeById(Integer id); -->
<select id="getEmployeeById" resultMap="myEmp" >
select id, last_name , email, gender from tbl_employee where id = #{id}
</select>

<resultMap id="myEmp" type="com.hongyu.mybatis.beans.Employee" >
<id column="id" property="id" /> <!-- 映射主键 -->
<!-- 映射其他字段 -->
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender"/>
</resultMap>

1.14.2 表关联-级联写法

在Employee实体中增加 Dept 引用属性

public Employee getEmpAndDept(Integer id);
<select id="getEmpAndDept" resultMap="myEmpAndDept" >
SELECT e.id eid, e.last_name, e.email, e.gender, d.dept_id did, d.dept_name
FROM tbl_employee e JOIN tbl_dept d
ON e.d_id=d.dept_id
WHERE e.id = #{id}
</select>
<resultMap id="myEmpAndDept"
type="com.hongyu.mybatis.beans.Employee" >
<id column="eid" property="id"></id>
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender"/>
<result column="did" property="dept.deptId" />
<result column="dept_name" property="dept.deptName" />
</resultMap>

1.14.3 表关联-association写法

<resultMap id="myEmpAndDept" type="com.hongyu.mybatis.beans.Employee" >
<id column="eid" property="id" />
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender"/>
<association property="dept" javaType="com.hongyu.mybatis.beans.Dept">
<id column="did" property="deptId" />
<result column="dept_name" property="deptName" />
</association>
</resultMap>

1.14.4 分布查询

先建一个部门的deptMapper,然后EmployeeMapper引用

import com.hongyu.mybatis.beans.Dept;
public interface DeptMapperResultMap {
public Dept getDeptById(Integer id);
}

<mapper namespace="com.hongyu.mybatis.dao.DeptMapperResultMap">
<!-- public Dept getDeptById(Integer id); -->
<select id="getDeptById" resultType="com.hongyu.mybatis.beans.Dept" >
SELECT dept_id deptId, dept_name deptName FROM tbl_dept WHERE dept_id=#{id}
</select>
</mapper>

public Employee getEmpAndDeptStep(Integer id);
<select id="getEmpAndDeptStep" resultMap="myEmpAndDeptStep">
SELECT id, last_name, email, gender, d_id
FROM tbl_employee
WHERE id=#{id}
</select>

<resultMap id="myEmpAndDeptStep"
type="com.hongyu.mybatis.beans.Employee" >
<id column="id" property="id" />
<result column="last_name" property="lastName" />
<result column="email" property="email" />
<result column="gender" property="gender"/>
<!-- 分布查询 -->
<association property="dept" select="com.hongyu.mybatis.dao.DeptMapperResultMap.getDeptById"
column="d_id" >
</association>

</resultMap>

1.14.5 分布查询-延迟加载

在Mybatis全局配置文件中增加settings

<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 配置按需加载 -->
<setting name="aggressiveLazyLoading" value="false" />

1.14.6 集合类型联合属性

public Dept getDeptAndEmpsById(Integer id);

<select id="getDeptAndEmpsById" resultMap="myDeptAndEmps" >
SELECT d.dept_id did, d.dept_name, e.id eid, e.last_name, e.email, e.gender
FROM tbl_dept d LEFT JOIN tbl_employee e
ON d.dept_id=e.d_id
WHERE d.dept_id=#{id}
</select>
<resultMap id="myDeptAndEmps" type="com.hongyu.mybatis.beans.Dept" >
<id column="did" property="deptId" />
<result column="dept_name" property="deptName" />
<!-- ofType: 指定集合中元素的类型 -->
<collection property="emps"
ofType="com.hongyu.mybatis.beans.Employee" >
<id column="eid" property="id" />
<result property="lastName" column="last_name" />
<result property="email" column="email" />
<result property="gender" column="gender" />
</collection>
</resultMap>

1.14.7 Collection分布查询

public List<Employee> getEmpsByDid(Integer did);

<select id="getEmpsByDid" resultType="com.hongyu.mybatis.beans.Employee" >
SELECT id, last_name lastName, email, gender
FROM tbl_employee
WHERE d_id=#{did}
</select>

public Dept getDeptAndEmpsByIdStep(Integer id);

<select id="getDeptAndEmpsByIdStep" resultMap="myDeptAndEmpsStep" >
SELECT dept_id did, dept_name
FROM tbl_dept
WHERE dept_id=#{id}
</select>
<resultMap id="myDeptAndEmpsStep"
type="com.hongyu.mybatis.beans.Dept" >
<id column="did" property="deptId" />
<result column="dept_name" property="deptName" />
<collection property="emps"
select="com.hongyu.mybatis.dao.EmployeeMapperResultMap.getEmpsByDid"
column="did" >
</collection>
</resultMap>

1.14.8 分布查询传多列值

传参时采用 {k1=v1, k2=v2} 的形式

Key是 参数占位的名字,即 #{k1}

Value是sql中对应的值

<resultMap id="myDeptAndEmpsStep" type="com.hongyu.mybatis.beans.Dept" >
<id column="did" property="deptId" />
<result column="dept_name" property="deptName" />
<!-- ofType: 指定集合中元素的类型 -->
<collection property="emps"
select="com.hongyu.mybatis.dao.EmployeeMapperResultMap.getEmpsByDid"
column="{did=did}" >
</collection>
</resultMap>

1.14.9 单独设置是否延迟加载

collection 标签 和 association 标签 都有 fetchType 属性

fetchType=“eager” 不延迟加载

fetchType=“lazy” 延迟加载

1.15 可重用sql片段

<sql id="empSelect" >
select id, last_name , email, gender
</sql>

<!-- public Employee getEmployeeById(Integer id); -->
<select id="getEmployeeById" resultMap="myEmp" >
<include refid="empSelect" /> from tbl_employee where id = #{id}
</select>

1.16 动态SQL

1.16.1 Where if

Where 标签主要是解决了第一个and的问题

public List<Employee> getEmpsByConditionIfWhere(Employee condition);

<select id="getEmpsByConditionIfWhere" resultMap="myEmp" >
SELECT id, last_name lastName, email, gender FROM tbl_employee
<where>
<if test="id!=null">
AND id=#{id}
</if>
<if test="lastName!=null&&lastName!=""">
AND last_name=#{lastName}
</if>
<if test="email!=null and email.trim()!=''">
AND email=#{email}
</if>
<if test="gender==0 or gender==1" >
AND gender=#{gender}
</if>
</where>
</select>

1.16.2 trim的使用

<!-- public List<Employee> getEmpsByConditionTrim(Employee condition); -->
<select id="getEmpsByConditionTrim" resultMap="myEmp" >
SELECT id, last_name , email, gender FROM tbl_employee

<!--
prefix 添加一个前缀
prefixOverrides 去掉一个前缀,去掉多个可以写成 and | or
suffix 添加一个后缀
suffixOverrides 去掉一个后缀,去掉多个可以写成 and | or
-->
<trim prefix=" where " prefixOverrides="and" suffix="" suffixOverrides="">
<if test="id!=null">
AND id=#{id}
</if>
<if test="lastName!=null&&lastName!=""">
AND last_name=#{lastName}
</if>
<if test="email!=null and email.trim()!=''">
AND email=#{email}
</if>
<if test="gender==0 or gender==1" >
AND gender=#{gender}
</if>
</trim>
</select>

1.16.3 set

主要解决多出的逗号的问题

update table
<set>
<if test=”XXX”>
XXX = #{XXX} ,
</if>
<if test=”XXX”>
XXX = #{XXX} ,
</if>
<if test=”XXX”>
XXX = #{XXX}
</if>
<set>

1.16.4 choose when otherwise

相当于case when,满足条件则不往下执行

<choose>
<when test=””></when>
<when test=””></when>
<when test=””></when>
<otherwise></otherwise>
</choose>

otherwise 是最后的默认条件

1.16.5 foreach

public List<Employee> getEmpsByIds(@Param("ids") List<Integer> ids);
<select id="getEmpsByIds" resultMap="myEmp">
SELECT id, last_name , email, gender FROM tbl_employee
WHERE id IN
<!--
collection 集合
item 单个元素
open 指定一个开始字符
close 指定一个结束字符
separator 元素与元素自己的分隔符
-->
<foreach collection="ids" item="currId" open="(" close=")" separator=",">
#{currId}
</foreach>
</select>

也可以完成批准添加、批量修改、批量删除

2 Mybatis SpringMVC Spring 整合

2.1 下载整合适配包

Mybatis-Spring    Mybatis     Spring
1.0.0/1.0.1 3.0.1-3.0.5 3.0.0+
1.0.2 3.0.6 3.0.0+
1.1.0+ 3.1.0+ 3.0.0+
1.3.0+ 3.4.0+ 3.0.0+

学习教程:

​ http://www.mybatis.org/spring/zh/index.html​

2.2 导入jar包

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.18.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

<!-- https://mvnrepository.com/artifact/commons-fileupload/commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mchange/c3p0 -->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>

2.3 配置web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">

<!-- 字符编码过滤器 -->
<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>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- Rest过滤器 -->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<!-- 初始化SpringIOC容器监听器 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!-- SpringMVC前端控制器 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>

2.4 配置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: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.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

<!-- 组件扫描 -->
<context:component-scan base-package="com.hongyu.ssm" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/" />
<property name="suffix" value=".jsp" />
</bean>

<!-- mvc -->
<mvc:default-servlet-handler />
<mvc:annotation-driven />

</beans>

2.5 配置 db.properties 文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mytest
jdbc.username=root
jdbc.password=admin

2.6 配置log4j

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>

2.7 配置 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>
<!-- 设置下划线到驼峰的映射,表名可以是下划线的方式,实体是驼峰的,可自动映射,例如:last_name和lastName -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 配置按需加载 -->
<setting name="aggressiveLazyLoading" value="false" />
</settings>
</configuration>

2.8 配置Spring配置文件

<?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:tx="http://www.springframework.org/schema/tx"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">
<!-- 组件扫描 -->
<context:component-scan base-package="com.hongyu.ssm" >
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!-- 数据源 -->
<!-- 引入配置文件 -->
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="user" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>

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

<!-- 基于注解的事务 -->
<tx:annotation-driven transaction-manager="dataSourceTransactionManager"/>

<!-- spring 整合 ssm -->
<!-- 1.SplSession对象的创建 管理-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" >
<property name="dataSource" ref="dataSource" />
<!-- mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
<!-- 配置Mybatis的Sql映射文件(指定路径,不需要同名同位置了) -->
<property name="mapperLocations" value="classpath:com/hongyu/ssm/dao/*.xml" />
<!-- 别名处理 -->
<property name="typeAliasesPackage" value="com.hongyu.ssm.beans" />
</bean>
<!-- 2.Mapper接口代理实现类对象的创建 管理
MapperScannerConfigurer 会为指定包下的dao接口实现代理实现类对象,并管理到IOC容器中
由于mybatis的DAO没有实现类,不能使用 @Repository注解标识实体类,因此只能使用下面这种方式注册实体类
-->
<mybatis-spring:scan base-package="com.hongyu.ssm.dao" />

</beans>

2.9 使用mybatis的DAO文件

@RestController
public class EmployeeAction {

@Autowired
private EmployeeMapper employeeMapper;

@RequestMapping("/emp/{id}")
public Employee getEmployeeById(@PathVariable("id") int id) {
return employeeMapper.getEmployeeById(id);
}

3 遇到的坑

坑:Spring文件中配置事务,导致服务无法正常启动

解决:Spring的命名空间问题,修改了Spring配置文件的头文件,问题解决

<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:tx="http://www.springframework.org/schema/tx"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd">