欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

mybatis的一对多双向关联映射

程序员文章站 2022-04-22 22:21:46
...

这里我们一对多中的一为班级,多为学生,一个班级有多个学生,而一个学生只能属于一个班级,采用mapper动态代理方式实现。

我们主要有以下几个文件:Student.java(学生类),Grade.java(班级类),StudentMapper.xml(学生类的映射文件),GradeMapper.xml(班级类的映射文件),StudentMapper.java(StudentMapper.xml对应的接口),GradeMapper.java(GradeMapper.xml对应的接口),测试类Test01.java,获得sqlSession类Access.java。pojo类对应的两个数据库表,Mybatis的核心配置文件SqlMapConfig,xml。

这是我的目录结构。

mybatis的一对多双向关联映射

Student.java

package com.liukun.po;

public class Student {
	private Integer studentId;
	private String studentName;
	private Grade studentGrade;//多的一方保存为一的一方的单个对象
	
	public Student(){
		
	}

	public Integer getStudentId() {
		return studentId;
	}

	public void setStudentId(Integer studentId) {
		this.studentId = studentId;
	}

	public String getStudentName() {
		return studentName;
	}

	public void setStudentName(String studentName) {
		this.studentName = studentName;
	}

	public Grade getStudentGrade() {
		return studentGrade;
	}

	public void setStudentGrade(Grade studentGrade) {
		this.studentGrade = studentGrade;
	}
}

Grade.java

package com.liukun.po;

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

public class Grade {
	
	private Integer gradeId;
	private String gradeName;
	//一的一方保存为多的一方的集合
	private List<Student> studentIdList = new ArrayList<Student>();
	
	public Grade(){
		
	}

	public Integer getGradeId() {
		return gradeId;
	}

	public void setGradeId(Integer gradeId) {
		this.gradeId = gradeId;
	}

	public String getGradeName() {
		return gradeName;
	}

	public void setGradeName(String gradeName) {
		this.gradeName = gradeName;
	}

	public List<Student> getStudentIdList() {
		return studentIdList;
	}

	public void setStudentIdList(List<Student> studentIdList) {
		this.studentIdList = studentIdList;
	}
	

}

StudentMapper.xml

<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!-- 与自己相对应的mapper接口绑定(映射) -->
<mapper namespace="com.liukun.mapper.StudentMapper">
	
	<!-- 
		type:返回的类型
		id:和下面的resultMap对应
	 -->
	<resultMap type="student" id="result">
		<!-- 
			id:主键(唯一性)
			column:列的名字,与你下面的sql语句查询结果的列名(你写的而不是数据库的列名,如果你下面为列定义别名,这里也要别名)相对应
			property:你所定义的pojo类(Student或Grade)的getxxx()方法去掉get,首字母小写的属性
		 -->
		<id column="studentId" property="studentId"/>
		<result column="studentName" property="studentName"/>
		<!-- 
			单一映射用 association
			javaType:属性对应的java类型
		-->
		<association property="studentGrade" javaType="Grade">
			<id column="gradeId" property="gradeId"/>
			<result column="gradeName" property="gradeName"/>		
		</association>
	</resultMap>
	
	<!-- 
		id:定义一个唯一标识符,(StudentMapper.java中的方法必须与id名字一样)
		resultMap:定义结果的映射(和上面的resultMap相对应)
	 -->
	<select id="findStudent" resultMap="result">
		select s.studentId, s.studentName, g.gradeId, g.gradeName from student s, grade g where s.grade_id = g.gradeId
	</select>


</mapper>

GradeMapper.xml

<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liukun.mapper.GradeMapper">

	<resultMap type="Grade" id="result">
		<id column="gradeId" property="gradeId"/>
		<result column="gradeName" property="gradeName"/>
		<!-- 
			集合用collection 
			ofType:集合的类型(泛型类型)	
		-->
		<collection property="studentIdList" ofType="Student">
			<id column="studentId" property="studentId"/>
			<result column="studentName" property="studentName"/>
		</collection>
	
	</resultMap>
	
	<select id="findList" resultMap="result">
		select s.studentId, s.studentName, g.gradeId, g.gradeName from student s, grade g where s.grade_id = g.gradeId	
	</select>


</mapper>

StudentMapper.java

