一对一映射查询

1、数据库执行脚本:

/*
SQLyog Ultimate v12.09 (64 bit)
MySQL - 5.7.11-log : Database - db_mybatis
*********************************************************************
*/ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=''*/; /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`db_mybatis` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci */; USE `db_mybatis`; /*Table structure for table `t_address` */ DROP TABLE IF EXISTS `t_address`; CREATE TABLE `t_address` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pro` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`city` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`country` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*Data for the table `t_address` */ insert into `t_address`(`id`,`pro`,`city`,`country`) values (1,'江苏省','苏州市','姑苏区'),(2,'江苏省','南京市','鼓楼区'); /*Table structure for table `t_student` */ DROP TABLE IF EXISTS `t_student`; CREATE TABLE `t_student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`addressId` int(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `addressId` (`addressId`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; /*Data for the table `t_student` */ insert into `t_student`(`id`,`name`,`age`,`addressId`) values (32,'张三那',23,1); /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

这里使用2张表,学生表t_student、地址表t_address,演示查询学生时查询出对应的地址对象,首先是StudentDao:

package com.cz.mappers;

import java.util.List;

import com.cz.model.Student;

public interface StudentDao {
/**
* 新增
* @param student
* @return
*/
public int add(Student student);
/**
* 修改
* @param student
* @return
*/
public int update(Student student);
/**
* 删除
* @param student
* @return
*/
public int delete(Integer id);
/**
* 根据id查找
* @param id
* @return
*/
public Student findById(Integer id);
/**
* 查找
* @param id
* @return
*/
public List<Student> find(); /**
* 根据学生id查询带地址的学生信息
* @param id
* @return
*/
public Student findWithAddr(Integer id);
}

Student实体类:

package com.cz.model;

public class Student {

    private Integer id;
private String name;
private int age; private Address address; public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} public Student(Integer id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
} public Student() {
super();
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} public Integer getId() {
return id;
}
public void setId(Integer 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;
} @Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
} }

Address实体类:

package com.cz.model;

public class Address {

    private Integer id;
private String pro;
private String city;
private String country; public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPro() {
return pro;
}
public void setPro(String pro) {
this.pro = pro;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
@Override
public String toString() {
return "Address [id=" + id + ", pro=" + pro + ", city=" + city + ", country=" + country + "]";
} }

AddressDao:

package com.cz.mappers;

import com.cz.model.Address;

public interface AddressDao {
/**
* 根据id查找
* @param id
* @return
*/
public Address findById(Integer id); }

StudentMapper.xml映射文件:

1)、直接result属性映射

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<result property="address.id" column="addressId"/>
<result property="address.pro" column="pro"/>
<result property="address.city" column="city"/>
<result property="address.country" column="country"/>
</resultMap> <select id="findWithAddr" parameterType="Integer" resultMap="StudentResult">
select * from t_student t1,t_address t2 where t1.addressId = t2.id and t1.id = #{id}
</select>

这里直接配置对应property属性,column为数据库对应的字段名称,property为javabean对应的字段,这里使用address.id,mybatis会自动为我们进行封装,封装到Student实体的Address属性上。

junit测试如下:

package com.cz.test;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.cz.mappers.StudentDao;
import com.cz.model.Student;
import com.cz.utill.SqlSessionFactoryUtil; public class StudentTest2 { public static Logger logger = Logger.getLogger(StudentTest2.class);
SqlSession sqlSession = null;
StudentDao studentDao = null; // 返回student dao接口 @Before
public void setUp() throws Exception {
sqlSession = SqlSessionFactoryUtil.openSession();
studentDao = sqlSession.getMapper(StudentDao.class);
logger.info("开始执行了");
} @After
public void tearDown() throws Exception {
sqlSession.close();
logger.info("执行结束了");
} /**
* 学生查询,带地址查询
* @throws Exception
*/
@Test
public void testFindWithAddr() throws Exception {
Student student = studentDao.findWithAddr(32);
sqlSession.commit();
System.out.println(student);
}
}

2)、Association和ResultMap形式:

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/> <association property="address" resultMap="AddressResult"/> </resultMap> <resultMap type="Address" id="AddressResult">
<result property="id" column="id"/>
<result property="pro" column="pro"/>
<result property="city" column="city"/>
<result property="country" column="country"/>
</resultMap>

3)、第二种方式映射时,Address的resultMap嵌套在Student的映射文件中,不利于代码的复用,改进版:

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/> <association property="address" column="addressId" select="com.cz.mappers.AddressDao.findById"></association>
</resultMap>

这里使用association进行关联映射,column为Student实体对应的表中关联address的字段名称,select表示该字段值通过其它映射语句直接查询返回,传的id参数即这里的addressId,AddressMapper.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.cz.mappers.AddressDao"> <resultMap type="Address" id="AddressResult">
<result property="id" column="id"/>
<result property="pro" column="pro"/>
<result property="city" column="city"/>
<result property="country" column="country"/>
</resultMap>
<select id="findById" resultType="Address" parameterType="Integer"> select * from t_address where id=#{id} </select>
</mapper>

