Mybatis [one-to-many, many-to-one, many-to-many] knowledge points

Mybatis [multi-table connection]

When we are learning Hibernate, if the table involves two, then we use the <set>.. <many-to-one>and other tags in the mapping file to associate its mapping properties... So how do we do it in Mybatis? ? ?

Let's review our SQL99 syntax first:


一)内连接(等值连接):查询客户姓名,订单编号,订单价格
    ---------------------------------------------------
    select c.name,o.isbn,o.price
    from customers c inner join orders o
    where c.id = o.customers_id;
    ---------------------------------------------------
    select c.name,o.isbn,o.price
    from customers c join orders o
    where c.id = o.customers_id; 
    ---------------------------------------------------
    select c.name,o.isbn,o.price
    from customers c,orders o
    where c.id = o.customers_id;
    ---------------------------------------------------
    select c.name,o.isbn,o.price
    from customers c join orders o
    on c.id = o.customers_id;
    ---------------------------------------------------
    注意:内连接(等值连接)只能查询出多张表中,连接字段相同的记录




二)外连接:按客户分组,查询每个客户的姓名和订单数
    ---------------------------------------------------
    左外连接:
    select c.name,count(o.isbn)
    from  customers c left outer join orders o
    on c.id = o.customers_id
    group by c.name; 
    ---------------------------------------------------
    右外连接:
    select c.name,count(o.isbn)
    from  orders o right outer join customers c   
    on c.id = o.customers_id
    group by c.name; 
    ---------------------------------------------------
    注意:外连接既能查询出多张表中,连接字段相同的记录;又能根据一方,将另一方不符合相同记录强行查询出来




三)自连接:求出AA的老板是EE
    ---------------------------------------------------
    内自连接:
    select users.ename,boss.ename
    from emps users inner join emps boss 
    on users.mgr = boss.empno;
    ---------------------------------------------------
    外自连接:
    select users.ename,boss.ename
    from emps users left outer join emps boss 
    on users.mgr = boss.empno;
    ---------------------------------------------------
    注意:自连接是将一张表,通过别名的方式,看作多张表后,再进行连接。
	  这时的连接即可以采用内连接,又可以采用外连接

Since our Mybatis is not fully automated like Hibernate, we do not have tags such as <set>.. <many-to-one>and so on. We still use handwritten SQL statements to connect our associated properties...

one-on-one

need:

  • Student and ID

 

write picture description here

 

Design table:



--mysql

create table cards(
	cid int(5) primary key,
	cnum varchar(10)
);

create table students(
	sid int(5) primary key,
	sname varchar(10),
	scid int(5),
	constraint scid_fk foreign key(scid) references cards(cid)
);

insert into cards(cid,cnum) values(1,'111');
insert into students(sid,sname,scid) values(1,'哈哈',1);

select * from cards;
select * from students;


entity

/**
 * 身份证(单方)
 * @author AdminTC
 */
public class Card {
	private Integer id;
	private String num;
	public Card(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
}


/**
 * 学生(单方)
 * @author AdminTC
 */
public class Student {
	private Integer id;
	private String name;
	private Card card;//关联属性
	public Student(){}
	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 Card getCard() {
		return card;
	}
	public void setCard(Card card) {
		this.card = card;
	}
}

map file

Since we have two entities, we will have two mapping files

Student Mapping File


<?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="studentNamespace">
	
	<resultMap type="zhongfucheng2.Student" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>
	</resultMap>
</mapper>

Card mapping file



<?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="cardNamespace">
	
	<resultMap type="zhongfucheng2.Card" id="cardMap">
		<id property="id" column="cid"/>
		<result property="num" column="cnum"/>
	</resultMap>	
	
</mapper>

DAO layers

Now I want to query the student's information and ID card information based on the student's number !

Since the query focuses on querying students' information, we write SQL statements in the students' mapping files

According to the requirements, the SQL statement we wrote is like this.



select * from zhongfucheng.students s,zhongfucheng.cards c where c.cid = s.scid and sid=1;

Let me take a look at the query results:

 

write picture description here

 

In our entity and mapping table, the Student entity is not associated with other fields, but only writes its own attributes .


