您的位置:首页 > 其它

mybatis详解-(15)返回结果封装

2017-12-17 20:08 225 查看
前面介绍的内容查询结果基本都是返回一个数据,然后将数据对应某一个对象。本篇探索一下多种不同类型的返回结果,mybatis是如何封装的。

1.返回list

创建Employee对象

package org.mybatis.returntype;

import org.apache.ibatis.type.Alias;

@Alias("empp")
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email
+ ", gender=" + gender + "]";
}
}


创建接口类

package org.mybatis.returntype;

import java.util.List;

public interface EmployeeMapper {

public List<Employee> getEmpByLastName(String lastName);

}


创建映射配置文件,使用like查询返回一个list集合,list集合中存放Employee对象。返回值类型仍然使用对象,而不是list

<?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="org.mybatis.returntype.EmployeeMapper">

<select id="getEmpByLastName" resultType="empp">
select id,last_name,email,gender from mybatis_employee where last_name like #{lastName}
</select>

</mapper>


创建主配置文件

<?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>

<properties resource="db.properties"></properties>

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<typeAliases>
<!-- 为包下的所有类起别名,默认为类名大小写(不区分大小写) -->
<package name="org.mybatis.returntype"/>
</typeAliases>

<!-- 默认development是开发环境,如果改成test则表示使用测试环境 -->
<environments default="dev_mysql">
<environment id="dev_mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</en
4000
vironment>

<environment id="test_mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${mysql.drivertest}" />
<property name="url" value="${mysql.urltest}" />
<property name="username" value="${mysql.usernametest}" />
<property name="password" value="${mysql.passwordtest}" />
</dataSource>
</environment>

</environments>

<mappers>
<mapper resource="mapper/returntypemapper.xml"/>
</mappers>

</configuration>


创建测试类

package org.mybatis.returntype;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.Test;

/**
* 使用接口式編程
*/
public class MybatisTest {

@Test
public void testMybatis() {
String resource = "mybatis-config-returntype.xml";//全局配置文件

InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();

EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
List<Employee> emp = mapper.getEmpByLastName("%an%");
System.out.println(emp);

sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}


返回结果如下:

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@e320068]

DEBUG - ==> Preparing: select id,last_name,email,gender from mybatis_employee where last_name like ?

DEBUG - ==> Parameters: %an%(String)

[Employee [id=3, lastName=panpan, email=tang_greatman@sohu.com, gender=1], Employee [id=4, lastName=huanhuan, email=tang_greatman@sina.com, gender=2], Employee [id=5, lastName=huanhuan, email=tang_greatman@sina.com, gender=2], Employee [id=6, lastName=huanan, email=tang_man@sina.com, gender=2], Employee [id=7, lastName=hussanan, email=tang_@qq.com, gender=2], Employee [id=8, lastName=hussanan, email=tang_@qq.com, gender=2]]

DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e320068]

DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@e320068]

DEBUG - Returned connection 238157928 to pool.

结果返回为一个集合。

2.返回map

a)返回一条记录的map

创建接口方法

public Map<String,Object> getEmpById(Integer id);


创建sql,这里map类型是一个Map的缩写

<select id="getEmpById" resultType="map">
select * from mybatis_employee where id = #{id}
</select>


创建测试

package org.mybatis.returntype;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

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.Test;

/**
* 使用接口式編程
*/
public class MybatisTest {

@Test
public void testMybatis() {
String resource = "mybatis-config-returntype.xml";//全局配置文件

InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();

EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//          List<Employee> emp = mapper.getEmpByLastName("%an%");
//          System.out.println(emp);

Map<String, Object> empmap = mapper.getEmpById(2);
System.out.println(empmap);

sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}


返回结果:

DEBUG - ==> Preparing: select * from mybatis_employee where id = ?

DEBUG - ==> Parameters: 2(Integer)

{gender=2, last_name=lisi, id=2, email=tang_greatman@qq.com}

DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1f57539]

DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1f57539]

DEBUG - Returned connection 32863545 to pool.

返回结果已经将对象封装为一个map对象。

b)返回多条记录封装到一个map中

创建接口方法

指定id作为map中的键,javabean作为值

/**
* @param lastName
* @return 键是某个属性,值是javabean
*/
@MapKey("id")
public Map<Integer,Employee> getEmpByLastNameLike(String lastName);


创建sql语句,指定返回值类型为Employee对象

<select id="getEmpByLastNameLike" resultType="empp">
select * from mybatis_employee where last_name like #{lastName}
</select>


创建测试类

package org.mybatis.returntype;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.Map;

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.Test;

