MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射

花了两天时间搞MyEclipse搭建MyBatis开发环境,主要涉及对MyBatis的核心对象的掌握,以及配置文件(配置文件结构以及如何引入DTD文件);对SQL映射文件的学习,主要学习了以下的任务:1.实现条件查询(SQL映射文件、单条件查询、多条件查询、自定义查询结果映射)2.实现增删改操作(增加操作、修改操作、多参数入参操作、删除操作)3.实现高级结果映射(resultMap的配置、使用association处理一对一关联关系、使用collecion处理一对多关联关系)4.配置resultMap自动映射级别和MyBatis缓存(缓存暂时作为了解性学习,此处不深究)。以下的代码全都是按照这个步骤来实现的,有详细的注解。在学完这些基础之后可以再用动态SQL进行进一步的优化改造。至于mybatis的理论知识只有自己去补充学习,这里不做说明。

搭建MyBatis开发环境

使用MyBatis的开发步骤:
1.下载mybatis-3.2.2.jar包并导入工程
2.编写MyBatis核心配置文件(configguration.xml)
3.创建实体类-POJO
4.DAO层-SQL映射文件(mapper.xml)
5.创建测试类
(1)读取核心配置文件mybatis-config.xml
(2)创建SqlSessionFactory对象,读取配置文件
(3)创建SqlSession对象
(4)调用mapper文件进行数据操作

resultType:直接表示返回类型
* 基础数据类型
* 复杂数据类型
resultMap:对外部resultMap的引用
* 应用场景:
1. 数据库字段信息与对象属性不一致
2. 复杂的联合查询,*控制映射结果
注意:二者不能同时存在,本质上都是Map数据结构
resultMap:
数据结构:map
属性:id 、 type
子节点:result--------->(property、column)


思考问题:使用resultMap如何实现*灵活的控制映射结果,从而达到只对关心的属性进行复制填充?
resultMap自动映射匹配前提:字段名与属性名一致
rwsultMap的自动映射级别(autoMappingBehavior):
NONE:禁止自动匹配。
PARTIAL(默认):自动匹配所有属性,有内部嵌套(association、cellection)的除外。
FULL:自动匹配所有属性。


数据库结构:
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
工程文件结构:
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
MyEclipse下用Mybatis框架搭建工程并实现条件的增删查改及结果映射
代码中关于说明都有详细注解,不再一一赘述。
database.properties配置文件:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms
username=root
password=123456

log4j.properties日志配置文件:

log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.cn.smbms.dao=debug
log4j.logger.com.ibatis=debug 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug 
log4j.logger.java.sql.Connection=debug 
log4j.logger.java.sql.Statement=debug 
log4j.logger.java.sql.PreparedStatement=debug 
log4j.logger.java.sql.ResultSet=debug 
log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug
######################################################################################
# Console Appender  \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n
######################################################################################
# DailyRolling File  \u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n
log4j.logger.com.opensymphony.xwork2=error  

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>
	<!--引入database.properties文件 -->
	<!-- <properties resource="database.properties" /> -->
	<!--resource属性值的优先级高于property子节点配置的值 -->
	<properties resource="database.properties">
		<property name="driver" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/smbms" />
		<property name="username" value="root" />
		<property name="password" value="123456" />
	</properties>

	<settings>
		<!--配置mybatis的log实现为LOG4J -->
		<setting name="logImpl" value="LOG4J" />
		<!--设置resultMap的自动映射级别,NONE(禁止自动匹配),PARTIAL(默认)自动匹配所有属性,有内部嵌套(association、collection)的除外,FULL(自动匹配所有属性) -->
		<setting name="autoMappingBehavior" value="FULL" />
	</settings>

	<!--typeAliases元素配置类型别名,给实体类取别名,方便在mapper配置文件中的使用(起简化作用) -->
	<typeAliases>
		<!-- <typeAlias alias="user" type="com.smbms.pojo.User" /> -->
		<!--package属性会根据name的包名自动扫描JavaBean的类名,更加简化了使用typeAlias属性配置实体类的别名 -->
		<package name="com.smbms.pojo" />
	</typeAliases>

	<!--配置mybatis多套运行环境 -->
	<environments default="development">
		<environment id="development">
			<!--配置事务管理,采用JDBC的事务管理 -->
			<transactionManager type="JDBC"></transactionManager>
			<!--POOLED:mybatis自带的数据源,JNDI:基于tomcat的数据源 -->
			<dataSource type="POOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			</dataSource>
		</environment>
	</environments><!--comment -->

	<!--将mapper文件加入配置文件中 -->
	<mappers>
		<mapper resource="com/smbms/dao/user/UserMapper.xml" />
	</mappers>

