简单类型的映射
返回的是简单基本类型
接口中的定义
int getAdminCount();
xml中具体的实现
<select id="getAdminCount" resultType="int">
select count(*) from admin
</select>
这里我选用了测试的一个jar包,就直接用来测试了,没有试用main方法。
@Test
public void find3() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);
int count = mapper.getAdminCount();
System.out.println(count);
sqlSession.commit();
sqlSession.close();
}
测试结果
返回多组数据
在数据库当中,查找多组的数据,就需要接受,而接受主要就靠的是集合来接受数据库所返回的数据。
接口中的定义:
List<Admin> getAdminList();
Mybatis中xml的定义:
<select id="getAdminList" resultType="Admin">
select * from admin
</select>
这里我选用了测试的一个jar包,就直接用来测试了,没有试用main方法。
@Test
public void findList() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
AdminMapper mapper = sqlSession.getMapper(AdminMapper.class);
List<Admin> adminList = mapper.getAdminList();
System.out.println(adminList);
sqlSession.commit();
sqlSession.close();
}
这里我试用了日志来返回查看数据库返回了几条的数据,并具体打印出来
POJO对象输出映射
POJO (Plain Old Java Objects,普通的 Java 对象)
如果数据库中表的列名和类中的属性名完全相同,则Mybatis会自动的将查询结果封装到这个POJO的对象当中去
如果java中使用了标准的驼峰命名,则数据库中也使用的是标准的下划线连接命名法,这样就可以开始全局的设置实现自动转换。
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
public User findUserInfoById(int id)
<select id="findAdminInfoById" parameterType="int" resultType="User">
select * from dmin where id=#{id}
</select>
复杂类型的返回
resultMap
特殊情况下,数据库的列名和属性名就是不一致,就要解决这个映射的问题。 那么这里就是使用resultMap。resultMap就是结果集的映射。就是自定义的一种映射
但是resultMap主要多用于多表关联。
定义 resultMap
resultMap中的的标签主要有个id(映射主键)和result(映射非主键) column表示的数据库中的数据列名,property表示的是类中定义的属性名
如果类中的属性名和数据库中的列名一致,可以不用将全部的数据写在resultMap当中 只写一些所需要的数据名之间的联系,一样的是不用写的。
<resultMap id="one" type="Admin">
<id column="id" property="id"></id>
<result column="account" property="account"></result>
<result column="password" property="password"></result>
<result column="sex" property="sex"></result>
</resultMap>
- resutlMap 的 id 属性是 resutlMap 的唯一标识,本例中定义为 “one”。
- resutlMap 的 id 属性是映射的 POJO 类。
- id 标签映射主键,result 标签映射非主键。
- property 设置 POJO 的属性名称,column 映射查询结果的列名称
使用resultMap
<select id="getAdminById" resultMap="one">
select * from admin where id = #{id}
</select>
输出的映射不是resultType,而是resultMap,resultMap的值填写定义好id的resultMap值
再定义一个resultMap值对应的resultMap值
<resultMap id="one" type="Admin">
<id column="id" property="id"></id>
<result column="account" property="account"></result>
<result column="password" property="password"></result>
<result column="sex" property="sex"></result>
</resultMap>
多表关联处理结果集(resultMap)
resultMap主要还是针对于多表之间的查询
resultMap 元素中 association , collection 元素 association , collection 都是对于复杂类型的联合,
association: 之间是一种一对一的关系,比如一个部门的操作针对于一个操作人。 association 是能够引用自身, 或者从其它地方引用。
collection: 是一种一对多或者多对一的关系。比如一个部门针对于多个员工。 collection 是能够能引用自身, 或者从其它地方引用。
association 关联元素处理“有一个”类型的关系,即一对一关联。 它有两种关联方式:
- 嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型。
- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。
Collection 关联元素处理一对多之间的关联。
Mybatis在多表之间的关联无异是异常方便的 在创建储存信息的类的时候,可以每一个表创建一个类,将相邻表的数据关联映射到我们的类当中去。使得在建类,取名等等
先建对应的存储数据的类
Admin(操作人)对应的类
package com.demo.mybatispro.model;
import java.io.Serializable;
public class Admin implements Serializable {
private int id;
private String account;
private String password;
private String sex;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Admin{" +
"id=" + id +
", account='" + account + '\'' +
", password='" + password + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
dept(部门)对应的类
package com.demo.mybatispro.model;
import java.io.Serializable;
import java.util.List;
public class Dept implements Serializable {
private int id;
private String name;
private List<Employer> employers;
private Admin admin;
public int getId(int i) {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Employer> getEmployers() {
return employers;
}
public void setEmployers(List<Employer> employers) {
this.employers = employers;
}
public Admin getAdmin() {
return admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", name='" + name + '\'' +
", employers=" + employers +
", admin=" + admin +
'}';
}
}
employee(员工)对应的类
package com.demo.mybatispro.model;
import javafx.scene.DepthTest;
import java.io.Serializable;
public class Employer implements Serializable {
private int id;
private String name;
private int age;
private Dept dept;
private Admin admin;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
public Admin getAdmin() {
return admin;
}
public void setAdmin(Admin admin) {
this.admin = admin;
}
@Override
public String toString() {
return "Employer{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", dept=" + dept +
", admin=" + admin +
'}';
}
}
将读取Mybatis核心配置,创建SqlSessionFactory这样的一个工厂,创建SqlSession对象的这些封装到一个类当中去
package com.demo.mybatispro.util;
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 java.io.IOException;
import java.io.Reader;
public class MybatisUtil {
static SqlSessionFactory development = null;
static {
Reader resourceAsReader = null;
try {
resourceAsReader = Resources.getResourceAsReader("mybtis.xml");
} catch (IOException e) {
e.printStackTrace();
}
development = new SqlSessionFactoryBuilder().build(resourceAsReader);
}
public static SqlSession getSqlSession() {
return development.openSession();
}
}
association就是针对于表之间的关系是一对一的
接口定义方法名
public interface EmployerMapper {
Employer getEmployerById(int id);
}
Mybatis中在xml中采用association具体的实现(一对一的关系)
<resultMap id="empmap" type="Employer">
<id column="id" property="id"></id>
<result column="ename" property="name"></result>
<result column="age" property="age"></result>
<association property="dept" javaType="Dept">
<result column="dname" property="name"></result>
</association>
<association property="admin" javaType="Admin">
<result column="account" property="account"></result>
</association>
</resultMap>
<select id="getEmployerById" resultMap="empmap">
SELECT
emp.id,
emp.name ename,
emp.age,
d.name dname,
a.account
FROM employee emp LEFT JOIN dept d ON emp.deptId = d.id
LEFT JOIN admin a ON emp.adminId = a.id
WHERE emp.id = #{id}
</select>
方法的调用:(我采用了测试的jar包,所以可以不用main方法来使用,就直接启动函数)
@Test
public void find(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmployerMapper mapper = sqlSession.getMapper(EmployerMapper.class);
Employer employer = mapper.getEmployerById(1);
System.out.println(employer.getName());
System.out.println(employer.getDept().getName());
System.out.println(employer.getAdmin().getAccount());
System.out.println(employer);
sqlSession.commit();
sqlSession.close();
}
我采用了日志做到整体的一个输出
在这个关系中一个员工(employee)对应一个部门(dept)和一个操作人(admin) 是一对一之间的关系
collection 就是针对于表之间的关系是一对一的
接口定义要实现的方法。
public interface DeptMapper {
Dept getDeptById(int id);
}
Mybatis中在xml中具体的实现(一对一的关系)
<?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.demo.mybatispro.mapper.DeptMapper">
<resultMap id="deptmap" type="Dept">
<id column="id" property="id"></id>
<result column="dname" property="name"></result>
<association property="admin" javaType="Admin">
<result column="account" property="account"></result>
</association>
<collection property="employers" javaType="list" ofType="Employer">
<result column="ename" property="name"></result>
</collection>
</resultMap>
<select id="getDeptById" resultMap="deptmap">
SELECT
d.id,
d.name dname,
a.account,
e.name ename
FROM dept d LEFT JOIN admin a ON d.adminId = a.Id
LEFT JOIN employee e ON d.id = e.deptId
WHERE d.id = #{id}
</select>
</mapper>
方法的调用:(我采用了测试的一个jar包,所以可以不用main方法来使用,就直接启动函数)
@Test
public void find() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept deptById = mapper.getDeptById(2);
System.out.println(deptById);
System.out.println(deptById.getName());
List<Employer> list = deptById.getEmployers();
for (Employer employer : list) {
System.out.println(employer.getName());
}
sqlSession.commit();
sqlSession.close();
}
采用了日志做到整体的一个输出 在这个关系当中一个部门(dept)对应的是一个操作人(admin)和多个员工(employee)。 部门对应操作人时用association,对于员工时就用collection。
嵌套查询
什么是嵌套查询?
嵌套查询其实就是在多表关联处理的结果。
需要查询关联信息时,就可以使用到Mybatis的嵌套查询特性。
Mybatis 一对一关联的 association 和一对多的 collection 可以实现懒加 载。嵌套循环时用到的是resultMap,不是resultType。
嵌套查询的例子
接口中的定义方法名
Employer getEmlpyeeById1(int id);
具体在xml中的实现
<resultMap id="emp1" type="Employer">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<result column="age" property="age"></result>
<association property="dept" javaType="Dept" fetchType="lazy"
select="findDeptById" column="deptId">
<result column="name" property="name"></result>
</association>
<association property="admin" javaType="Admin" fetchType="lazy"
select="findAdminById" column="adminId">
<result column="account" property="account"></result>
</association>
</resultMap>
<select id="getEmlpyeeById1" resultMap="emp1">
SELECT
id,
name,
age,
deptId,
adminId
FROM employee
WHERE id = #{id}
</select>
<select id="findDeptById" resultType="Dept">
select name from dept where id = #{deptId};
</select>
<select id="findAdminById" resultType="Admin">
select account from admin where id = #{adminId};
</select>
调用方法
@Test
public void find2(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmployerMapper mapper = sqlSession.getMapper(EmployerMapper.class);
Employer employer = mapper.getEmlpyeeById1(2);
System.out.println(employer.getName());
System.out.println(employer.getDept().getName());
System.out.println(employer.getAdmin().getAccount());
System.out.println(employer);
sqlSession.commit();
sqlSession.close();
}
嵌套查询首次查询时,只查询主表的信息,关联表信息的获取是在用户需求时,再加载得到的。
懒加载(按需加载)
懒加载的使用可以有效的减少数据库的压力。
懒加载就是在嵌套循环上加了一个setting的全局配置。
在标签里也要这个这个赋上lazy值,fetchType="lazy"意为开启延迟加载(需要时,才会触发查询) 懒加载的前提就是首先必须是一个嵌套查询
在核心配置文件中通过 settings 配置 lazyLoadingEnabled 来关闭嵌套查询。
<settings>
<setting name="lazyLoadTriggerMethods" value=""/>
</settings>
以上面的嵌套循环为基础,实现这个懒加载。
打一个断点,使用debug进行一步一步调试。
- 第一个
- 第二个
- 第三个
这就是懒加载的方式与过程。
上一篇:>>> Mybatis对数据的增删改查
|