package com.liukun.mapper;

import java.io.IOException;
import java.util.List;

import com.liukun.po.Student;

public interface StudentMapper {
	
	
	public List<Student> findStudent() throws IOException;

}

GradeMapper.java

package com.liukun.mapper;

import java.io.IOException;
import java.util.List;

import com.liukun.po.Grade;
import com.liukun.po.Student;

public interface GradeMapper {

	public List<Grade> findList() throws IOException;
}

Access.java

package com.liukun.access;

import java.io.IOException;
import java.io.Reader;

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 Access {
	public static SqlSession getSqlSession() throws IOException{
		//通过配置文件获取数据库连接信息
		Reader reader =  Resources.getResourceAsReader("SqlMapConfig.xml");
		//通过配置信息构建一个SqlSessionFactory
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		//通过sqlSessionFactory打开一个数据库会话
		SqlSession sqlSession =  sqlSessionFactory.openSession();
		return sqlSession;		
	}

}

Test01.java

package com.liukun.test;

import java.io.IOException;
import java.util.List;

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

import com.liukun.access.Access;
import com.liukun.mapper.GradeMapper;
import com.liukun.mapper.StudentMapper;
import com.liukun.po.Grade;
import com.liukun.po.Student;
public class Test01{
	
	//通过班级找学生(多对一)
	@Test //单元测试
	public void fun() throws IOException{
		SqlSession sqlSession =  Access.getSqlSession();
		GradeMapper gm = sqlSession.getMapper(GradeMapper.class);
		List<Grade> list =  gm.findList();
		for (Grade s : list) {
			System.out.print(s.getGradeId()+" "+s.getGradeName()+":");
			for (Student g : s.getStudentIdList()) {
				System.out.print(g.getStudentId()+" "+g.getStudentName()+" ");
			}
			System.out.println();
		}
		sqlSession.close();
	}
	//通过学生找班级(一对多)
	@Test  //单元测试
	public void fun1() throws IOException{
		SqlSession sqlSession =  Access.getSqlSession();
		StudentMapper sm = sqlSession.getMapper(StudentMapper.class);		
		List<Student> list = sm.findStudent();	
		for (Student s : list) {
				System.out.println(s.getStudentId()+" "+s.getStudentName()+" "+s.getStudentGrade().getGradeId()+" "+s.getStudentGrade().getGradeName());
		}
		sqlSession.close();
	}
}


SqlMapConfig.xml(全局配置文件)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">


<configuration>
	
	<!-- 使得整个包下的类可以直接通过类名访问,大小写不敏感 -->
	<typeAliases>
		<package name="com.liukun.po"/>
	</typeAliases>
	<!-- 连接数据相关的配置 -->
 	<environments default="development">
    	<environment id="development">
      		<transactionManager type="JDBC">
       			<property name="" value=""/>
      		</transactionManager>
      		<dataSource type="UNPOOLED">
        		<property name="driver" value="com.mysql.jdbc.Driver"/>
        		<property name="url" value="jdbc:mysql://127.0.0.1:3306/t5"/>
        		<property name="username" value="root"/>
        		<property name="password" value="123"/>
      		</dataSource>
    	</environment>
  	</environments>

	<!-- 使得整个包下的.xml文件都可以找到 -->
	<mappers>
		<package name="com.liukun.mapper"/>	
		
		<!-- 否则要这样写,一个一个加载
			<mapper resource="com.liukun.mapper.StudentMapper.xml"/>
			<mapper resource="com.liukun.mapper.GradeMapper.xml"/> 
		-->				
	</mappers>
</configuration>

Student.java对应的表student

create table student(
studentId int(11) primary key,
studentName varchar(20) not null,
grade_id int(11) not null,
constraint student_fk_grade FOREIGN KEY (grade_id) REFERENCES grade (gradeId) //为student表添加了一个外键关联grade表的主键

Grade.java对应的表grdae

create table grade(
gradeId int(11) primary key,
gradeName varchar(20) not null
);

整个对于mybatis的一对多双向关联mapper动态代理开发就完成了,上面的StudentMapper.java和GradeMapper.java与其相对应的.xml文件要放在同一个文件夹中(包),接口中的方法要与相对应的mapper,xml中的select的id一样,返回值,参数(这里没用到参数)都一样。