Mybatis一对多双向关联

在弄Mybatis的一对多关联的时候,不知道有没有遇到这样的问题,本来数据库中对应有多条数据,然而关联出来却只有一条数据,比如数据库中有个班级表和学生表,数据库中一个班级中对应了多个学生,但使用Mybatis做一对多关联的时候,查询出来的却只有一条。如果出现这样的问题,那么就是两张数据表中的主键重名了,导致在关联查询时分不清到底是那一张表了,因此有关联的数据表时,主键id不要重名,一对多关联实现如下:

数据表:

CREATE TABLE tab_class (
	c_id INT PRIMARY KEY AUTO_INCREMENT,
	c_name VARCHAR(50)
)

CREATE TABLE tab_student(
	s_id INT PRIMARY KEY AUTO_INCREMENT,
	s_name VARCHAR(50),
	c_id INT
)

实体类:

package com.tenghu.mybatis.model;

import java.util.List;

/**
 * 班级实体类
 * @author Arvin
 *
 */
public class Classes {
	private int cId;
	private String cName;
	private List<Student> studentList;
	public int getcId() {
		return cId;
	}
	public void setcId(int cId) {
		this.cId = cId;
	}
	public String getcName() {
		return cName;
	}
	public void setcName(String cName) {
		this.cName = cName;
	}
	public List<Student> getStudentList() {
		return studentList;
	}
	public void setStudentList(List<Student> studentList) {
		this.studentList = studentList;
	}

}
package com.tenghu.mybatis.model;
/**
 * 学生实体
 * @author Arvin
 *
 */
public class Student {
	private int sId;
	private String sName;
	private Classes classes;
	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 Classes getClasses() {
		return classes;
	}
	public void setClasses(Classes classes) {
		this.classes = classes;
	}

}

映射文件:

<?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.tenghu.mybatis.model.xml.ClassesMapper">
	<resultMap type="Classes" id="getClasses">
		<id property="cId" column="c_id"/>
		<result property="cName" column="c_name"/>

		<!-- 映射到一个集合  表示多的一方-->
		<collection property="studentList" ofType="Student">
			<id property="sId" column="s_id"/>
			<result property="sName" column="s_name"/>
		</collection>
	</resultMap>

	<!-- 根据班级id查询 -->
	<select id="queryClassesById" resultMap="getClasses" parameterType="int">
		SELECT * FROM tab_class c,tab_student s WHERE c.c_id=s.c_id AND c.c_id=#{id}
	</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="com.tenghu.mybatis.model.xml.StudentMapper">
	<resultMap type="Student" id="getStudent">
		<id property="sId" column="s_id"/>
		<result property="sName" column="s_name"/>

		<!-- 表示一的一方 -->
		<association property="classes" javaType="Classes">
			<id property="cId" column="c_id"/>
			<result property="cName" column="c_name"/>
		</association>
	</resultMap>

	<!-- 根据学生id查询 -->
	<select id="queryStudentById" parameterType="int" resultMap="getStudent">
		SELECT * FROM tab_class c,tab_student s WHERE c.c_id=s.c_id AND s.s_id=#{id}
	</select>
</mapper>

mybatis工具类:

package com.tenghu.mybatis.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

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

/**
 * Mybatis工具类
 * @author Arvin
 *
 */
public class MybatisUtil {
	private MybatisUtil(){}
	//声明SqlSessionFactory对象
	private static SqlSessionFactory sqlSessionFactory;

	static{
		//mybatis主配置文件
		String mybatisResource="mybatis-config.xml";
		//数据库属性文件
		String databaseProps="jdbc.properties";

		try {
			//获取mybatis住配置文件资源
			InputStream inputStream=Resources.getResourceAsStream(mybatisResource);
			//创建属性对象
			Properties props=new Properties();
			//加数据库属性配置文件资源
			props.load(Resources.getResourceAsStream(databaseProps));
			//创建SqlSession工厂对象
			sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream, props);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * 开启SqlSession,不自动提交
	 * @return
	 */
	public static SqlSession openSession(){
		return sqlSessionFactory.openSession();
	}

	/**
	 * 开启SqlSession,自动提交
	 * @param isAuto
	 * @return
	 */
	public static SqlSession openSessionAuto(){
		return sqlSessionFactory.openSession(true);
	}

	/**
	 * 关闭SqlSession对象
	 * @param sqlSession
	 */
	public static void closeSqlSession(SqlSession sqlSession){
		if(null!=sqlSession){
			sqlSession.close();
		}
	}
}

测试类:

package com.tenghu.mybatis.test;

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

import com.tenghu.mybatis.model.Student;
import com.tenghu.mybatis.util.MybatisUtil;
/**
 * 学生实体测试类
 * @author Arvin
 *
 */
public class StudentTest {
	private String namespace="com.tenghu.mybatis.model.xml.StudentMapper.";

	@Test
	public void testQueryStudentById(){
		//获取SqlSession
		SqlSession sqlSession=MybatisUtil.openSession();
		try {
			//查询
			Student student=sqlSession.selectOne(namespace+"queryStudentById", 1);
			//输出
			System.out.println(student.getsName());
			System.out.println(student.getClasses().getcName());
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭SqlSession
			MybatisUtil.closeSqlSession(sqlSession);
		}

	}
}
package com.tenghu.mybatis.test;

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

import com.tenghu.mybatis.model.Classes;
import com.tenghu.mybatis.model.Student;
import com.tenghu.mybatis.util.MybatisUtil;

/**
 * 班级测试类
 * @author Arvin
 *
 */
public class ClassesTest {
	private String namespace="com.tenghu.mybatis.model.xml.ClassesMapper.";

	@Test
	public void testQueryClassById(){
		//获取SqlSession
		SqlSession sqlSession=MybatisUtil.openSession();
		try {
			//查询
			Classes classes=sqlSession.selectOne(namespace+"queryClassesById",1);
			//输出
			System.out.println(classes.getcName());
			for (Student student : classes.getStudentList()) {
				System.out.println(student.getsName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			//关闭SqlSession
			MybatisUtil.closeSqlSession(sqlSession);
		}
	}
}

主键id相同的情况,这里就不测试了,如果没有遇到那样的情况,可以去试试。

时间: 2024-11-07 07:31:47

Mybatis一对多双向关联的相关文章

MyBatis一对多双向关联——MyBatis学习笔记之七

处理has-one关系需要用到association元素,而处理has many关系则需要用到collection元素.例如本例中,假设一 名教师可同时指导多名学生,下面就来介绍如何使用collection元素来实现这种映射,具体的任务是查询出教师及其指导的多个学生的信息(本示例源代 码下载页面:http://down.51cto.com/data/490947). 一.为Teacher实体增加相关属性 为教师实体增加指导学生集合的属性如下: private List<Student> sup

Hibernate 一对多双向关联Demo

以Classes[班级]和Student[学生]为例的Demo //Classes.java public class Classes implements Serializable { private long cid; private String cname; private String cdesc; private Set<Student> students; //get和set } //Student .java public class Student implements Se

hibernate一对多双向关联

14.一对多双向关联 1.在多的一方关联一的一方,多的一方直接维护了关系,所以多的一方没有inverse属性,多的一方在保存自己的时候直接保存了外键,效率高. 2.建立关系和保存对象,可以对应两个映射文件,保存多的一方自己对应自己的映射文件,建立关系可以使用一的一方表的inverse属性.这样发出update语句,效率低了.一对多,从多的一方建立关系,效率高. 例子 在student这边保存属性private Classess classess; 在student.hbm.xml文件在<clas

JPA开发总结&lt;三&gt;--一对多双向关联

学习JPA规范,也会涉及到关联关系的操作,对于使用注解方式的关联操作,这点就不如使用XML思路清晰明了,下面这是我总结的操作代码,注释说明很清楚,需要重点提的就是这里所有引得包都是sun提供的工具包,即javax.persistence.*,避免引包错误. 一对多关联从两点入手学习:JPA中的一对多双向关联与级联操作 JPA中的一对多延迟加载与关系维护 我们分析一对多,典型的例子就是订单和订单项的关系,一个订单有多个订单项,一个订单项指定一个订单id,详细看代码: 首先是Order类: /**

Hibernate中用注解配置一对多双向关联和多对一单向关联

Hibernate中用注解配置一对多双向关联和多对一单向关联 Hibernate提供了Hibernate Annotations扩展包,使用注解完成映射.在Hibernate3.3之前,需单独下载注解开发包 配置持久化类 配置关联关系 下面我们先从多对一单向关联关系讲起,多对一单向关联就是在多的一方植入一的一方的主键作为外键,下面我们先进行初始配置, 在配置的过程中我们会遇到一个问题  就是无论用load还是get都不会出现延迟加载,那么我们应该如何设置为要延迟加载,这样做的好处是可以在用的时候

grails一对多双向关联

前面分享了一些学习grails的心得,可是grails的知识还远不止这些,这次整理了一点有关grails一对多双向关联关系的知识.我认为这样的关联用的地方太多了,这次准备的样例是城市和区域的相关样例. 1.领域模型 class CityInfo { static hasMany = [area:AreaInfo] static fetchMode = [area:'lazy'] Integer id; String name; String code; static mapping = { ta

hibernate一对多双向关联中怎么配置list

假设有一个文档管理者类User,和一个文档类Archives.其中User和Archives是一对多双向关联关系 表现在类中如下(此处省略了属性的set和get方法) public class User implements Serializable { private static final long serialVersionUID = -7327980678002278494L; /** 定义id */ private Long id; /** 定义用户名*/ private Strin

15.Hibernate一对多双向关联映射+分页

1.创建如下数据库脚本 1 --创建用户信息表 2 --编号,用户名,密码,年龄,性别,昵称,手机,地址,管理员,图像地址 3 create table users 4 ( 5 id number(10) primary key, 6 username varchar2(20) not null, 7 password varchar2(40) not null, 8 age number(10) not null, 9 sex number(10) not null, 10 nickname

Hibernate!!多对一与一对多双向关联映射

双向的时候必须制定MappedBy这个属性!防止数据库生成的冗余. MappedBy属性是设置在多的一方,即在数据库中,一般都是将属性设置在多的一方. 如果没有,那么在生成数据库表的时候,就会有两个外键如图: onetomany的例子如下 加入MappedBy这个属性的 例子: 1 package com.hb.model; 2 3 import java.util.Collection; 4 import java.util.HashSet; 5 import java.util.Iterat