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:自动匹配所有属性。
数据库结构:
工程文件结构:
代码中关于说明都有详细注解,不再一一赘述。
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/)