• 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 ('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);
        }
    }

  • 相关阅读:
    CLR via C#
    一些写英文简历的词汇
    组合与组合数
    A lowlevel Look at the ASP.NET Architecture
    \r与\n的区别,\r\n与\n或\r的区别(C语言/C#)
    Canvas lineWidth 属性 【每日一段代码18】
    程序员三大世界观 如何看待HTML5
    Canvas运用样式与颜色fillStyle【每日一段代码15】
    Canvas绘制路径:贝塞尔曲线【每日一段代码12】
    Canvas绘制弧形【每日一段代码10】
  • 原文地址:https://www.cnblogs.com/vipzhou/p/5633404.html
Copyright © 2020-2023  润新知