Mybatis一對一、一對多、多對多查詢。+MYSQL


場景:使用三張數據表:student學生表、teacher教師表、position職位表

一個學生可以有多為老師、一位老師可以有多個學生、但是一個老師只能有一個職位:教授、副教授、講師;但是一個職位可以有多個老師:例如教授可以多人

這里則產生了:

一對一關系,從老師角度:老師對職位一對一

一對多關系,從職位角度:職位對老師一對多

多對多關系:查找被教授教導的所有學生(首先職位對老師一對多,老師再對學生再對多、這里便有了一對多對多)

數據表:

老師表

CREATE TABLE `tb_teacher` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_no` varchar(20) DEFAULT NULL,
  `t_name` varchar(20) DEFAULT NULL,
  `position_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Data for the table `tb_teacher` */

insert  into `tb_teacher`(`id`,`t_no`,`t_name`,`position_id`) values
(1,'163314001','張文遠',1),
(2,'163314002','趙傳智',1),
(3,'163314003','風清揚',2),
(4,'163314004','王匯智',2),
(5,'163314005','汪思遠',3);

學生表

CREATE TABLE `tb_student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_stu_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

/*Data for the table `tb_student` */

insert  into `tb_student`(`id`,`t_stu_name`) values 

(1,'趙依'),

(2,'錢邇'),

(3,'張山'),

(4,'李石'),

(5,'王武'),

(6,'馬柳');

職位表

CREATE TABLE `tb_position` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_pos_name` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

/*Data for the table `tb_position` */

insert  into `tb_position`(`id`,`t_pos_name`) values 

(1,'教授'),

(2,'副教授'),

(3,'講師');

最后是教師學生關系表

