`

ibatis2中的一对多和一对一映射

阅读更多

直接看代码。部分细节,请自行参透,你懂的。。

这里先来演示ibatis2.x中的一对多映射

首先是位于CLASSPATH中的ibatis2的全局配置文件SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMapConfig      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
	<settings useStatementNamespaces="true"/>
	<transactionManager type="JDBC">
		<dataSource type="SIMPLE">
			<property name="JDBC.Driver" value="oracle.jdbc.OracleDriver" />
			<property name="JDBC.ConnectionURL" value="jdbc:oracle:thin:@127.0.0.1:1521:jadyer" />
			<property name="JDBC.Username" value="scott" />
			<property name="JDBC.Password" value="jadyer" />
		</dataSource>
	</transactionManager>
	<sqlMap resource="com/jadyer/model/User.xml" />
	<sqlMap resource="com/jadyer/model/People.xml" />
</sqlMapConfig>

然后是演示一对多映射用到的两个实体类

package com.jadyer.model;
import java.util.List;
public class User {
	private Integer id;              //主键
	private String name;             //姓名
	private String job;              //工作
	private List<Address> addresses; //地址。一个人可能有很多的居住地
	/*--它们的setter和getter略--*/
}

/**
 * 上面是演示一对多用到的User实体类
 * 下面是演示一对多用到的Address实体类
 */

package com.jadyer.model;
public class Address {
	private Integer id;       //主键
	private Integer userId;   //对应User类的id
	private String address;   //地址
	private Integer postcode; //邮编
	/*--它们的setter和getter略--*/
}

接着是演示一对多映射用到的实体类映射文件User.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="User">
	<typeAlias alias="user" type="com.jadyer.model.User"/>
	<typeAlias alias="address" type="com.jadyer.model.Address"/>
	
	<resultMap id="get-user-result" class="user">
		<result property="id" column="ID"/>
		<result property="name" column="NAME"/>
		<result property="job" column="JOB"/>
		<result property="addresses" column="id" select="User.getAddressesByUserId"/> 
	</resultMap>
	
	<select id="getAddressesByUserId" parameterClass="int" resultClass="address">
		select address, postcode from t_address where user_id = #userId#
	</select>
	<select id="getUsers" resultMap="get-user-result">
		select id, name, job from t_user
	</select>
	<select id="getUserByName" parameterClass="java.lang.String" resultMap="get-user-result">
		select id, name, job from t_user where name = #name#
	</select>
</sqlMap>
<!--
实际开发中,常常遇到关联数据的情况
如User对象拥有若干Address对象,每个Address对象描述了对应User的一个联系地址
此时通常做法是,通过Statement读取用户数据,再手工调用另一个Statement根据用户ID返回对应Address信息
不过这样未免过于繁琐。于是ibatis提供了Statement嵌套支持,通过Statement嵌套,即可实现关联数据的操作
【这里通过在<resultMap/>中定义嵌套查询getAddressByUserId,实现了关联数据的读取】
实际上,这种方式类似于前面所说的通过两条单独的Statement进行关联数据的读取
只是将关联关系在配置中加以描述,由ibatis自动完成关联数据的读取。但,这时就有一个潜在的性能问题,即N+1
所以,在实际的系统设计中,应根据具体情况,采用一些规避手段,如:使用存储过程集中处理大批量关联数据
从而避免因为N+1的问题而导致产品品质上的缺陷
-->

然后是使用了JUnit4.x的单元测试类IbatisOneToManyTest.java

package com.jadyer.test;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.jadyer.model.Address;
import com.jadyer.model.User;

public class IbatisOneToManyTest {
	private static SqlMapClient sqlMapClient = null;
	
	/**
	 * 读取ibatis配置文件,连接数据库,并创建SqlMapClient
	 */
	@BeforeClass
	public static void readConfig() throws IOException {
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
		reader.close();
	}
	
	/**
	 * 获取所有用户的,包含了地址的,详细资料
	 */
	@Test
	public void getUsers() throws SQLException {
		List<User> userList = sqlMapClient.queryForList("User.getUsers");
		for(User user : userList){
			System.out.println("==>" + user.getName() + ":" + user.getJob());
			for(Address address : user.getAddresses()){
				System.out.println(address.getAddress() + "---" +address.getPostcode());
			}
		}
	}
	
	/**
	 * 获取指定用户的,包含了地址的,详细资料
	 */
	@Test
	public void getUserByName() throws SQLException {
		User user = (User)sqlMapClient.queryForObject("User.getUserByName", "王怜花");
		System.out.println("==>" + user.getName() + ":" + user.getJob());
		for(Address address : user.getAddresses()){
			System.out.println(address.getAddress() + "---" +address.getPostcode());
		}
	}
}

最后是演示一对多映射用到的数据库脚本文件

-- Oracle 11g

-- Create table
create table t_user(
  id    number,
  name  varchar2(10),
  job varchar2(20)
);

create table t_address(
  id    number,
  user_id number,
  address varchar2(20),
  postcode number
);

-- Add data
insert into t_user values(1, '沈浪', '侠客');
insert into t_user values(2, '王怜花', '军师');
insert into t_user values(3, '金不换', '财务');
insert into t_address values(1, 1, '来无影去无踪', 999999);
insert into t_address values(2, 1, '赏金侠客天君', 888888);
insert into t_address values(3, 1, '万剑山庄之主', 777777);
insert into t_address values(4, 2, '鬼魅狐影奸狭', 666666);
insert into t_address values(5, 2, '易容之术无敌', 555555);
insert into t_address values(6, 3, '鬼迷心窍恋财', 444444);
insert into t_address values(7, 3, '厚颜无耻杯具', 333333);

下面演示ibatis2.x中的一对一映射

首先是演示一对一映射用到的实体类People.java

package com.jadyer.model;

public class People {
	private Integer id;  //主键
	private String name; //姓名
	private String job;  //工作
	private String sex;  //性别。唯一
	private String card; //身份证编号。唯一
	/*--它们的setter和getter略--*/
}

然后是演示一对一映射用到的实体类映射文件People.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap      
    PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"      
    "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="People">
	<typeAlias alias="people" type="com.jadyer.model.People"/>
	
	<resultMap id="get-people-result" class="people">
		<result property="id" column="ID"/>
		<result property="name" column="NAME"/>
		<result property="job" column="JOB"/>
		<result property="sex" column="SEX"/>
		<result property="card" column="CARD"/>
	</resultMap>
	
	<select id="getPeoples" resultMap="get-people-result">
		select * from t_people, t_identity where t_people.id = t_identity.people_id
	</select>
	<select id="getPeopleByName" parameterClass="java.lang.String" resultMap="get-people-result">
		select * from t_people, t_identity where name = #name# and t_people.id = t_identity.people_id
	</select>
</sqlMap>
<!--
一对一关联
一对一关联是一对多关联的一种特例。这种情况下,如果一对多的编写方式,将导致1+1条SQL的执行
此时,我们可以采用一次Select两张表的方式,避免这样的性能开销
这时,还应保证People类中包含sex和card两个属性。且此时一个People类就够了,并不需要Identity类
-->

接着是使用了JUnit4.x的单元测试类IbatisOneToOneTest.java

package com.jadyer.test;

import java.io.IOException;
import java.io.Reader;
import java.sql.SQLException;
import java.util.List;

import org.junit.BeforeClass;
import org.junit.Test;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import com.jadyer.model.People;

public class IbatisOneToOneTest {
	private static SqlMapClient sqlMapClient = null;
	
	/**
	 * 读取ibatis配置文件,连接数据库,并创建SqlMapClient
	 */
	@BeforeClass
	public static void readConfig() throws IOException {
		Reader reader = Resources.getResourceAsReader("SqlMapConfig.xml");
		sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
		reader.close();
	}
	
	/**
	 * 获取所有用户的,包含了身份证的,详细资料
	 */
	@Test
	public void getPeoples() throws SQLException {
		List<People> peopleList = sqlMapClient.queryForList("People.getPeoples");
		for(People people : peopleList){
			System.out.println("==>" + people.getName() + ":" + people.getCard());
		}
	}
	
	/**
	 * 获取指定用户的,包含了身份证的,详细资料
	 */
	@Test
	public void getPeopleByName() throws SQLException {
		People people = (People)sqlMapClient.queryForObject("People.getPeopleByName", "陈文锦");
		System.out.println("==>" + people.getName() + ":" + people.getCard());
	}
}

最后是演示一对一映射用到的数据库脚本文件

-- Oracle 11g

-- Create table
create table t_people(
  id    number,
  name  varchar2(8),
  job varchar2(20)
);

create table t_identity(
  id    number,
  people_id number,
  sex varchar2(2),
  card number
);

-- Add data
insert into t_people values(1, '张起灵', '武器');
insert into t_people values(2, '陈文锦', '领队');
insert into t_people values(3, '吴三省', '插班');
insert into t_identity values(1, 1, '男', 777777777777);
insert into t_identity values(2, 2, '女', 666666666666);
insert into t_identity values(3, 3, '男', 555555555555);


分享到:
评论

相关推荐

    ibatis 一对多关系映射

    ibatis 一对多关系映射 ibatis 一对多关系映射ibatis 一对多关系映射

    ibatis 一对多 多对多完整映射

    NULL 博文链接:https://self4j.iteye.com/blog/906319

    Mybatis/ibatiS多表映射 一对一 一对多 extjs前台取值 详细讲解

    一、mybatis/ibatiS xml配置文件中 以 学生班级和班主任 为例 讲解多表映射 其中班级和学生为 一对多 班主任和班级为 一对一 二、extjs 前台写model 及 grid 简易编码 内有详细讲解

    iBatis2学习笔记

    6.iBatis2学习笔记:一对多映射(双向).doc 7.iBatis2学习笔记:多对多映射(双向) .doc 8.iBatis2学习笔记:总结与思考.doc 9.iBatis2实体状态图解.doc 10.iBatis insert操作陷阱.doc 每章都有小例子。 呵呵,希望...

    ibatis2.x 详细介绍

    一对多关联............................................................................................ 26 一对一关联......................................................................................

    iBATIS实战

    书中既详实地介绍了iBATIS的设计理念和基础知识,也讨论了动态SQL、高速缓存、DAD框架等高级主题,还讲解了iBATIS在实际开发中的应用。书的最后给出了一个设计优雅、层次清晰的示例程序JGameStore,该示例涵盖全书的...

    ibatis开发指南_夏昕

    一对多关联............................................................................................26 一对一关联........................................................................................

    ibatis开发指南中文版

    一对多关联............................................................................................26 一对一关联........................................................................................

    持久层框架ibatis学习笔记

    能,我没有去深思,学了iBatis 对以后学习其它持久层框架是有很多好吃的。希望看到我的 这篇学习笔记的同学们也一起学习iBatis。 这篇iBatis 学习笔记是跟着传智播客的视频学习整理的,理解上难免有些错误,请以视频...

    ibatis 开发指南(pdf)

    26 一对多关联............................................................................................ 26 一对一关联...........................................................................

    ibatisORM增删查改及关系映射

    此为Ibatis样例代码,包含Ibatis的增删查改及一对多,多对多关系样例

    MyBatis学习资料

    1. 背景 Ibatis 为Apache旗下的产品,随着开发团队转投Google Code旗下,ibatis3.x正式更名为Mybatis . 2. 是什么 MyBatis是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架 . ...一对多 多对一 多对多

    ibatis入门教程

    一对多关联............................................................................................ 26 一对一关联......................................................................................

    流风通用管理框架源码

    iBATIS作为一种独特的Data Mapper,使用SQL映射的方式将对象持久化至关系型数据库。简单的理解就是它将我们在数据访问层实现的C#逻辑代码,变为通过关系数据库与对象的映射,将SQL逻辑放到外部的XML配置文件中,以...

    MyBatis数据持久层框架 v3.5.13

    MyBatis的前身就是iBatis。是一个数据持久层(ORM)框架。 MyBatis SQL映射器框架使将关系数据库与面向对象的应用程序结合使用变得更加容易...1、SQL语句的编写工作量较大,尤其当字段多、关联表多时,对开发人员编写SQ

    流风通用管理框架(源码+数据库)

    iBATIS作为一种独特的Data Mapper,使用SQL映射的方式将对象持久化至关系型数据库。简单的理解就是它将我们在数据访问层实现的C#逻辑代码,变为通过关系数据库与对象的映射,将SQL逻辑放到外部的XML配置文件中,以...

    mybatis_day01.docx

    mybatis是一种持久层框架,也属于ORM映射。前身是ibatis。 相比于hibernatehibernate为全自动化,配置文件书写之后不需要书写sql语句,但是欠缺灵活,很多时候需要优化; mybatis为半自动化,需要自己书写sql语句,...

    通用管理框架源码下载 

    用户管理: 管理系统用户信息,并可以定义用户所属的角色,部门,岗位,一个用户可以选择多个角色 部门管理: 管理系统部门信息 岗位管理: 管理系统岗位 在线用户: 查看当前登录系统的用户 参考界面: 代码生成器: ...

    IBatisNet.DataMapper 之简单三层

    iBATIS允许你用多种方式建立从对象到数据库的映射关系 MySpace已应用 4.使用于任何类型的关系数据库: 应用数据库 企业数据库 私有数据库 遗留数据库 简单性 性能 明确分工 可移植性:Java、.Net或者其他 ...

Global site tag (gtag.js) - Google Analytics