一对多映射查询

1、数据导入:

/*
Navicat MySQL Data Transfer Source Server : 192.168.20.132
Source Server Version : 50711
Source Host : localhost:3306
Source Database : db_mybatis Target Server Type : MYSQL
Target Server Version : 50711
File Encoding : 65001 Date: 2016-07-01 17:53:44
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for t_grade
-- ----------------------------
DROP TABLE IF EXISTS `t_grade`;
CREATE TABLE `t_grade` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`gradeName` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- ----------------------------
-- Records of t_grade
-- ----------------------------
INSERT INTO `t_grade` VALUES ('', '一年级');
INSERT INTO `t_grade` VALUES ('', '二年级');

新建年级表t_grade,年级对学生为一对多关系。

首先是根据年级查询该年级下的所有学生:

1)、新建Grade实体类:

package com.cz.model;
import java.util.List; /**
* 年级类
* @author Administrator
*
*/
public class Grade { private Integer id;
private String gradeName; private List<Student> students; public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getGradeName() {
return gradeName;
} public void setGradeName(String gradeName) {
this.gradeName = gradeName;
} public List<Student> getStudents() {
return students;
} public void setStudents(List<Student> students) {
this.students = students;
} @Override
public String toString() {
return "Grade [id=" + id + ", gradeName=" + gradeName + "]";
} }

通过students实例属性关联,然后是GradeDao接口实现:

package com.cz.mappers;

import com.cz.model.Grade;

public interface GradeDao {
/**
* 根据id查找(完整字段)
* @param id
* @return
*/
public Grade findById(Integer id);
}

只有一个方法findById,这里查询时会顺带查出该年级下的所有学生信息,GradeMapper映射文件如下:

<?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.cz.mappers.GradeDao"> <resultMap type="Grade" id="GradeResult">
<result property="id" column="id" />
<result property="gradeName" column="gradeName" /> <!-- 映射students集合 -->
<collection property="students" column="id" select="com.cz.mappers.StudentDao.findByGradeId"></collection>
</resultMap> <select id="findById" parameterType="Integer" resultMap="GradeResult">
select * from t_grade where id = #{id}
</select>
</mapper>

mybatis多对一关联使用collection标签实现,column为Grade实体对应的表的字段,select表示使用该字段进行关联查询,StudentDao的findByGradeId具体实现如下:

首先是Dao层:

package com.cz.mappers;

import java.util.List;

import com.cz.model.Student;

public interface StudentDao {
/**
* 新增
* @param student
* @return
*/
public int add(Student student);
/**
* 修改
* @param student
* @return
*/
public int update(Student student);
/**
* 删除
* @param student
* @return
*/
public int delete(Integer id);
/**
* 根据id查找
* @param id
* @return
*/
public Student findById(Integer id);
/**
* 查找
* @param id
* @return
*/
public List<Student> find(); /**
* 根据学生id查询带地址的学生信息
* @param id
* @return
*/
public Student findWithAddr(Integer id);
/**
* 根据gradeId查询Student对象
* @param id
* @return
*/
public List<Student> findByGradeId(Integer gradeId);
}

然后是映射文件:

<?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.cz.mappers.GradeDao"> <resultMap type="Grade" id="GradeResult">
<result property="id" column="id" />
<result property="gradeName" column="gradeName" /> <!-- 映射students集合 -->
<collection property="students" column="id" select="com.cz.mappers.StudentDao.findByGradeId"></collection>
</resultMap> <select id="findById" parameterType="Integer" resultMap="GradeResult">
select * from t_grade where id = #{id}
</select>
</mapper>

然后是StudentDao对应的映射文件StudentMapper:

<resultMap type="Student" id="StudentResult">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/> <!-- 一对一关联 -->
<association property="address" column="addressId" select="com.cz.mappers.AddressDao.findById"></association>
<association property="grade" column="gradeId" select="com.cz.mappers.GradeDao.findById"></association>
</resultMap> <select id="findByGradeId" parameterType="Integer" resultMap="StudentResult">
select * from t_student where gradeId = #{gradeId}
</select>

这里Student配置了一个grade属性,目的是后边查询学生顺带查询出其所属的班级信息,Student实体具体实现:

package com.cz.model;

public class Student {

    private Integer id;
private String name;
private int age; private Address address; private Grade grade; public Student(String name, int age) {
super();
this.name = name;
this.age = age;
} public Student(Integer id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
} public Student() {
super();
} public Address getAddress() {
return address;
} public void setAddress(Address address) {
this.address = address;
} public Integer getId() {
return id;
}
public void setId(Integer 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 Grade getGrade() {
return grade;
} public void setGrade(Grade grade) {
this.grade = grade;
} @Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + ", grade=" + grade
+ "]";
} }

junit测试部分(根据学生查询对应年级信息):