CREATE TABLE `tb_stu_teach` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `t_stu_id` int(11) DEFAULT NULL,
  `t_teach_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=14 DEFAULT CHARSET=utf8;

/*Data for the table `tb_stu_teach` */

insert  into `tb_stu_teach`(`id`,`t_stu_id`,`t_teach_id`) values 

(1,1,1),

(2,1,2),

(3,1,3),

(4,2,2),

(5,2,3),

(6,2,4),

(7,3,3),

(8,3,4),

(9,3,5),

(10,4,4),

(11,4,5),

(12,4,1);

最后在eclipse中的目錄結構如下:

希望您明白sqlMapConfig該如何配置,以及jdbc.properties和log4j的作用。

貼出POJO中的三個實體(注意:以下的POJO都用了lombok來快速生成setter和getter等,lomok具體使用,請見此文):

Position.java

package com.pojo;

import java.io.Serializable;

import lombok.Data;

@Data
public class Position implements Serializable {
	private int id;
	private String name;
	
	private Teacher teacher;

}

Student.java

package com.pojo;

import java.io.Serializable;
import java.util.List;

import lombok.Data;

@Data
public class Student implements Serializable {
	private String id;
	private String name;
	
	private List<Teacher> list;
}

Teacher.java

package com.pojo;

import java.io.Serializable;
import java.util.List;

import lombok.Data;

@Data
public class Teacher implements Serializable {
	private int id;
	
	private String no;
	private String name;
	private List<Student> studentList;
	
	private Position pos;
}

注意:關系表不用以實體表示出來,表示外鍵關系的ID也不用寫在實體中(一般我們也不使用外鍵)

 

再貼另一個MybatisUtil.java工具類

package com.util;

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 MyBatisUtil {
	private static SqlSessionFactory sqlSessionFactory = null;
	
	static {
		String resource = "sqlMapConfig.xml";
		// 首先要加載核心配置文件:從classpath下開始找。
		InputStream in;
		try {
			in = Resources.getResourceAsStream(resource);
			
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
		} catch (IOException e) {
			throw new RuntimeException(e.getMessage());
		}	
	}
	
	public static SqlSession getSqlSession() {
		
		return sqlSessionFactory.openSession();
	}
	
	public static SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}
}

一對一:老師對職位

TeacherMapper.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.mapper.TeacherMapper">
	<resultMap type="Teacher" id="teacherPositionResultMap">
		<id property="id" column="id"/>
		<result property="no" column="t_no"/>
		<result property="name" column="t_name"/>
		<!-- association:配置的一對一屬性 -->
		<!-- property:名字
			 javaType:類型
		 -->
		<association property="pos" javaType="Position">
			<id property="id" column="id"/>
			<result property="name" column="t_pos_name"/>
		</association>
	</resultMap>
	
	<!-- 一對一關聯查詢,查詢老師及其對應的職位 -->
	<!-- 注意:id不能相同,當多個值傳入,比如包裝類的時候,我們才能夠用SQL片段的形式來做if判斷,單個值是不行的 -->
	<select id="queryTeacherPositionResultMapById" resultMap="teacherPositionResultMap" parameterType="Integer">
		SELECT *
		FROM tb_teacher t
		LEFT JOIN tb_position p
		ON t.position_id = p.id
		where t.id = #{id}
	</select>

	<select id="queryTeacherPositionResultMap" resultMap="teacherPositionResultMap">
		SELECT *
		FROM tb_teacher t
		LEFT JOIN tb_position p
		ON t.`position_id` = p.id
	</select> 
</mapper>

TeacherMapper.java接口

package com.mapper;

import java.util.List;

import com.pojo.Teacher;

public interface TeacherMapper {
	public List<Teacher> queryTeacherPositionResultMap();
	
	public Teacher queryTeacherPositionResultMapById(Integer id);
}

測試一對一:

package com.test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mapper.TeacherMapper;
import com.pojo.Teacher;
import com.util.MyBatisUtil;

public class TestOneToOne {
	@Test
	public void testOneToOne() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		System.err.println(sqlSession);
		
		TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
		
		List<Teacher> list = teacherMapper.queryTeacherPositionResultMap();
		
		System.out.println(list);
		
		Teacher teacher = teacherMapper.queryTeacherPositionResultMapById(1);
		System.out.println(teacher);
	}
}

 

一對多:職位對老師

PositionMapper.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.mapper.PositionMapper"> 
	<resultMap type="Position" id="positionTeacherResultMap">
		<id property="id" column="id"/>
		<result property="name" column="t_pos_name"/> <!-- t_name -->
		<!-- 
		property同association中的一樣是屬性名稱(javaBean中的);
		javaType也同association中的是類型,
		最后多了一個OfType,因為一對多,不像一對一是單個的!我們這里是List集合,list和List都可以。
		一對多其中是放的一個集合所以這個是集合的泛型的類型,這里我們的list中放的是Teacher:
		所以這里是Teacher。
		 -->
		<collection property="teacherList" javaType="List" ofType="Teacher" >
			<!-- 
				一對多出現的問題:
					當數據庫表中,主表的主鍵id和明細表的 ...
					當表中的字段名相同時怎么辦?多表聯查?
					
					注意:Mybatis中做多表聯查的時候,不管是
					一對一、一對多、一對多對多:多對多:
					都不能有字段重名的情況:不管是主鍵還是普通字段。
					一旦字段重名的話,就會造成數據少自動賦值,或者覆蓋,甚至重復賦值!
					規避和解決此類問題的方法:
						1.盡量不要表間重名,mybatis里處理起來很麻煩!id和普通字段都是。
						但是在表多的時候,很難不會出現字段重名的情況。主鍵id最容易重名!
						那么就要用以下的辦法了!
						
						2.在mybatis中寫原生SQL進行查詢的時候,查的字段盡可能的少,這
						也影響速率,強烈禁止使用*,用多少查多少!這樣也能及時發現字段重
						名的情況!
						
						3.最后如果真的需要查出重名的字段,並且修改數據庫字段名造成的更改
						過大,這里推薦的方式是給字段取別名,在寫resultMap映射的時候,其
						中的column屬性就填寫SQL語句中查出字段取的別名,這樣就能解決重復
						問題了!
			 -->
			<id property="id" column="t_id"/>
			<result property="no" column="t_no"/>
			<result property="name" column="t_name"/>	
		</collection>
	</resultMap>
	
	<select id="queryPositionTeacherResultMapById" resultMap="positionTeacherResultMap" 
		parameterType="Integer">
		<!-- 
		SELECT *
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		WHERE p.id = #{id}
		-->
		
		SELECT 
		p.*, 
		t.id t_id,
		t.t_name,
		t.t_no
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		WHERE p.id = #{id}
	</select>
	
	<select id="queryPositionTeacherResultMap" resultMap="positionTeacherResultMap" >
		<!-- 
		SELECT *
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		-->
		
		SELECT 
		p.*, 
		t.id t_id,
		t.t_name,
		t.t_no
		FROM tb_position p
		LEFT JOIN tb_teacher t
		ON p.id = t.position_id
		
	</select>
</mapper>

TeacherMapper.java接口

package com.mapper;

import java.util.List;

import com.pojo.Position;

public interface PositionMapper {
	public Position queryPositionTeacherResultMapById(Integer id);
	
	public List<Position> queryPositionTeacherResultMap();
}

測試一對多:

package com.test;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mapper.PositionMapper;
import com.pojo.Position;
import com.util.MyBatisUtil;

public class TestOneToMany {
	
	@Test
	public void testOneToMany() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		PositionMapper positionMapper = sqlSession.getMapper(PositionMapper.class);
		List<Position> list = positionMapper.queryPositionTeacherResultMap();
		
		System.out.println(list);
		
		Position pos = positionMapper.queryPositionTeacherResultMapById(1);
		
		System.out.println(pos);
	}
}

多對多:職位是教授的老師教授的所有學生(一對多對多:只要你願意可以一直對多下去...)

PositionMapper.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.mapper.PositionMapper"> 
	<resultMap type="Position" id="positionStudentResultMap">
		<!-- <id property="id" column="id"/> -->
		<result property="name" column="t_pos_name"/>
		<collection property="teacherList" javaType="List" ofType="Teacher" >
			<result property="name" column="t_name"/>	
			<collection property="studentList" javaType="List" ofType="Student">
				<result property="name" column="t_stu_name"/>
			</collection>
		</collection>
	</resultMap>
	
	<select id="selectPositionStudentByPosId" resultMap="positionStudentResultMap" parameterType="Integer">
		SELECT p.t_pos_name, t.t_name, s.t_stu_name
		FROM tb_position p
		INNER JOIN tb_teacher t ON p.id = t.position_id
		LEFT JOIN tb_stu_teach st ON st.t_teach_id = t.id
		LEFT JOIN tb_student s ON s.id = st.t_stu_id
		WHERE p.id = #{id}
	</select>
</mapper>

PositionMapper.java接口

package com.mapper;

import com.pojo.Position;

public interface PositionMapper {
	public Position selectPositionStudentByPosId(Integer id);
	
}

測試:

package com.test;

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.mapper.PositionMapper;
import com.pojo.Position;
import com.util.MyBatisUtil;

public class TestManyToMany {
	
	@Test
	public void testManyToMany() {
		SqlSession sqlSession = MyBatisUtil.getSqlSession();
		PositionMapper positionMapper = sqlSession.getMapper(PositionMapper.class);
		Position pos = positionMapper.selectPositionStudentByPosId(1);
		
		System.out.println(pos);
	}
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM