parameterType配置参数
此参数主要用于SQL语句传参,该属性的值可以是基本类型、引用类型、还可以是实体类类型。本节主要说明实体类的包装类作为此属性的值,进行参数传递,这种方式主要应用于多表联合查询,这时候可以使用包装对象传递参数来作为查询条件。
在不修改user表的前提下,增加了其他表,SQL语句如下:
-- role表
DROP TABLE IF EXISTS `role`;
CREATE TABLE `role` (
`ID` int(11) NOT NULL COMMENT '编号',
`ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
`ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');
--user_role表
DROP TABLE IF EXISTS `user_role`;
CREATE TABLE `user_role` (
`UID` int(11) NOT NULL COMMENT '用户编号',
`RID` int(11) NOT NULL COMMENT '角色编号',
PRIMARY KEY (`UID`,`RID`),
KEY `FK_Reference_10` (`RID`),
CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);
查询男总裁的用户信息
- 在前面的基础上,编写Role类,并将User类和Role类进行封装。
package com.liang.domain;
/**
* Role类
*/
public class Role {
private int id;
private String role_name;
private String role_desc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRole_name() {
return role_name;
}
public void setRole_name(String role_name) {
this.role_name = role_name;
}
public String getRole_desc() {
return role_desc;
}
public void setRole_desc(String role_desc) {
this.role_desc = role_desc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", role_name='" + role_name + '\'' +
", role_desc='" + role_desc + '\'' +
'}';
}
}
package com.liang.domain;
/**
* 封装User类和Role类 作为查询条件
*/
public class QueryUR {
private User user;
private Role role;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
@Override
public String toString() {
return "QueryUR{" +
"user=" + user +
", role=" + role +
'}';
}
}
- 在持久层接口中添加查询方法
/**
* 通过性别和角色查询用户信息
* @param queryUR
* @return
*/
List<User> findByUR(QueryUR queryUR);
- 在持久层接口映射文件中添加SQL语句
<!--通过性别和角色查询用户信息-->
<select id="findByUR" parameterType="com.liang.domain.QueryUR" resultType="com.liang.domain.User">
select *from role left join
(SELECT * FROM user_role right join user
on user.id = user_role.UID) as userID
on role.ID = userID.RID where role_name = #{role.role_name} and sex = #{user.sex};
</select>
- 编写测试方法进行测试
@Test
public void testFindByUR() {
User user = new User();
user.setSex("男");
Role role = new Role();
role.setRole_name("总裁");
QueryUR queryUR = new QueryUR();
queryUR.setUser(user);
queryUR.setRole(role);
List<User> list = userDao.findByUR(queryUR);
for (User user2 : list) {
System.out.println(user2);
}
}
resultType配置参数
此属性主要用于结果集的类型,支持基本类型和实体类类型。当是实体类名称时,实体类中的属性名称必须和查询语句中的类名保持一致,否则无法实现封装。
如下:查询所有角色的实现。
package com.liang.domain;
public class Role {
private int id;
private String roleName;//数据库中字段为role_name
private String roleDesc;//数据库中字段为role_desc
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
在配置文件中增加
<mappers>
<mapper resource="com/liang/dao/UserDao.xml"/>
<mapper resource="com/liang/dao/RoleDao.xml"></mapper>
</mappers>
编写持久层接口
package com.liang.dao;
import com.liang.domain.Role;
import java.util.List;
public interface RoleDao {
/**
* 查询所有角色
* @return
*/
List<Role> findAll();
}
编写持久层接口映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liang.dao.RoleDao">
<select id="findAll" resultType="com.liang.domain.Role">
select id,role_name,role_desc from role;
</select>
</mapper>
编写测试方法
import com.liang.dao.RoleDao;
import com.liang.dao.UserDao;
import com.liang.domain.Role;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class TestRole {
private SqlSession sqlSession = null;
private InputStream inputStream = null;
private RoleDao roleDao = null;
@Before
public void init() throws IOException {
inputStream = Resources.getResourceAsStream("SqlConfig.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
sqlSession = sqlSessionFactory.openSession();
roleDao = sqlSession.getMapper(RoleDao.class);
}
@After
public void destroy() throws IOException {
sqlSession.commit();
sqlSession.close();
inputStream.close();
}
@Test
public void testFindAll()
{
List<Role> roles = roleDao.findAll();
for (Role role : roles)
{
System.out.println(role);
}
}
}
测试结果
这就是由于实体类中的属性名称没有和查询语句中的列名保持一致,无法实现封装导致的。
解决方法
解决方法一: 使用别名查询 —— 修改持久层映射文件SQL语句
<select id="findAll" resultType="com.liang.domain.Role">
select id,role_name as roleName,role_desc as RoleDesc from role;
</select>
缺点:当查询很多时,修改起来会很麻烦。为了解决此问题Mybatis引入了resultMap标签
resultMap标签
resultMap标签用于 查询的字段名和实体类的属性名称不一致时,为两者建立对应关系,从而实现封装。
解决方法二:使用resultMap标签 建立实体类和数据库表的对应关系,修改映射文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liang.dao.RoleDao">
<!--建立Role实体类和数据库表的对应关系
id属性: 给定一个唯一标识,主要用于其他标签引用
type属性: 指定书体类的全限定类名-->
<resultMap id="roleMap" type="com.liang.domain.Role">
<!--
id标签:用于指定主键字段
result标签:用于指定非主键字段
column属性:用于指定数据库字段名
property属性:用于指定书体类属性名
-->
<id property="id" column="id" />
<result column="role_name" property="roleName"/>
<result column="role_desc" property="roleDesc"/>
</resultMap>
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="roleMap">
select id,role_name,role_desc from role;
</select>
</mapper>