	<resultMap type="zhongfucheng2.Student" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>
	</resultMap>

Obviously, our Student cannot encapsulate the returned result, so we need to associate the associated properties!


	<resultMap type="zhongfucheng2.Student" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>

		<!--
			property写的是在Student实体中写关联字段的属性变量名称
			resultMap写的是映射文件中的命名空间.id
		-->
		<association property="card" resultMap="cardNamespace.cardMap"/>
	</resultMap>

After we associate, the Student entity can encapsulate the returned results


	<resultMap type="zhongfucheng2.Student" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>

		<!--
			property写的是在Student实体中写关联字段的属性变量名称
			resultMap写的是映射文件中的命名空间.id
		-->
		<association property="card" resultMap="cardNamespace.cardMap"/>
	</resultMap>

	<select id="findById" parameterType="int" resultMap="studentMap">
		select * from zhongfucheng.students s,zhongfucheng.cards c where c.cid = s.scid and sid=#{id};
	</select>

Query the student information with number 1 [including ID number]



    public Student findById(int id) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{

            return sqlSession.selectOne("studentNamespace.findById", id);

          /*  sqlSession.commit();*/
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }

    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        Student student = studentDao.findById(1);

        System.out.println(student.getId() + "----" + student.getName() + "----" + student.getCard().getNum());

    }

 

write picture description here

 

one-to-many

need:

  • There are multiple students in a class, query the student information of the java subject

 

write picture description here

 

Design database tables



create table grades(
  gid int(5) primary key,
  gname varchar(10)
);

create table students(
  sid int(5) primary key,
  sname varchar(10),
  sgid int(5),
  constraint sgid_fk foreign key(sgid) references grades(gid)
);

insert into grades(gid,gname) values(1,'java');

insert into students(sid,sname,sgid) values(1,'哈哈',1);
insert into students(sid,sname,sgid) values(2,'呵呵',1);


select * from grades;
select * from students;


entity


package zhongfucheng2;

import java.util.ArrayList;
import java.util.List;

/**
 * 学科(单方)
 * @author AdminTC
 */
public class Grade {
	private Integer id;
	private String name;
	private List<Student> studentList = new ArrayList<Student>();//关联属性
	public Grade(){}
	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 List<Student> getStudentList() {
		return studentList;
	}
	public void setStudentList(List<Student> studentList) {
		this.studentList = studentList;
	}
}




package zhongfucheng2;

/**
 * 学生(多方)
 * @author AdminTC
 */
public class Student {
	private Integer id;
	private String name;
	private Grade grade;//关联属性
	public Student(){}
	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 Grade getGrade() {
		return grade;
	}
	public void setGrade(Grade grade) {
		this.grade = grade;
	}
}

Mapping file SQL statements




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


	<!--查询选修的java学科有多少位学生-->

	<!--由于我们只要查询学生的名字,而我们的实体studentMap可以封装学生的名字,那么我们返回studentMap即可,并不需要再关联到学科表-->
	<select id="findByGrade" parameterType="string" resultMap="studentMap">

		select s.sname,s.sid from zhongfucheng.students s,zhongfucheng.grades g WHERE s.sgid=g.gid and g.gname=#{name};


	</select>

</mapper>



<?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="gradeNamespace">
	
	<resultMap type="zhongfucheng2.Grade" id="gradeMap">
		<id property="id" column="gid"/>
		<result property="name" column="gname"/>
	</resultMap>
</mapper>


DAO


public List<Student> findByGrade(String  grade) throws Exception {
        //得到连接对象
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        try{

            return sqlSession.selectList("studentNamespace.findByGrade", grade);
          /*  sqlSession.commit();*/
        }catch(Exception e){
            e.printStackTrace();
            sqlSession.rollback();
            throw e;
        }finally{
            MybatisUtil.closeSqlSession();
        }
    }

    public static void main(String[] args) throws Exception {
        StudentDao studentDao = new StudentDao();
        List<Student> student = studentDao.findByGrade("java");

        for (Student student1 : student) {
            System.out.println(student1.getName());
        }
    }

 

write picture description here

 

