mybatis一对多等

resultMap属性和resultType属性区别

resultType :指定输出结果的类型(pojo、简单类型、hashmap…),将sql查询结果映射为java对象 。

  • 使用resultType注意:sql查询的列名要和resultType指定pojo的属性名相同,指定相同 属性方可映射成功,如果sql查询的列名要和resultType指定pojo的属性名全部不相同,list中无法创建pojo对象的。

resultMap:将sql查询结果映射为java对象。

  • 如果sql查询列名和最终要映射的pojo的属性名不一致**,使用resultMap将列名和pojo的属性名做一个对应关系 (列名和属性名映射配置)**

一对一(association案例)

需求:

  • 学生和身份证表
  • 查询一号学生的信息以及身份证信息

1.创建表

create table card
(
	id int primary key,
	num varchar(20) not null
);
create table student(
id int primary key,
name varchar(10),
cardId int  references card(id)
);

insert into card values(1,1);
insert into card values(2,2);
insert into student values(1,"陈伟斌",1);
insert into student values(2,"彭于晏",2);
select * from card;
select * from student;

2.创建pojo

public class Card {
    Integer id;
    String num;
    //getter and setter
}
public class Student {
    Integer id ;
    String name;
    Card card;
     //getter and setter
}

3. 创建映射文件(重点)并加入到全局配置文件

resultMap标签内:

  • 使用association和collection完成一对一和一对多高级映射。

    • association<-------->pojo对象
    • collection<-------->list集合多个pojo
    association:
    
    作用:
    
    将关联查询信息映射到一个pojo类中。
    场合:
    
    为了方便获取关联信息可以使用association将关联订单映射为pojo,比如:查询订单及关联用户信息。
    ########################################################    
    collection:
    
    作用:
    
    将关联查询信息映射到一个list集合中。
    场合:
    
    为了方便获取关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块和功能,可使用collection将模块和功能列表映射到list中。
    
    

    1.CardMapper.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="CardMapper">
        <resultMap id="cardResult" type="Domin.Card">
            <id property="id" column="id"></id>
            <result property="num" column="num"></result>
        </resultMap>
    </mapper>
    

    2.StudentMapper.xml

    <mapper namespace="Mapper.StudentMapper">
        <resultMap id="studentResult" type="Domin.Student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <!--
                将关联属性进行关联起来
               property写的是在Student实体中写关联字段的属性变量名称
               resultMap写的是映射文件中的命名空间.id   最终填充到哪个pojo
           -->
            <association property="card" resultMap="CardMapper.cardResult" />
        </resultMap>
    
        <select id="findStudentAndCardById" resultMap="studentResult" parameterType="int">
            select * from student s, card c where s.cardId=c.id and s.id=#{id}
        </select>
    </mapper>
    

    3.全局配置文件中注册

      <mappers>
            <mapper resource="StudentMapper.xml"/>
            <mapper resource="CardMapper.xml"/>
        </mappers>
    

4.编写Mapper接口(即dao层)

StudentMapper.java

public interface StudentMapper {
    public Student findStudentAndCardById(Integer id);
}

5.测试

public class StudentService {

    public static Student findStudentAndCardById(Integer i){
        SqlSession sqlSession= MybatisUtil.getSqlSession();
        // Mapper.StudentMapper.class 接口的class
        StudentMapper studentMapper= sqlSession.getMapper(Mapper.StudentMapper.class);
        return studentMapper.findStudentAndCardById(i);

    }

    public static void main(String[] args) {
       Student student= StudentService.findStudentAndCardById(1);
        System.out.println(student.getName());
        System.out.println(student.getCard().getNum());
    }
}

注:也可以分两次连接查询将数据分别封装在Student和Card中

要获得完整的student即包含card对象的student必须通过association

MybatisUtil在mybatis基础中有源码展示

一对多(collection案例)

需求:

  • 查询名为实验班的班级(grade)的学生信息
  • 查询名为实验班的班级的班级信息所有学生的信息
  • grade 和student是一对多的关系

1.创建表

