一、学习目标
- 掌握resultMap的基本配置项
- 掌握使用resultMap实现复杂类型关联
- 了解resultMap
- 了解MyBatis缓存
二、resultMap
resultMap属性:
- id:resultMap的唯一标识
- type:Java实体类
resultMap子元素
- id:一般对应数据库中该行的主键id,设置此项可提高MyBatis性能
- result:映射到JavaBean的某个“简单类型”属性
- association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
- collection:映射到JavaBean的某个“复杂类型”属性,比如集合
三、association 2-1
复杂的类型关联,一对一
内部嵌套:应设一个嵌套JavaBean属性
属性:
- property:映射数据库列的实体对象的属性
- javaType:完整Java类名或者别名
- resultMap:引用外部resultMap
子元素:
- id
- result : -- property:映射数据库列的实体对象的属性。 --column:数据库列名或者别名。
四、需求-根据用户角色ID,获取该角色列表下用户列表信息
Role.java
package cn.smbms.pojo;
import java.util.Date;
public class Role {
private int id;
private String roleCode;//角色编码
private String roleName;//角色名称
private int createdBy;//创建者
private Date creationDate;//创建时间
private int modifyBy;//修改者
private Date modifyDate;//修改时间
public Role() {
super();
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleCode() {
return roleCode;
}
public void setRoleCode(String roleCode) {
this.roleCode = roleCode;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public int getCreatedBy() {
return createdBy;
}
public void setCreatedBy(int createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public int getModifyBy() {
return modifyBy;
}
public void setModifyBy(int modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
}
User.java
package cn.smbms.pojo;
import java.util.Date;
public class User {
private int id; // id
private String userCode; // 用户编码
private String userName; // 用户名称
private String userPassword; // 用户密码
private int gender; // 性别
private Date birthday; // 出生日期
private String phone; // 电话
private String address; // 地址
private int userRole; // 用户角色
private int createdBy; // 创建者
private Date creationDate; // 创建日期
private int modifyBy; // 修改者
private Date modifyDate; // 修改日期
private String userRoleName; //用户角色名称
private int age;
private Role role;//用户角色
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
public int getAge() {
Date date = new Date();
int age = date.getYear() - birthday.getYear();
return age;
}
public void setAge(int age) {
this.age = age;
}
public User() {
super();
}
public int getId() {
return id;
}
public void setId(int 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 int getGender() {
return gender;
}
public void setGender(int 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 int getUserRole() {
return userRole;
}
public void setUserRole(int userRole) {
this.userRole = userRole;
}
public int getCreatedBy() {
return createdBy;
}
public void setCreatedBy(int createdBy) {
this.createdBy = createdBy;
}
public Date getCreationDate() {
return creationDate;
}
public void setCreationDate(Date creationDate) {
this.creationDate = creationDate;
}
public int getModifyBy() {
return modifyBy;
}
public void setModifyBy(int modifyBy) {
this.modifyBy = modifyBy;
}
public Date getModifyDate() {
return modifyDate;
}
public void setModifyDate(Date modifyDate) {
this.modifyDate = modifyDate;
}
public String getUserRoleName() {
return userRoleName;
}
public void setUserRoleName(String userRoleName) {
this.userRoleName = userRoleName;
}
}
UserMapper.java
/**
* 根据角色ID查询出对应的用户列表信息
* @param roleId
* @return
*/
public List<User> getUserListByRoleId(@Param("userRole")Integer roleId);
UserMapper.xml
<resultMap type="user" id="userRoleResult">
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
<result property="userRole" column="userRole"/>
<association property="role" javaType="Role">
<id property="id" column="r_id"/>
<result property="roleCode" column="roleCode"/>
<result property="roleName" column="roleName"/>
</association>
</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>
UserMapperTest.java
@Test
public void testGetUserListByRoleId() {
List<User> userList = new ArrayList<User>();
SqlSession sqlSession = null;
Integer roleId = 3;
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getUserListByRoleId(roleId);
}catch (Exception e) {
e.printStackTrace();
} finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User _user : userList) {
logger.debug("testGetUserListByRoleId userCode: " + _user.getUserCode()
+ "and userName: " + _user.getUserName()
+ "and userRoleCode: " + _user.getRole().getRoleCode()
+ "and userRoleName: " + _user.getRole().getRoleName());
}
}
五、association的复用
<resultMap type="Role" id="roleResult">
<id property="id" column="id"/>
<result property="roleCode" column="roleCode"/>
<result property="roleName" column="roleName"/>
</resultMap>
<resultMap type="user" id="userRoleResult">
<id property="id" column="id"/>
<result property="userCode" column="userCode"/>
<result property="userName" column="userName"/>
<result property="userRole" column="userRole"/>
<association property="role" javaType="Role" resultMap="roleResult"/>
</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>
六、collection 2-1
collection:
1. 复杂类型集合,一对多
2. 内部嵌套:映射一个嵌套结果集到一个列表
3. 属性:
- property:映射数据库列的实体对象的属性
- ofType:完整Java类名或者别名(集合所包括的类型)
- resultMap:引用外部resultMap
4. 子元素
- id
- result: -- property:映射数据库列的实体对象的属性 -- column:数据库列名或者别名
七、需求 - 获取指定用户的相关信息和地址列表
Address.java
package cn.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 creationDate; // 创建时间
private Integer modifyBy; // 更新时间
private Date modifyDate; // 更新时间
private Integer userId; // 用户ID
public Address() {
super();
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public String getContact() {
return contact;
}
public void setContact(String contact) {
this.contact = contact;
}
public String getAddressDesc() {
return addressDesc;
}
public void setAddressDesc(String addressDesc) {
this.addressDesc = addressDesc;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
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;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
}
UserMapper.java
/**
* 根据用户ID获取用户信息及地址列表
* @param userId
* @return
*/
public List<User> getAddressListByUserId(@Param("id")Integer userId);
UserMapper.xml
<resultMap type="address" id="addressResult">
<id property="id" column="a_id" />
<result property="contact" column="contact" />
<result property="addressDesc" column="addressDesc" />
<result property="tel" column="tel" />
<result property="postCode" column="postCode" />
</resultMap>
<resultMap type="user" id="userAddressResult">
<id property="id" column="id" />
<result property="userCode" column="userCode" />
<result property="userName" column="userName" />
<collection property="addressList" ofType="Address" resultMap="addressResult"/>
</resultMap>
<select id="getAddressListByUserId" parameterType="Integer"
resultMap="userAddressResult">
select u.*, a.id as a_id, a.contact, a.addressDesc, a.tel,
a.postCode
from smbms_user u, smbms_address a
where u.id=a.userId and u.id=#{id}
</select>
UserMapperTest.java
@Test
public void testGetAddressListByUserId() {
List<User> userList = new ArrayList<User>();
SqlSession sqlSession = null;
Integer userId = 1;
try {
sqlSession = MyBatisUtil.createSqlSession();
userList = sqlSession.getMapper(UserMapper.class).getAddressListByUserId(userId);
}catch(Exception e) {
e.printStackTrace();
}finally {
MyBatisUtil.closeSqlSession(sqlSession);
}
for(User _user: userList) {
logger.debug("testGetUserListByRoleId userCode: " + _user.getUserCode()
+ "and userName: " + _user.getUserName());
for(Address address : _user.getAddressList()) {
logger.debug("address---" + address.getId()
+ "contact---" + address.getContact()
+ "addressDesc --- " + address.getAddressDesc());
}
}
}
八、resultMap自动映射(autoMappingBehavior)的三个匹配级别
- NONE:禁止自动匹配
- PARTIAL(默认):自动匹配所有属性,内部嵌套除外
- FULL:自动匹配所有
九、MyBatis缓存
一级缓存:基于MyBatis自带的HashMap的一个本地缓存,作用范围只在session作用域中。flush或者close后,session域中都会清空。
二级缓存:global作用域,全局缓存。作用:可以被所有的sqlSession所共享。
二级缓存的配置
- MyBatis的全局cache配置
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
- 在Mapper XML文件中设置缓存,默认情况下:未开启。global cache只针对mapper的namespace内。
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
- 在Mapper XML文件配置支持cache后,若需要对个别查询进行调整,可以单独设置cache。
<select id="selectAll" resultType="Emp" useCache="true">