/**
* 使用接口式編程
*/
public class MybatisTest {

@Test
public void testMybatis() {
String resource = "mybatis-config-returntype.xml";//全局配置文件

InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();

EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
//          List<Employee> emp = mapper.getEmpByLastName("%an%");
//          System.out.println(emp);

//          Map<String, Object> empmap = mapper.getEmpById(2);
//          System.out.println(empmap);

Map<Integer, Employee> mapbean = mapper.getEmpByLastNameLike("%an%");
System.out.println(mapbean);

sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}


返回结果:

DEBUG - ==> Preparing: select * from mybatis_employee where last_name like ?

DEBUG - ==> Parameters: %an%(String)

{3=Employee [id=3, lastName=panpan, email=tang_greatman@sohu.com, gender=1],

4=Employee [id=4, lastName=huanhuan, email=tang_greatman@sina.com, gender=2],

5=Employee [id=5, lastName=huanhuan, email=tang_greatman@sina.com, gender=2],

7=Employee [id=7, lastName=hussanan, email=tang_@qq.com, gender=2], 8=Employee [id=8, lastName=hussanan, email=tang_@qq.com, gender=2]}

DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4493d195]

DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4493d195]

DEBUG - Returned connection 1150538133 to pool.

返回结果键为数据记录id,值为Employee对象。

3.resultmap

上面两种返回,都是使用resulttype对查询的结果进行封装,且封装的都是单个对象。而实际的生产环境中有很多的关联查询,使用resulttype进行封装显然已经不能满足需求。mybatis提供了一种自定义封装方式resulmap,结合示例做一个介绍:

1)一个employee对应一个department

创建Employee和Department:

package org.mybatis.resultmap;

/**
* ALTER TABLE mybatis_employee ADD COLUMN dept_id INT(11) COMMENT '部门id';
* ALTER TABLE mybatis_employee ADD CONSTRAINT mybatis_dept_emp FOREIGN KEY (dept_id) REFERENCES mybatis_department (id);
*/
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
private Department department;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Department getDepartment() {
return department;
}
public void setDepartment(Department department) {
this.department = department;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email="
+ email + ", gender=" + gender + ", department=" + department
+ "]";
}

}


package org.mybatis.resultmap;
public class Department {

private Integer id;
private String deptName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
public String toString() {
return "Department [id=" + id + ", deptName=" + deptName + "]";
}
}


创建接口:

package org.mybatis.resultmap;

public interface EmployeeMapper {

public Employee getEmpById(Integer id);

}


创建表和外键:

CREATE TABLE `mybatis_employee` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`last_name` varchar(255) DEFAULT NULL,
`email` varchar(255) DEFAULT NULL,
`gender` varchar(255) DEFAULT NULL,
`dept_id` int(11) DEFAULT NULL COMMENT '部门id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

CREATE TABLE `mybatis_department` (
`id` int(11) NOT NULL,
`deptName` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--创建外键关联
ALTER TABLE mybatis_employee ADD CONSTRAINT mybatis_dept_emp FOREIGN KEY (dept_id) REFERENCES mybatis_department (id);


创建映射配置文件:

创建
<resultMap type="org.mybatis.resultmap.Employee" id="memp">
标签,设置id=memp,返回值类型为Employee对象,将
<select id="getEmpById" resultMap="memp">
查询结果通过resultMap标签和实际javabean属性一一对应。此时查询结果就会按照resultMap中设置的对应关系将查询结果设置到Employee对象中。有了这种自定义方式,之前的驼峰命名配置就可以去除掉。

<?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="org.mybatis.resultmap.EmployeeMapper">

<!--这里department是按照属性传递进行书写-->
<resultMap type="org.mybatis.resultmap.Employee" id="memp">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<result column="did" property="department.id"/>
<result column="deptName" property="department.deptName"/>
</resultMap>

<select id="getEmpById" resultMap="memp">
select me.id,me.last_name,me.email,me.gender,me.dept_id d_id,md.id did,md.deptName from mybatis_employee me,mybatis_department md where me.dept_id = md.id and me.id = #{id}
</select>
</mapper>


也可以将resultMap通过association进行关联,代码如下:

<resultMap type="org.mybatis.resultmap.Employee" id="memp2">
<id column="id" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
<association property="department" javaType="org.mybatis.resultmap.Department">
<id column="did" property="id"/>
<result column="deptName" property="deptName"/>
</association>
</resultMap>


创建主配置文件:

<?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>

<properties resource="db.properties"></properties>

<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

<typeAliases>
<!-- 为包下的所有类起别名,默认为类名大小写(不区分大小写) -->
<package name="org.mybatis.resultmap"/>
</typeAliases>

<!-- 默认development是开发环境,如果改成test则表示使用测试环境 -->
<environments default="dev_mysql">
<environment id="dev_mysql">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</environment>

<environment id="test_mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${mysql.drivertest}" />
<property name="url" value="${mysql.urltest}" />
<property name="username" value="${mysql.usernametest}" />
<property name="password" value="${mysql.passwordtest}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/resultmapmapper.xml"/>
</mappers>

</configuration>


创建测试类:

package org.mybatis.resultmap;

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;
import org.junit.Test;
/**
* 使用接口式編程
*/
public class MybatisTest {

@Test
public void testMybatis() {
String resource = "mybatis-config-resultmap.xml";//全局配置文件

InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();

EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
Employee emp = mapper.getEmpById(2);
System.out.println(emp);

sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}


执行结果:

DEBUG - ==> Preparing: select me.id,me.last_name,me.email,me.gender,me.dept_id d_id,md.id did,md.deptName from mybatis_employee me,mybatis_department md where me.dept_id = md.id and me.id = ?

DEBUG - ==> Parameters: 2(Integer)

Employee [id=2, lastName=lisi, email=tang_greatman@qq.com, gender=2, department=Department [id=2, deptName=测试部]]

DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@6ee52dcd]

DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@6ee52dcd]

