直接看代码。部分细节,请自行参透,你懂的。。
这里先来演示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的一对多关系映射可以避免频繁的数据库查询,提高系统性能。同时,它也能帮助开发者将关注点从底层数据库操作转移到业务逻辑上,使代码更加简洁、易于理解和维护。因此,对于任何使用...
总结来说,这个话题覆盖了Mybatis/iBatis中的多表映射,通过XML配置文件处理一对一和一对多关系,以及如何在ExtJS前端通过Model和Grid获取并展示这些数据。了解这些知识对于开发涉及多表交互的应用至关重要,能够...
ibatis配置多表关联(一对一、一对多、多对多
本文将深入探讨`iBatis` 中的一对多映射关系,以及如何通过源码理解和使用这个特性。 一对多映射是数据库关系模型中的常见概念,指的是一个父表(如部门表)可以对应多个子表(如员工表),每个部门可以有多个员工...
这篇博客可能深入探讨了iBATIS如何实现从数据库结果集到Java对象的映射,以及如何处理一对多、多对一和多对多的关系。 在数据库设计中,关系映射是至关重要的,因为它允许我们将复杂的数据库结构转换为易于管理和...
本文将深入探讨如何利用Ibatis实现一对多关系、批处理、事务管理和与Spring及Struts2的集成。 首先,让我们来看一下“一对多”关系。在数据库设计中,一对多关系很常见,比如一个用户可以有多个订单。在Ibatis中,...
在IT领域,特别是Java开发中,iBatis是一个非常受欢迎的...以上是关于iBatis一对多关联映射的实战介绍,希望对您在开发过程中有所帮助。更多关于iBatis的高级用法和最佳实践,可以通过文章链接中的资源进行深入学习。
此外,元素允许你处理一对多或多对多的关系,使数据的层次结构得以保持。 在实际应用中,Java代码通过SqlSession对象与SqlMap进行交互。SqlSession提供了execute方法来执行SqlMap中的SQL语句,同时,它还负责管理...
本篇文章将详细探讨iBatis在增删改查(CRUD)操作以及一对一和一对多关系映射中的应用。 首先,让我们了解一下iBatis的CRUD操作: 1. **创建(Create)**:在iBatis中,创建数据通常通过`<insert>`标签实现。你需要...
在本文档中,我们将详细介绍iBatis在处理多对多关系时的配置和实现。 多对多关系 多对多关系是一种常见的关系数据库设计模式,用于描述两个实体之间的多对多关系。在本例中,我们将使用学生(Student)和教师...
6.iBatis2学习笔记:一对多映射(双向).doc 7.iBatis2学习笔记:多对多映射(双向) .doc 8.iBatis2学习笔记:总结与思考.doc 9.iBatis2实体状态图解.doc 10.iBatis insert操作陷阱.doc 每章都有小例子。 呵呵,希望...
标题 "iBatis 一对多映射" 描述中提到的是关于 iBatis 框架下的一对多关系映射。iBatis 是一个基于 Java 的持久层框架,它允许程序员将 SQL 查询与 Java 代码相结合,以实现更灵活的数据访问。在数据库关系模型中,...
在iBATIS 2.0中文API中,我们可以深入理解这个框架的核心功能和用法,包括一对多、多对一的关系映射、属性设置以及解决方案的详细解析。 首先,一对多和多对一的关系映射是ORM(对象关系映射)中的关键概念。在...
`<resultMap>`标签可以处理复杂的一对多、一对一、多对多关系,以及自定义的类型转换。 6. **事务管理**: iBatis支持JDBC和Spring的事务管理方式,通过`transactionManager`配置来决定。在Spring环境下,可以利用...
这包括了列名到字段名的映射,以及处理一对一、一对多、多对多等复杂关系的方法。 4. **动态SQL**:iBatis的一个强大特性是支持动态SQL,开发者可以在XML映射文件中使用条件语句、循环结构等,以适应不同情况下的...
在多表查询中,Ibatis 提供了多种方式来处理复杂的关联查询,包括一对一、一对多、多对一和多对多等关系。在这个例子中,我们将探讨如何在 Ibatis 中实现一对多的关系查询。 首先,我们创建了两个表:`book` 和 `...