many-to-many

need:

  • students and courses

 

write picture description here

 

Database Table


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

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

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

insert into students(sid,sname) values(1,'哈哈');
insert into students(sid,sname) values(2,'呵呵');

insert into courses(cid,cname) values(1,'java');
insert into courses(cid,cname) values(2,'android');

insert into middles(msid,mcid) values(1,1);
insert into middles(msid,mcid) values(1,2);
insert into middles(msid,mcid) values(2,1);
insert into middles(msid,mcid) values(2,2);

select * from students;
select * from courses;
select * from middles;


entity

package cn.itcast.javaee.mybatis.many2many;

import java.util.ArrayList;
import java.util.List;

/**
 * 课程(多方)
 * @author AdminTC
 */
public class Course {
	private Integer id;
	private String name;
	private List<Student> studentList = new ArrayList<Student>();//关联属性
	public Course(){}
	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 List<Student> getStudentList() {
		return studentList;
	}
	public void setStudentList(List<Student> studentList) {
		this.studentList = studentList;
	}
}




package cn.itcast.javaee.mybatis.many2many;

import java.util.ArrayList;
import java.util.List;

/**
 * 学生(多方)
 * @author AdminTC
 */
public class Student {
	private Integer id;
	private String name;
	private List<Course> courseList = new ArrayList<Course>();//关联属性
	public Student(){}
	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 List<Course> getCourseList() {
		return courseList;
	}
	public void setCourseList(List<Course> courseList) {
		this.courseList = courseList;
	}
}

map file


<?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="courseNamespace">
	
	<resultMap type="cn.itcast.javaee.mybatis.many2many.Course" id="courseMap">
		<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 middles m
		on s.sid = m.msid
		inner join courses c
		on m.mcid = c.cid
		and s.sname = #{name}
	</select>
	
</mapper>




<?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="studentNamespace">
	
	<resultMap type="cn.itcast.javaee.mybatis.many2many.Student" id="studentMap">
		<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 middles m
		on s.sid = m.msid 
		inner join courses c
		on m.mcid = c.cid
		and c.cname = #{name}
	</select>
	
</mapper>



DAO



package cn.itcast.javaee.mybatis.many2many;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import cn.itcast.javaee.mybatis.util.MybatisUtil;

/**
 * 持久层
 * @author AdminTC
 */
public class StudentCourseDao {
	/**
	 * 查询哈哈选学了哪些课程
	 * @param name 表示学生的姓名
	 */
	public List<Course> findAllByName(String name) throws Exception{
		SqlSession sqlSession = null;
		try{
			sqlSession = MybatisUtil.getSqlSession();
			return sqlSession.selectList("courseNamespace.findAllByName",name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	/**
	 * 查询java课程有哪些学生选修
	 * @param name 表示学生的课程
	 */
	public List<Student> findAllByCourseName(String name) throws Exception{
		SqlSession sqlSession = null;
		try{
			sqlSession = MybatisUtil.getSqlSession();
			return sqlSession.selectList("studentNamespace.findAllByCourseName",name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	
	
	
	
	
	
	public static void main(String[] args) throws Exception{
		StudentCourseDao dao = new StudentCourseDao();
		List<Course> courseList = dao.findAllByName("哈哈");
		System.out.print("哈哈选学了" + courseList.size()+"个课程,分别是:");
		for(Course c : courseList){
			System.out.print(c.getName()+" ");
		}
		System.out.println("\n-----------------------------------------------------");
		List<Student> studentList = dao.findAllByCourseName("android");
		System.out.println("选修了android课程的学生有"+studentList.size()+"个,分别是:");
		for(Student s : studentList){
			System.out.print(s.getName()+" ");
		}
	}
}


Summarize

The multi-table connection of Mybatis is very simple. Since the SQL statements are all written by ourselves, if the data type we return is not encapsulated enough in the current entity, then we only need to associate the corresponding mapping attributes !

If there are any mistakes in the article, please correct me, and we can communicate with each other. Students who are accustomed to reading technical articles on WeChat and want to get more Java resources can follow WeChat public account: Java3y

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325247766&siteId=291194637