DEBUG - Returned connection 1860513229 to pool.

联合查询数据已经设置到javabean中。

2)一个department对应多个employee

上面介绍的是在一个employee中对应一个department对象,如果查询某一个id的employee,那么返回的结果是1。如果在department中存在一个employee集合,那么查询某一个id的department,返回的就是一个employee集合,结果又该如何处理呢?

Employee类,接口,配置文件,映射文件保持不变。Department做相关调整

实体类变更为

添加Employee集合

package org.mybatis.resultmap;
import java.util.List;
public class Department {

private Integer id;
private String deptName;
/**
* 添加emp集合
*/
private List<Employee> emps;

public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}

public List<Employee> getEmps() {
return emps;
}
public void setEmps(List<Employee> emps) {
this.emps = emps;
}

public String toString() {
return "Department [id=" + id + ", deptName=" + deptName + "]";
}
}


接口类变更为

添加查询方法

public Department getDeptWithEmpById(Integer id);


映射文件变更为

返回的Employee集合使用
<collection>
标签进行接收,类型使用
ofType=""
进行配置

<?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="org.mybatis.resultmap.DepartmentMapper">

<select id="getDeptById" resultType="org.mybatis.resultmap.Department">
select id,deptName from mybatis_department where id = #{id}
</select>

<resultMap type="org.mybatis.resultmap.Department" id="mdept1">
<id column="did" property="id"/>
<result column="deptName" property="deptName"/>
<!-- 一个department对应多个employee -->
<collection property="emps" ofType="org.mybatis.resultmap.Employee">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
</resultMap>

<select id="getDeptWithEmpById" resultMap="mdept1">
SELECT
md.id did,
md.deptName deptName,
me.id eid,
me.last_name last_name,
me.email email,
me.gender gender
FROM
mybatis_department md
LEFT JOIN mybatis_employee me ON md.id = me.dept_id
WHERE
md.id = #{id}
</select>
</mapper>


测试

package org.mybatis.resultmap;

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;
import org.junit.Test;

/**
* 使用接口式編程
*/
public class MybatisTest {

@Test
public void testMybatis() {
String resource = "mybatis-config-resultmap.xml";//全局配置文件

InputStream inputStream = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession();

DepartmentMapper mapper = sqlSession.getMapper(DepartmentMapper.class);
Department dept1 = mapper.getDeptWithEmpById(2);
System.out.println(dept1);
System.out.println(dept1.getEmps());

sqlSession.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
}
}


返回结果

DEBUG - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]

DEBUG - ==> Preparing: SELECT md.id did, md.deptName deptName, me.id eid, me.last_name last_name, me.email email, me.gender gender FROM mybatis_department md LEFT JOIN mybatis_employee me ON md.id = me.dept_id WHERE md.id = ?

DEBUG - ==> Parameters: 2(Integer)

Department [id=2, deptName=测试部]

[Employee [id=2, lastName=lisi, email=tang_greatman@qq.com, gender=2], Employee [id=5, lastName=huanhuan, email=tang_greatman@sina.com, gender=2], Employee [id=6, lastName=huanan, email=tang_man@sina.com, gender=2]]

DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]

DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4cf4d528]

DEBUG - Returned connection 1291113768 to pool.

封装完毕
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  mybatis