create table grade(
 id int primary key,
 name varchar(20)
);
create table student(
	id int primary key,
	name varchar(10) not null,
	cardId int,
	gradeId int,
	constraint student_card foreign key (cardId) references card(id),
	constraint student_grade foreign key (gradeId) references garde(id)
);
insert into grade values(1,"实验班)                

2.创建pojo

public class Student {
    Integer id ;
    String name;
    Card card;
    Grade grade;
// getter and setter
}
public class Grade {
    Integer id;
    String name;
    List<Student> students;
// getter and setter
}

3.创建映射文件,并加入到全局配置文件

问题1:查询名为实验班的班级(grade)的学生信息,因为仅仅是查找学生信息用连接查询就行

因为仅获得学生的信息,所以在StudentMapper.xml中配置如下sql:

    <select id="findStudentByGradeName"  resultMap="studentResult" parameterType="string">
        select * from student s, grade g where s.gradeId=g.id and g.name=#{name}
    </select>

问题2:查询名为实验班的班级的班级信息所有学生的信息

编写GradeMapper.xml并使用collection标签解决,获得完整的Grade pojo对象

<?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="Mapper.GradeMapper">
    <!-- 当数据库列名和pojo的属性名相同是resultMap可以不写-->
   <resultMap id="GradeResult" type="Domin.Grade">
       <id column="id" property="id"/>
       <result column="g_name" property="name"/>
       <!-- 映射订单明细信息
      property:要将关联信息映射到Grade的哪个属性中
      ofType:集合中pojo的类型   最终填充到哪个pojo
      -->
        <collection property="students" ofType="Domin.Student">
            <id property="id" column="s_id"/>
            <result property="name" column="s_name"/>
        </collection>
    </resultMap>

    <select id="findGradeAndStudentsByName" resultMap="GradeResult" parameterType="string">
        select g.id,g.g_name,s.s_id,s.s_name from student s,grade g where s.gradeId= g.id and g.g_name=#{name}
    </select>
</mapper>

**注意:*此处有个坑,如果grade和student表的id和name列的列名完全相同的话,使用select 或者select g.id,g.name,s.id,s.name 无法将数据填充到pojo中,因此建表的时候,最好,将表中的列名用不同的列名命名加以区分。

4.编写Mapper接口

针对问题二编写Mapper接口

public interface GradeMapper {
    public Grade findGradeAndStudentsByName(String name);
}

5.测试


    public static void main(String[] args) {
      GradeMapper gradeMapper= MybatisUtil.getSqlSession().getMapper(Mapper.GradeMapper.class);
    Grade grade=gradeMapper.findGradeAndStudentsByName("实验班");
        System.out.println("班级信息:");
        System.out.println(grade.getId());
        System.out.println(grade.getName());
        System.out.println("班级所有学生:");

        for (Student student : grade.getStudents()){
            System.out.println(student.getId()+"-----"+student.getName());

        }
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hC82ot3b-1607520885489)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201111231711659.png)]

在resultMap标签中可以使用extends继承一个包含collection或者association标签的resultMap,同时在自己的标签中也编写一个collection这样就可以实现,多个关联数据的查询,填充,当然应该也可以写多个collection在resultMap标签中

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ecr2WueD-1607520885491)(C:\Users\hello\AppData\Roaming\Typora\typora-user-images\image-20201111232134130.png)]

多对多

  • 包含中间表
  • 查询陈伟斌选择的课程
  • 查询java课程被哪些学生选择
  • 建立一个student_course的中间表

1.创建表


create table students(
    sid int(5) primary key,
    sname varchar(10)
);

create table courses(
    cid int(5) primary key,
    cname varchar(10)
);

create table student_course(
    msid int(5),
    mcid int(5),
    primary key(msid,mcid)
);

2.创建pojo

public class Course {
    private Integer id;
    private String name;
    private List<Student> studentList = new ArrayList<Student>();//关联属性
    ...
}
public class Student {
    private Integer id;
    private String name;
    private List<Course> courseList = new ArrayList<Course>();//关联属性}

3.编写映射文件

问题1:查询陈伟斌选择的课程

因为是最终得到课程信息,所以在课程的CourseMapper.xml编写sql如下

<mapper namespace="courseNamespace">
    
    <resultMap type="Domin.Course" id="courResult">
        <id property="id" column="cid"/>
        <result property="name" column="cname"/>
    </resultMap>    
      
    <!-- 查询陈伟斌选学了哪些课程 -->
    <select id="findAllByName" parameterType="string" resultMap="courseMap">
        select c.cid,c.cname
        from students s inner join student_course m
        on s.sid = m.msid
        inner join courses c
        on m.mcid = c.cid
        and s.sname = #{name}
    </select>
    
</mapper>

问题2:查询java课程被哪些学生选择

因为是最终得到学生信息,所以在课程的StudenteMapper.xml编写sql如下

<mapper namespace="studentNamespace">
    
    <resultMap type="Domin.Student" id="studentResult">
        <id property="id" column="sid"/>
        <result property="name" column="sname"/>
    </resultMap>    

    
    <select id="findAllByCourseName" parameterType="string" resultMap="studentMap">
        select s.sname
        from students s inner join student_course m
        on s.sid = m.msid 
        inner join courses c
        on m.mcid = c.cid
        and c.cname = #{name}
    </select>
    
</mapper>


4.编写Mapper接口

省略,直接通过sqlSession.selectList(“命名空间.sql的id”,参数) 来测试

5.测试

 sqlSession = MybatisUtil.getSqlSession();
 List<Course> courseList =sqlSession.selectList("courseNamespace.findAllByName","陈伟斌");
for(Course c : courseList){
            System.out.print(c.getName()+" ");
=================================================================
 sqlSession = MybatisUtil.getSqlSession();
 List<Student> studentList= sqlSession.selectList("studentNamespace.findAllByCourseName","java课程"); 
       for(Student s : studentList){
            System.out.print(s.getName()+" ");
        }  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值