</configuration>

UserMapper.java接口:

package com.smbms.dao.user;

import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import com.smbms.pojo.User;

public interface UserMapper {

	// 单一条件 查询用户列表(参数:对象入参)
	public List<User> getUserList(User user);

	// 根据用户名称查询用户列表(模糊查询)
	public List<User> getUserListByUserName(String userName);

	// 多条件 查询用户列表(参数:对象入参)---》复杂数据类型,封装成map,通过#{属性名}或者#{Map的key}即可获取传入值
	public List<User> getUserListByMap(Map<String, String> userMap);

	// 自定义查询(连表查询)使用resultType完成自动映射
	public List<User> getUserList1(User user);

	// 自定义查询(连表查询)通过resultMap自动映射结果
	public List<User> getUserList2(User user);

	// 用户增加(返回结果是条数,int类型;用用户对象入参)
	public int add(User user);

	// 修改用户信息(需要修改的User对象作为入参)
	public int modify(User user);

	// 根据用户id修改用户密码(多参数入参,这里只需要传入id和新密码,不适合传入对象做参数;这种情况在每个参数前都需要增加@param注解)
	public int updatePwd(@Param("id") Integer id, @Param("userPassword") String pwd);

	// 根据用户id删除用户信息
	public int deleteUserById(@Param("id") Integer delId);

	// 根据用户角色id获取该角色下的用户列表
	public List<User> getUserListByRoleId(@Param("userRole") Integer roleId);

	//根据用户id获取指定用户的相关信息和地址列表
	public List<User> getAddressListByUserId(@Param("id") Integer userId);
	
}

