mybatis学习之高级映射
一对一映射查询
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学习之高级映射的更多相关文章
- 【mybatis深度历险系列】mybatis中的高级映射一对一、一对多、多对多
学习hibernate的时候,小编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博文,小编主要来简单的介绍一下mybatis中的高级映射,包括一对一.一对多.多对多,希望多有需要 ...
- mybatis入门基础----高级映射(一对一,一对多,多对多)
阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id ...
- mybatis学习(一)-------XML 映射配置文件详解
XML 映射配置文件 MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置(settings)和属性(properties)信息.文档的顶层结构如下: configuration 配 ...
- Mybatis学习--Mapper.xml映射文件
简介 Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 映射文件中有很多属性,常用的就是parameterType(输入类型 ...
- mybatis学习------打包xml映射文件
编译mybatis时,idea不会将mybatis的xml映射文件一起打包进jar,即在编译好的jar包里缺少mybatis映射文件,导致网站加载失败 为解决这个问题,可在mybatis对应modul ...
- mybatis学习第(二)天
Mybatis第二天 高级映射 查询缓存 关于与spring的整合和反转工程我偷懒了,下次看. 使用的sql: CREATE TABLE USER( id INT PRIMARY KEY A ...
- Mybatis学习(四)————— 高级映射,一对一,一对多,多对多映射
一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部 ...
- Mybatis学习总结(六)——高级映射(一对一,一对多,多对多)
一.订单商品数据模型 1.数据库执行脚本 创建数据库表代码: /*Table structure for table `t_user` */ CREATE TABLE t_user ( id INT ...
- MyBatis学习--高级映射
简介 前面说过了简单的数据库查询和管理查询,在开发需求中有一些一对一.一对多和多对多的需求开发,如在开发购物车的时候,订单和用户是一对一,用户和订单是一对多,用户和商品是多对多.这些在Hibernat ...
随机推荐
- Pycharm中安装Pygame并写第一个程序
第一步:打开Pycharm 第二步:点File ->Default Settings->Project Interpreter->点加号 第三步: 搜索Pygame->Inst ...
- js验证汉字正则表达式
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- 原生态js单个点击展开收缩
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- uC/OS-II 函数之内存管理相关函数
上文主要介绍了邮箱管理相关的函数,本文介绍内存管理相关的函数:OSMemCreate()内存块创建函数,OSMemGet()函数,OSMemPut()函数,OSMemQuery()函数.以前用过的uC ...
- python3入门之print,import,input介绍
本节主要介绍print,import和input,t函数,包括他们在python2.7和python3 的区别以及用法.下面附有之前的文章: python3的print函数的变化 python3之 ...
- 线上CPU100%?看看这篇是怎么排查的!
前言 作为后端开发工程师,当收到线上服务器CPU负载过高告警时,你会这么做?重启服务,忽略告警?不过在我看来一个合格的工程师是一定要定位到具体问题所在的,从而 fix 它.下面记录一下线上服务器 CP ...
- 移动端一个奇怪的触摸bug
这两天遇到一个很奇怪的bug,在移动端,一个页面里所有的input框都不能点击,我查了一下,里面的没有设置readonly属性,只要页面滚动一下就可以用了,而且,只要我在真机测试的时候,f12开发者模 ...
- P1642 规划 01分数规划+树形DP
$ \color{#0066ff}{ 题目描述 }$ 某地方有N个工厂,有N-1条路连接它们,且它们两两都可达.每个工厂都有一个产量值和一个污染值.现在工厂要进行规划,拆除其中的M个工厂,使得剩下的工 ...
- 使用Avd 调试慢的解决方案
AVD 太慢了,不仅启动,而且运行慢.以致于要用手机去调.你觉得这样方便吗? 如果没有一个简单快速的开发调试环境,把时间都浪费在启动,调试及等待上,那是对生命的浪费. 必要条件: ...
- 北京DNS
202.106.0.20 202.106.196.115 202.106.46.151