0


Mybatis如何实现多表查询:(一对一,一对多)

提示:在阅读本篇文章之前,大家应该熟练掌握SQL的多表联查语句,有助于提高大家对本篇文章的理解,用到的工具依旧是我们熟悉的eclipse。

前言:

mybatis作为一个半自动的ORM模型,内部封装了jdbc,并且通过注解或者xml文件的形式完成了加载驱动,创建连接,创建Statement等繁琐过程,并通过java对象和statement中sql的动态参数进行银蛇生成最终执行的sql语句,最后由mybatis框架执行SQL并将返回结果映射称java对象并返回。本篇文章将用注解和xml文件两种方式对多表联查进行讲解。


实现mybatis多表联查的步骤如下:

①首先我们先来熟悉要用到的两张表的表关系:

学生表(student)

班级表(class)

从上图两张表中我们可以看出,

对于学生表来说,一个学生只能对应一个班级信息,所以学生=》班级就是一对一关系。

对于班级表来说,一个班级可以有多名学生信息,所以班级=》学生就是一对多关系。

②创建项目以及创建学生和班级实体类,和sqlsession的封装

创建普通java项目,导入相关jar包,如下图:

封装sqlsession,创建Daoutil

package com.ape.dao;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class DaoUtil {
private static SqlSessionFactory build;
    
    static {
        try {
            // 1. 加载配置文件
            InputStream    istem = Resources.getResourceAsStream("mybatis-config.xml");
            // 2. 构建 sqlsession工厂对象(工厂模式)
            build = new SqlSessionFactoryBuilder().build(istem);
            
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    
    
    public static SqlSession getSqlSession() {
        return build.openSession();
    }
    
    
    public static void closeSource(SqlSession sqlSession) {
        sqlSession.close();
    }

}

**创建学生和班级类 **

**学生类(Student): **

**我们会将banji类的对象做为外部属性封装到Student类中 **

package com.ape.bean;

import java.util.Date;

public class Student {
    private int sid;
    private String sname;
    private Date birthday;
    private String ssex;
    private int classid;
    
    //外部属性
    Banji bj = new Banji();
    
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getSsex() {
        return ssex;
    }
    public void setSsex(String ssex) {
        this.ssex = ssex;
    }
    public int getClassid() {
        return classid;
    }
    public void setClassid(int classid) {
        this.classid = classid;
    }
    public Banji getBj() {
        return bj;
    }
    public void setBj(Banji bj) {
        this.bj = bj;
    }
    public Student() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Student(int sid, String sname, Date birthday, String ssex, int classid, Banji bj) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.birthday = birthday;
        this.ssex = ssex;
        this.classid = classid;
        this.bj = bj;
    }
    @Override
    public String toString() {
        return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", ssex=" + ssex + ", classid="
                + classid + ", bj=" + bj + "]";
    }
    
    
    
    

}

班级类(Banji)java中不能将类名设置成class

**我们会将Studnet类的集合作为外部属性封装到Banji类中 **

package com.ape.bean;

import java.util.List;

public class Banji {
    private int classid;
    private String classname;
    
    //外部属性
    List<Student> list;
    
    public int getClassid() {
        return classid;
    }
    public void setClassid(int classid) {
        this.classid = classid;
    }
    public String getClassname() {
        return classname;
    }
    public void setClassname(String classname) {
        this.classname = classname;
    }
    public List<Student> getList() {
        return list;
    }
    public void setList(List<Student> list) {
        this.list = list;
    }
    public Banji() {
        super();
        // TODO Auto-generated constructor stub
    }
    public Banji(int classid, String classname, List<Student> list) {
        super();
        this.classid = classid;
        this.classname = classname;
        this.list = list;
    }
    @Override
    public String toString() {
        return "Banji [classid=" + classid + ", classname=" + classname + ", list=" + list + "]";
    }
}

③完成上述步骤后,我们将从xml文件和注解两种方式对多表联查进行讲解

XML文件形式:

一对一:(学生=》班级):

创建StudentMapper接口:

package com.ape.mapper;

import java.util.List;

import com.ape.bean.Student;

public interface StudentMapper {
    //一对一查找学生和班级
    public List<Student> findStudentAndBanji();

}

创建StudentMapper的xml文件:

这里我们用到了标签<association>,标签内的属性property中间依旧写实体类中外部属性的对象名称,在标签中间,照常写外部属性的信息映射,字段和属性关系映射。

<?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.ape.mapper.StudentMapper">
        <!-- 类路径 -->     
     <!-- 一对以学生和班级 -->
     <resultMap type="Student" id="StudentMapper">
         <id column="sid" property="sid"/>
         <result column="sname" property="sname"/>
         <result column="birthday" property="birthday"/>
         <result column="ssex" property="ssex"/>
         <result column="classid" property="classid"/>
             <association property="bj">
                 <result column="classid" property="classid"/>
                 <result column="classname" property="classname"/>
             </association>
     </resultMap>
     <select id="findStudentAndBanji" resultMap="StudentMapper">
         select * from Student left join class on student.classid = class.classid
     </select>

</mapper>

测设类:

package com.ape.test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.StudentMapper;

public class TestfindStudentAndBanji {
    public static void main(String[] args) {
        SqlSession sqlSession = DaoUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> list = mapper.findStudentAndBanji();
        
        for (Student s:list) {
            System.out.println(s);
        }
        
        sqlSession.close();
    }

}

可以看到其中班级信息显示出来了,证明一对一多表联查映射成功!!!

一对多(班级=》学生):

创建BanjiMapper接口:

package com.ape.mapper;

import java.util.List;

import com.ape.bean.Banji;

public interface BanjiMapper {
    //一对多映射(班级学生)
    public List<Banji> findBanjiAndStudent();

}

创建BanjiMapper的xml文件:

这里我们用到了标签<collection>,其中属性property写实体类中外部属性Studnet集合的名称,ofYupe写集合中元素的类型,这里就写Student类。

<?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.ape.mapper.BanjiMapper">
        <!-- 类路径 -->
        <!-- 一对多结果集关系映射 -->
        <resultMap type="Banji" id="BanjiMapper">
            <id column="classid" property="classid"/>
            <result column="classname" property="classname"/>
            <collection property="list" ofType="Student">
                <id column="sid" property="sid"/>
                 <result column="sname" property="sname"/>
                 <result column="birthday" property="birthday"/>
                 <result column="ssex" property="ssex"/>
                 <result column="classid" property="classid"/>
            </collection>
        </resultMap>
        <!-- 班级和学生全查 -->
        <select id="findBanjiAndStudent" resultMap="BanjiMapper">
            select * from class inner join student on class.classid = student.classid
            order by class.classid
        </select>
     
</mapper>

测试类:

package com.ape.test;

import java.util.Date;
import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.ape.bean.Banji;
import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.BanjiMapper;

public class TestfindBanjiAndStudent {
    public static void main(String[] args) {
        SqlSession sqlSession = DaoUtil.getSqlSession();
        BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
        List<Banji> list = mapper.findBanjiAndStudent();
        
        for (Banji b : list) {
            System.out.println("班级名称:"+b.getClassname());
            for (Student s : b.getList()) {
                int sid = s.getSid();
                String sname = s.getSname();
                Date birthday = s.getBirthday();
                String ssex = s.getSsex();
                int classid = s.getClassid();
                System.out.println("学生编号:"+sid+" 学生姓名:"+sname+" 学生生日:"+birthday+" 学生性别:"+ssex+" 班级编号:"+classid);
                
            }
            System.out.println("================");
        }
    }

}

注解的形式:

一对一(学生=》班级):

创建StudentMapper接口文件:

用@Results和@Result写对应字段和属性的关系映射。

用@One注解写实体类中外部属性的关系映射,select中写调用方法的类路径,这里相当于将classid字段信息传入findAllBanjiByClassid方法中,通过classid查询学生信息之后返回到结果集中。

package com.ape.mapper;

import java.util.List;

import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.jdbc.SQL;

import com.ape.bean.Student;

public interface StudentMapper {
    //根据班级classid查询学生信息
    @Select("select * from Student where classid=#{classid}")
    public List<Student> findAllStudentByClassid();

    //一对一映射(学生班级)
    @Results(id = "StudentAndBanjiMapper",value = {
            @Result(column = "classid",property = "classid"),
            @Result(column = "classid",property = "bj",
            one=@One(select = "com.ape.mapper.BanjiMapper.findAllBanjiByClassid")
            )
    })
    @Select("select * from student")
    public List<Student> findAllStudentAndBanji();
    
}

测试类:

package com.ape.teat;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.StudentMapper;

public class TestfindAllStudentAndBanji {
    public static void main(String[] args) {
        SqlSession sqlSession = DaoUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        
        List<Student> list = mapper.findAllStudentAndBanji();
        
        for (Student student : list) {
            System.out.println(student);
        }
        
        sqlSession.close();
    }

}

一对多(班级=》学生):

创建BanjiMapper接口:

依旧使用@Results和@Result进行字段和属性的映射,对于外部属性Studnet集合我们使用@Many注解进行关系映射,select中还是写入调用的方法,相当于对奥用方法查询班级中所有的学生信息放入集合中,然后映射到结果集中。

package com.ape.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.ape.bean.Banji;

public interface BanjiMapper {
    //通过classid查询班级信息
    @Select("select * from class where classid=#{classid}")
    public List<Banji> findAllBanjiByClassid();
    
    
    //一对多映射(班级和学生)
    @Results(id = "findAllBanjiAndStudent",value = {
            @Result(column = "classid",property = "list",many=@Many(select = "com.ape.mapper.StudentMapper.findAllStudentByClassid")
            )    
    })
    @Select("select * from class")
    public List<Banji> findAllBanjiAndStudent();

}

测试类:

package com.ape.teat;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.ape.bean.Banji;
import com.ape.dao.DaoUtil;
import com.ape.mapper.BanjiMapper;

public class TestfindAllBanjiAndStudent {
    public static void main(String[] args) {
        SqlSession sqlSession = DaoUtil.getSqlSession();
        BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
        List<Banji> list = mapper.findAllBanjiAndStudent();
        
        for (Banji banji : list) {
            System.out.println(banji);
        }
        
        sqlSession.close();
    }

}

总结:

方式一:sqlMapper配置文件

**一对一:在resultMap标签中使用 association 标签 **

一对多:在resultMap 标签中使用collection 标签

**方式二:注解 **

**一对一:在@Results 注解中的@Result注解中使用@One注解 **

一对多:在@Results 注解中的@Result 注解中使用@Many注解

最后的最后!!!分享一句从顿顿老师那里听到的名言:

     让你的生活如夏花一般绚烂,让不开心的事情像秋叶一般宁静❥(^_-)

     Let life be beautiful like summer flowers and death like autumn leaves.

                                            ——泰戈尔《生如夏花》
标签: mybatis java 数据库

本文转载自: https://blog.csdn.net/m0_46420244/article/details/125470353
版权归原作者 飘飘~ 所有, 如有侵权,请联系我们删除。

“Mybatis如何实现多表查询:(一对一,一对多)”的评论:

还没有评论