/**
* 学生查询,带地址查询
* @throws Exception
*/
@Test
public void testFindWithAddr() throws Exception {
Student student = studentDao.findWithAddr(32);
sqlSession.commit();
System.out.println(student);
}

junit测试部分(根据年级信息查询对应学生信息):

package com.cz.test;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; import com.cz.mappers.GradeDao;
import com.cz.model.Grade;
import com.cz.utill.SqlSessionFactoryUtil; public class GradeTest { public static Logger logger = Logger.getLogger(GradeTest.class);
SqlSession sqlSession = null;
GradeDao gradeDao = null; // 返回student dao接口 @Before
public void setUp() throws Exception {
sqlSession = SqlSessionFactoryUtil.openSession();
gradeDao = sqlSession.getMapper(GradeDao.class);
logger.info("开始执行了");
} @After
public void tearDown() throws Exception {
sqlSession.close();
logger.info("执行结束了"); } /**
* 年级查询(加年级下所有学生信息)
* @throws Exception
*/
@Test
public void testFindGradeWithStudents() throws Exception {
Grade grade = gradeDao.findById(1);
System.out.println(grade);
}
}

mybatis学习之高级映射的更多相关文章

  1. 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多

    学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...

  2. mybatis入门基础----高级映射(一对一,一对多,多对多)

    阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id ...

  3. mybatis学习(一)-------XML 映射配置文件详解

    XML 映射配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配 ...

  4. Mybatis学习--Mapper.xml映射文件

    简介 Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 映射文件中有很多属性,常用的就是parameterType(输入类型 ...

  5. mybatis学习------打包xml映射文件

    编译mybatis时,idea不会将mybatis的xml映射文件一起打包进jar,即在编译好的jar包里缺少mybatis映射文件,导致网站加载失败 为解决这个问题,可在mybatis对应modul ...

  6. mybatis学习第(二)天

    Mybatis第二天    高级映射   查询缓存 关于与spring的整合和反转工程我偷懒了,下次看. 使用的sql: CREATE TABLE USER( id INT PRIMARY KEY A ...

  7. Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射

    一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...

  8. Mybatis学习总结(六)——高级映射(一对一,一对多,多对多)

    一.订单商品数据模型 1.数据库执行脚本 创建数据库表代码: /*Table structure for table `t_user` */ CREATE TABLE t_user ( id INT ...

  9. MyBatis学习--高级映射

    简介 前面说过了简单的数据库查询和管理查询,在开发需求中有一些一对一.一对多和多对多的需求开发,如在开发购物车的时候,订单和用户是一对一,用户和订单是一对多,用户和商品是多对多.这些在Hibernat ...

随机推荐

  1. Maven项目编译时报错缺少tools.jar

    [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile (default ...

  2. 二十一、Node.js-EJS 模块引擎

    初识 EJS 模块引擎 我们学的 EJS 是后台模板,可以把我们数据库和文件读取的数据显示到 Html 页面上面.它是一个第三方模块,需要通过 npm 安装https://www.npmjs.com/ ...

  3. 实体bean里面不要轻易加transient,反序列回来之后会变成null

     实体bean里面不要轻易加transient,反序列回来之后会变成null

  4. TCP/IP协议之分层

     应用层和运输层只在端系统(End System)中实现, 底层协议在中间系统(Intermediate System)实现 ICMP和IGMP属于网络层的附属协议.虽然其内容是IP数据报的载荷(P ...

  5. 题目1022:游船出租(hash简单应用)

    问题来源 http://ac.jobdu.com/problem.php?pid=1022 问题描述 每次输入:船号(1~100) 键值(S或E) 发生时间(小时:分钟).当船号为0时,代表一天结束: ...

  6. Hibernate 初识

    第一步: 导包:(这是我根据其他网站的介绍导入的包,可能不完善,但开发没什么问题,遇到问题再说) 当然还有mysql的jar包 第二步:进行hibernate环境配置 在classpath目录下建立h ...

  7. python的builtins模块

    builtins模块详解 1.简介 builtins是python的内建模块,所谓内建模块就是你在使用时不需要import,在python启 动后,在没有执行程序员编写的任何代码前,python会加载 ...

  8. bzoj 3261 最大异或和 可持久化字典树(01树)

    题目传送门 思路: 由异或的性质可得,题目要求的式子可以转化成求$max(pre[n]^x^pre[i])$,$pre[i]$表示前缀异或和,那么我们现在就要求出这个东西,所以用可持久化字典树来求,每 ...

  9. HDU - 5306 剪枝的线段树

    题意:给定\(a[1...n]\),\(m\)次操作,0表示使\([L,R]\)中的值\(a[i]=min(a[i],x)\),其余的1是查最值2是查区间和 本题是吉利爷的2016论文题,1 2套路不 ...

  10. Drupal Coder 模块远程命令执行分析(SA-CONTRIB-2016-039)

    转载请注明文章出处:http://www.cnblogs.com/magic-zero/p/5787181.html 起初看到这个漏洞的时候是在exploit-db上边.地址在这里:https://w ...