文档章节

mybatis学习之高级映射

c
 caiyezi
发布于 2016/11/08 20:24
字数 2054
阅读 3
收藏 0

一对一映射查询

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 ('1', '一年级');
INSERT INTO `t_grade` VALUES ('2', '二年级');

新建年级表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);
    }
}

本文转载自:http://www.cnblogs.com/vipzhou/p/5633404.html

共有 人打赏支持
c
粉丝 1
博文 108
码字总数 0
作品 0
西安
程序员
私信 提问
mybatis学习笔记(2)-mybatis概述

mybatis学习笔记(2)-mybatis概述 标签: mybatis [TOC] 本文对mybatis做一个简单介绍,包括框架原理,执行过程,开发方法,输入输出映射以及动态sql,我会在后续的系列文章中一一详细说明 my...

brianway
2016/02/27
334
0
MyBatis中如何通过继承SqlSessionDaoSupport来编写DAO(二)

(本文示例工程源代码下载地址:http://down.51cto.com/data/1975295) 在上一篇博文的最后,介绍了使用@PostConstruct注解标注StudentDao的init方法,这样在Spring完成依赖注入后此方法即会...

NashMaster2011
2015/01/14
0
0
springMVC+mybatis+mysql学习心得

MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。 MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。 MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、...

magelee
2015/07/14
0
1
Hibernate 与mybatis的区别

首先简单介绍下两者的概念: Hibernate :Hibernate 是当前最流行的ORM框架,对数据库结构提供了较为完整的封装。 Mybatis:Mybatis同样也是非常流行的ORM框架,主要着力点在于POJO 与SQL之间...

quickhelper
2015/08/12
0
0
mybatis(八)mapper映射文件配置之select、resultMap

上篇介绍了insert、update、delete的用法,本篇将介绍select、resultMap的用法。select无疑是我们最常用,也是最复杂的,mybatis通过resultMap能帮助我们很好地进行高级映射。下面就开始看看...

LCZ777
2014/12/19
0
0

没有更多内容

加载失败,请刷新页面

加载更多

前端工程师的知识体系

Front-End Engineer 这词很好的体现了前端的特(ku)殊(bi)性。 下图是张克军绘制的前端工程师图解: 前端开发的核心是HTML + CSS + JavaScript。本质上它们构成一个MVC框架,即HTML作为信息模...

文文1
9分钟前
0
0
随行付微服务测试之性能测试

背景 传统性能测试更多的是以事务为核心,更多的是由单个或者多个事务构成业务场景进行压测。全链路压测指完全引入相关联的系统,尽量真实模拟线上硬件环境,更多的是以请求为核心,完全模拟...

马力-随行付
12分钟前
0
0
JavaScript是如何工作的:事件循环和异步编程的崛起 + 5种使用 async/await 更好地编码方式!

摘要: 深度理解JS事件循环!!! 原文:JavaScript是如何工作的:事件循环和异步编程的崛起+ 5种使用 async/await 更好地编码方式! 作者:前端小智 Fundebug经授权转载,版权归原作者所有。...

Fundebug
12分钟前
0
0
hanlp在Python环境中的安装失败后的解决方法

Hanlp是由一系列模型与算法组成的javag工具包,目标是普及自然语言处理再生环境中的应用。有很多人在安装hanlp的时候会遇到安装失败的情况,下面就是某大神的分享的在python环境中安装失败的...

左手的倒影
34分钟前
1
0
【更新】Infragistics Ultimate UI for WPF v18.2(二):分类图

下载Infragistics Ultimate UI for WPF最新版本 Infragistics Ultimate UI for WPF是一款提供高速的网格和图表,轻松创建仿Office应用程序的WPF界面框架,从广度和深度两方面使得开发者在缩短...

电池盒
34分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部