UserMapper.xml配置文件(注意UserMapper.xml与UserMapper.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">

<!--namespace的ID与UserMapper.java的ID(即接口的包名)需要一致 -->
<!--select标签中的id是命名空间的唯一标识符号,一般使用dao接口对应的方法名 -->
<!--select标签中的parameterType是传入参数的类型的完全限定名或者别名 -->

<mapper namespace="com.smbms.dao.user.UserMapper">
	<!--查询用户表记录数 -->
	<select id="count" resultType="int">
		select count(1) as count from
		smbms_user
	</select>

	<!--单一条件 查询用户列表 通过#{参数名}(字段名)获取传入的值 -->
	<select id="getUserList" resultType="user" parameterType="user">
		select
		* from smbms_user where userName like CONCAT ('%',#{userName},'%')
		and
		userRole=#{userRole}
	</select>

	<!--根据用户名称查询用户列表(模糊查询) -->
	<select id="getUserListByUserName" resultType="User"
		parameterType="String">
		select * from smbms_user where userName like CONCAT
		('%',#{userName},'%')
	</select>

	<!--多条件 查询用户列表(复杂数据类型,封装成map,通过#{属性名}或者#{Map的key}即可获取传入值) -->
	<select id="getUserListByMap" resultType="user" parameterType="Map">
		<!--传入UserMapperTest.java里HashMap设置的 Key 值 -->
		select * from smbms_user where userName like CONCAT ('%',#{uName},'%')
		and userRole=#{uRole}
	</select>

	<!--自定义查询(连表查询)使用resultType完成自动映射 -->
	<select id="getUserList1" resultType="user" parameterType="user">
		<!--r.roleName as userRoleName表示smbms_role表的字段需要与User.java的参数名一致,用了as转换。u和 
			r是别名 -->
		select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r
		where userName
		like CONCAT ('%',#{userName},'%') and
		userRole=#{userRole} and u.userRole=r.id
	</select>

	<!--自定义查询(连表查询)通过resultMap自动映射结果(自定义一个id),不需要再取别名与User.java参数名对应一致了 -->
	<!--将数据库的column(数据库列名或者别名)列名字段映射到元素参数名一一对应,即使字段名不一致也可以映射 -->
	<!--property表示查询出来的属性对应的值赋给实体对象的哪一个属性 -->
	<!--resultMap描述如何将结果集映射到Java对象,适用于数据库字段名与pojo属性名不一致的情况下的灵活关系映射 -->
	<!--注意:一下映射并没有映射age和address,但是在测试的时候一样可以测试出来,原因是resultMap的自动映射级别(autoMappingBehavior)PARTIAL(默认)自动匹配所有属性,NONE则是禁止自动匹配 -->
	<resultMap type="user" id="userList">
		<result property="id" column="id" />
		<result property="userCode" column="userCode" />
		<result property="userName" column="userName" />
		<result property="phone" column="phone" />
		<result property="birthday" column="birthday" />
		<result property="gender" column="gender" />
		<result property="userRole" column="userRole" />
		<result property="userRoleName" column="roleName" />
	</resultMap>
	<!--在select标签里引入一个外部的resultMap的id(userList),表示返回结果映射到哪一个resultMap上面 -->
	<select id="getUserList2" resultMap="userList" parameterType="user">
		select u.*,r.roleName from smbms_user u,smbms_role r
		where userName
		like CONCAT ('%',#{userName},'%') and
		userRole=#{userRole} and
		u.userRole=r.id
	</select>

	<!--增加用户 -->
	<insert id="add" parameterType="User">
		insert into
		smbms_user(userCode,userName,userPassword,gender,birthday,phone,address,userRole,createdBy,creationDate)
		value(#{userCode},#{userName},#{userPassword},#{gender},#{birthday},#{phone},#{address},#{userRole},#{createdBy},#{creationDate})
	</insert>

	<!--对用户信息进行修改 -->
	<update id="modify" parameterType="user">
		update smbms_user set
		userCode=#{userCode},userName=#{userName},userPassword=#{userPassword},gender=#{gender},phone=#{phone},birthday=#{birthday},address=#{address},userRole=#{userRole},modifyBy=#{modifyBy},modifyDate=#{modifyDate}
		where id=#{id}
	</update>

	<!--修改当前用户的密码 -->
	<update id="updatePwd">
		update smbms_user set userPassword=#{userPassword}
		where id=#{id}
	</update>

	<!--根据userId删除用户信息 -->
	<delete id="deleteUserById" parameterType="Integer">
		delete from smbms_user
		where id=#{id}
	</delete>

	<!--根据用户角色id获取该角色下的用户列表 -->
	<!--使用association处理一对一关联关系 -->
	<resultMap type="user" id="userRoleResult">
		<result property="id" column="id" />
		<result property="userCode" column="userCode" />
		<result property="userName" column="userName" />
		<result property="userRole" column="userRole" />
		<!--设置association的resultMap属性来引用外部的“roleResult”,可以达到复用的效果,适合association的结果映射比较多的情况 -->
		<association property="role" javaType="Role" resultMap="roleResult" />
	</resultMap>
	<resultMap type="Role" id="roleResult">
		<id property="id" column="r_id" />
		<result property="roleCode" column="roleCode" />
		<result property="roleName" column="roleName" />
	</resultMap>
	<!--在select标签里引入一个外部的resultMap的id(userRoleResult),表示返回结果映射到哪一个resultMap上面 -->
	<select id="getUserListByRoleId" parameterType="Integer"
		resultMap="userRoleResult">
		select u.*,r.id as r_id,r.roleCode,r.roleName from
		smbms_user u,smbms_role r
		where u.userRole=#{userRole} and
		u.userRole=r.id
	</select>

	<!--需求:根据用户id获取指定用户的相关信息和地址列表 -->
	<!--使用cellection处理一对多关联关系 -->
	<resultMap type="user" id="userAddressResult">
		<result property="id" column="id" />
		<result property="userCode" column="userCode" />
		<result property="userName" column="userName" />
		<!--设置collection的resultMap属性来引用外部的“roleResult”,可以达到复用的效果,适合collection的结果映射比较多的情况 -->
		<collection property="addressList" ofType="Address"
			resultMap="addressResult" />
	</resultMap>
	<resultMap type="Address" id="addressResult">
		<id property="id" column="a_id" />
		<result property="postCode" column="postCode" />
		<result property="tel" column="tel" />
		<result property="contact" column="contact" />
		<result property="addressDesc" column="addressDesc" />
	</resultMap>
	<!--在select标签里引入一个外部的resultMap的id(userAddressResult),表示返回结果映射到哪一个resultMap上面 -->
	<select id="getAddressListByUserId" parameterType="Integer"
		resultMap="userAddressResult">
		select u.*,a.id as
		a_id,a.contact,a.addressDesc,a.postCode,a.tel,a.userId from
		smbms_user u LEFT
		JOIN smbms_address a ON u.id=a.userId where u.id=#{id}
	</select>

</mapper>

Address.java类:

package com.smbms.pojo;

import java.util.Date;

public class Address {
	private Integer id; // 主键ID
	private String postCode; // 邮编
	private String contact; // 联系人
	private String addressDesc; // 地址
	private String tel; // 联系电话
	private Integer createdBy; // 创建者
	private Date crestionDate; // 创建时间
	private Integer modifyBy; // 更新者
	private Date modifyDate; // 更新时间
	private Integer userId; // 用户ID
省略set  /  get ......................

Role.java类:

package com.smbms.pojo;

import java.util.Date;

public class Role {
	private int id; // id
	private String roleCode; // 角色编码
	private String roleName; // 角色名称
	private int createBy; // 创建者
	private Date creationDate; // 创建时间
	private int modifyBy; // 更新者
	private Date modifyDate; // 更新时间
省略set  /  get ......................

User.java类:

package com.smbms.pojo;

import java.util.Date;
import java.util.List;

public class User {
	private Integer id;
	private String userCode;  //用户编码
	private String userName;   //用户名称
	private String userPassword;   //用户密码
	private Integer gender;    //性别
	private Date birthday;    //出生日期
	private String phone;    //电话
	private String address;    //地址
	private Integer userRole;    //用户角色
	private Integer createdBy;   //创建者
	private Date creationDate;   //创建时间
	private Integer modifyBy;     //更新者
	private Date modifyDate;    //更新时间

	@SuppressWarnings("unused")
	private int age;  //年龄 这个属性在数据库不存在,在查询时可根据出生日期自动计算年龄
	
	private String userRoleName;  //用户角色名称
	//内部嵌套一个复杂类型的属性
	private Role role;  //用户角色(需求:根据用户角色id获取该角色下的用户列表)
	
	//增加地址列表属性(List<Address> addressList)
	private List<Address> addressList;  //根据用户id获取指定用户的相关信息和地址列表
	
	public List<Address> getAddressList() {
		return addressList;
	}

	public void setAddressList(List<Address> addressList) {
		this.addressList = addressList;
	}

	public Role getRole() {
		return role;
	}

	public void setRole(Role role) {
		this.role = role;
	}

	public int getAge() {
		Date date=new Date();
		@SuppressWarnings("deprecation")
		int age=date.getYear()-birthday.getYear();
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getUserRoleName() {
		return userRoleName;
	}

	public void setUserRoleName(String userRoleName) {
		this.userRoleName = userRoleName;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getUserCode() {
		return userCode;
	}

	public void setUserCode(String userCode) {
		this.userCode = userCode;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public Integer getGender() {
		return gender;
	}

	public void setGender(Integer gender) {
		this.gender = gender;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public Integer getUserRole() {
		return userRole;
	}

	public void setUserRole(Integer userRole) {
		this.userRole = userRole;
	}

	public Integer getCreatedBy() {
		return createdBy;
	}

	public void setCreatedBy(Integer createdBy) {
		this.createdBy = createdBy;
	}

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		this.creationDate = creationDate;
	}

	public Integer getModifyBy() {
		return modifyBy;
	}

	public void setModifyBy(Integer modifyBy) {
		this.modifyBy = modifyBy;
	}

	public Date getModifyDate() {
		return modifyDate;
	}

	public void setModifyDate(Date modifyDate) {
		this.modifyDate = modifyDate;
	}

}

MyBatisUtil.java工具管理类:

package com.smbms.utils;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MyBatisUtil {
	private static SqlSessionFactory factory;

	// 静态代码块
	static {
		try {// 1.获取mybatis-config.xml文件的输入流
			InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
			// 2.创建sqlsessionfactory对象,完成对配置文件的读取
			factory = new SqlSessionFactoryBuilder().build(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	// 3.创建SqlSession对象
	public static SqlSession createSqlSession() {
		// 参数false表是开启事务控制,不传参数表示默认为true(为自动提交事务)
		return factory.openSession(false);
	}

	// 关闭Sqlsession对象
	public static void closeSqlSession(SqlSession sqlSession) {
		if (null != sqlSession) {
			sqlSession.close();
		}
	}
}

UserMapperTest.java测试(junit方式)

package com.smbms.dao.user;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Test;

import com.smbms.pojo.Address;
import com.smbms.pojo.User;
import com.smbms.utils.MyBatisUtil;

public class UserMapperTest {
	private Logger logger = Logger.getLogger(UserMapperTest.class);

	// 测试查询总数量
	@Test
	public void test() {
		int count = 0; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 通过Sqlsession实例直接运行映射的SQL语句
			count = sqlSession.selectOne("com.smbms.dao.user.UserMapper.count");
			logger.debug("UserMapperTest count--->" + count);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
	}

	// 测试 单一条件 查询总记录
	@Test
	public void testGetUserList() {
		List<User> usersList = null; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		User user = new User(); // 创建一个user对象
		user.setUserName("赵"); // 设置需要查询的名字(模糊查询)
		user.setUserRole(2); // 设置需要查询的用户角色
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 通过Sqlsession实例直接运行映射的SQL语句
			// usersList =
			// sqlSession.selectList("com.smbms.dao.user.UserMapper.getUserList");

			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法(注意:接口的方法必须与SQL映射文件中的SQL语句的ID(路径)一一对应)
			usersList = sqlSession.getMapper(UserMapper.class).getUserList(user);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for (User _user : usersList) {
			logger.debug(_user.getId() + "\t" + _user.getUserCode() + "\t" + _user.getUserName() + "\t"
					+ _user.getPhone() + "\t" + _user.getAddress());
		}
	}

	// 测试根据用户名称查询用户列表(模糊查询)
	@Test
	public void getUserListByUserName() {
		List<User> usersList = null; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		String userName = "赵";
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法(注意:接口的方法必须与SQL映射文件中的SQL语句的ID(路径)一一对应)
			usersList = sqlSession.getMapper(UserMapper.class).getUserListByUserName(userName);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for (User user : usersList) {
			logger.debug(user.getId() + "\t" + user.getUserCode() + "\t" + user.getUserName() + "\t" + user.getPhone()
					+ "\t" + user.getAddress());
		}
	}

	// 测试 多条件 查询总记录(复杂数据类型,封装成map,通过#{属性名}或者#{Map的key}即可获取传入值)
	@Test
	public void getUserListByMap() {
		List<User> usersList = null; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		Map<String, String> userMap = new HashMap<String, String>(); // 创建HashMap对象userMap
		userMap.put("uName", "赵");
		userMap.put("uRole", "3");
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 通过Sqlsession实例直接运行映射的SQL语句
			// usersList =
			// sqlSession.selectList("com.smbms.dao.user.UserMapper.getUserList");

			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法(注意:接口的方法必须与SQL映射文件中的SQL语句的ID(路径)一一对应)
			usersList = sqlSession.getMapper(UserMapper.class).getUserListByMap(userMap); // 传入userMap对象
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for (User _user : usersList) {
			logger.debug(_user.getId() + "\t" + _user.getUserCode() + "\t" + _user.getUserName() + "\t"
					+ _user.getPhone() + "\t" + _user.getAddress());
		}
	}

	// 测试 自定义查询(连表查询)使用resultType完成自动映射
	@Test
	public void testGetUserList1() {
		List<User> usersList = null; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		User user = new User(); // 创建一个user对象
		user.setUserName("赵"); // 设置需要查询的名字(模糊查询)
		user.setUserRole(2); // 设置需要查询的用户角色
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法(注意:接口的方法必须与SQL映射文件中的SQL语句的ID(路径)一一对应)
			usersList = sqlSession.getMapper(UserMapper.class).getUserList1(user);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for (User _user : usersList) {
			logger.debug(_user.getId() + "\t" + _user.getUserCode() + "\t" + _user.getUserName() + "\t"
					+ _user.getPhone() + "\t" + _user.getAddress() + "\t" + _user.getUserRoleName());
		}
	}

	// 测试 自定义查询(连表查询)通过resultMap自动映射结果,相对resultType性能resultMap更加灵活。
	// 注意查出来的age和address属性值
	@Test
	public void testGetUserList2() {
		List<User> usersList = null; // 初始化查询数量
		SqlSession sqlSession = null; // 初始化sqlsession对象
		User user = new User(); // 创建一个user对象
		user.setUserName("赵"); // 设置需要查询的名字(模糊查询)
		user.setUserRole(3); // 设置需要查询的用户角色
		try {
			// 1.调用工具类创建SqlSession对象,必须先把mapper文件引入到mybatis-config.xml中才能生效
			sqlSession = MyBatisUtil.createSqlSession();
			// 2.调用mapper文件进行数据操作(mybatis通过mapper文件的namespace和子元素的id来找到相应的SQL语句,从而执行查询操作)
			/**
			 * 开启一次Sqlsession会话可以执行多次SQL语句,一旦关闭,就必须重新创建Sqlsession会话。
			 * Sqlsession是线程级别,不能被共享的,最佳作用域在request里(也可以在方法体里)。
			 * 也就是说Sqlsession的生命周期在一次会话。
			 */
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法(注意:接口的方法必须与SQL映射文件中的SQL语句的ID(路径)一一对应)
			usersList = sqlSession.getMapper(UserMapper.class).getUserList2(user);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			// Sqlsession数据库会话结束必须正常关闭, 关闭Sqlsession对象
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		for (User _user : usersList) {
			logger.debug(
					_user.getId() + "\t" + _user.getUserCode() + "\t" + _user.getUserName() + "\t" + _user.getPhone()
							+ "\t" + _user.getAddress() + "\t" + _user.getAge() + "\t" + _user.getUserRoleName());
		}
	}

	// 测试 用户增加
	@Test
	public void testAdd() {
		// 打印日志
		logger.debug("testAdd!==================");
		SqlSession sqlSession = null; // 申明一个sqlSession
		int count = 0;
		try {
			sqlSession = MyBatisUtil.createSqlSession(); // 调工具类方法,创建sqlSession对象
			User user = new User(); // 创建用户对象
			// 对用户信息值设定
			user.setUserCode("test001");
			user.setUserName("测试用户 001");
			user.setUserPassword("1234567");
			Date birthday = new SimpleDateFormat("yyyy-MM-dd").parse("1984-12-12");
			user.setBirthday(birthday);
			user.setAddress("地址测试");
			user.setGender(1);
			user.setPhone("18980056410");
			user.setUserRole(1);
			user.setCreatedBy(1);
			user.setCreationDate(new Date());
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法
			count = sqlSession.getMapper(UserMapper.class).add(user);
			// 模拟异常,进行回滚
			// int i= 2/0;
			// 因为在MyBatisUtil中开启了事务控制:factory.openSession(false),所以在测试中,
			// 当sqlSession执行add()方法之后需要进行commit,完成数据的插入操作,如在执行过程中抛出异常,那么必须在catch中进行回滚,以此来保证数据的一致性,同时设置count为0.
			sqlSession.commit();
		} catch (Exception e) {
			e.printStackTrace();
			sqlSession.rollback();
			count = 0;
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		logger.debug("testAdd count:" + count);
	}

	// 测试 用户信息修改
	@Test
	public void testModify() {
		// 打印日志
		logger.debug("testModify!==================");
		SqlSession sqlSession = null; // 申明一个sqlSession
		int count = 0;
		try {
			sqlSession = MyBatisUtil.createSqlSession(); // 调工具类方法,创建sqlSession对象
			User user = new User(); // 创建用户对象
			// 对用户信息值设定
			user.setId(16);
			user.setUserCode("testModify");
			user.setUserName("测试用户 001");
			user.setUserPassword("1234567");
			Date birthday = new SimpleDateFormat("yyyy-MM-dd").parse("2018-12-12");
			user.setBirthday(birthday);
			user.setAddress("地址测试");
			user.setGender(1);
			user.setPhone("18980050000");
			user.setUserRole(1);
			user.setModifyBy(1);
			user.setModifyDate(new Date());
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法
			count = sqlSession.getMapper(UserMapper.class).modify(user);
			// 模拟异常,进行回滚
			// int i= 2/0;
			// 因为在MyBatisUtil中开启了事务控制:factory.openSession(false),所以在测试中,
			// 当sqlSession执行add()方法之后需要进行commit,完成数据的插入操作,如在执行过程中抛出异常,那么必须在catch中进行回滚,以此来保证数据的一致性,同时设置count为0.
			sqlSession.commit();
		} catch (Exception e) {
			e.printStackTrace();
			sqlSession.rollback();
			count = 0;
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		logger.debug("testModify count------" + count);
	}

	// 测试 修改当前用户的密码
	@Test
	public void testUpdatePwd() {
		// 打印日志
		logger.debug("testUpdatePwd!==================");
		SqlSession sqlSession = null; // 申明一个sqlSession
		String pwd = "8888888";
		Integer id = 16;
		int count = 0;
		try {
			sqlSession = MyBatisUtil.createSqlSession(); // 调工具类方法,创建sqlSession对象
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法
			count = sqlSession.getMapper(UserMapper.class).updatePwd(id, pwd);
			// 模拟异常,进行回滚
			// int i= 2/0;
			// 因为在MyBatisUtil中开启了事务控制:factory.openSession(false),所以在测试中,
			// 当sqlSession执行add()方法之后需要进行commit,完成数据的插入操作,如在执行过程中抛出异常,那么必须在catch中进行回滚,以此来保证数据的一致性,同时设置count为0.
			sqlSession.commit();
		} catch (Exception e) {
			e.printStackTrace();
			sqlSession.rollback();
			count = 0;
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		logger.debug("testUpdatePwd count------" + count);
	}

	// 测试 根据userId删除用户信息
	@Test
	public void testDeleteUserById() {
		// 打印日志
		logger.debug("testDeleteUserById!==================");
		SqlSession sqlSession = null; // 申明一个sqlSession
		Integer delId = 16;
		int count = 0;
		try {
			sqlSession = MyBatisUtil.createSqlSession(); // 调工具类方法,创建sqlSession对象
			// 基于mapper接口方式操作数据库;调用getMapper(Mapper.class)执行Mapper接口方法
			count = sqlSession.getMapper(UserMapper.class).deleteUserById(delId);
			// 模拟异常,进行回滚
			// int i= 2/0;
			// 因为在MyBatisUtil中开启了事务控制:factory.openSession(false),所以在测试中,
			// 当sqlSession执行add()方法之后需要进行commit,完成数据的插入操作,如在执行过程中抛出异常,那么必须在catch中进行回滚,以此来保证数据的一致性,同时设置count为0.
			sqlSession.commit();
		} catch (Exception e) {
			e.printStackTrace();
			sqlSession.rollback();
			count = 0;
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		logger.debug("testDeleteUserById count------" + count);
	}

	// 测试 根据用户角色id获取该角色下的用户列表
	@Test
	public void getUserListByRoleIdTest() {
		SqlSession sqlSession = null;
		List<User> userList = new ArrayList<User>(); // 创建一个ArrayList集合对象
		Integer roleId = 3; // 设置角色id为3
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getUserListByRoleId(roleId);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		logger.debug("getUserListByRoleIdTest userList.size:" + userList.size());
		for (User user : userList) {
			logger.debug("userList------>userName:" + user.getUserName() + "\t" + "Role:" + user.getRole().getId()
					+ "\t---" + user.getRole().getRoleCode() + "\t---" + user.getRole().getRoleName());
		}
	}

	// 测试 根据用户id获取指定用户的相关信息和地址列表
	@Test
	public void getAddressListByRoleIdTest() {
		SqlSession sqlSession = null;
		List<User> userList = new ArrayList<User>(); // 创建一个ArrayList集合对象
		Integer userId = 1; // 设置用户id为1
		try {
			sqlSession = MyBatisUtil.createSqlSession();
			userList = sqlSession.getMapper(UserMapper.class).getAddressListByUserId(userId);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtil.closeSqlSession(sqlSession);
		}
		// 调用getAddressListByUserId方法获取userList,并进行结果输出,关键是映射的用户地址列表的相关信息,需要进一步循环addressList输出
		for (User user : userList) {
			logger.debug("userList(include:addresslist)====>userCode:" + user.getUserCode() + "\t userName:"
					+ user.getUserName() + "\t <未做映射字段>userPassword:" + user.getUserPassword());
			for (Address address : user.getAddressList()) {
				logger.debug("address---->id:" + address.getId() + "\t contact:" + address.getContact()
						+ "\t addressDesc:" + address.getAddressDesc() + "\t tel:" + address.getTel() + "\t postCode:"
						+ address.getPostCode() + "\t <未做映射字段>userId:" + address.getUserId());
			}
		}
	}
}

[mybatis官网:/(http://blog.mybatis.org/)