`
lzh166
  • 浏览: 293819 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

iBATIS入门知识进阶四

阅读更多
一、关联数据的存储查询方式,以班级和学生为例,
在学生多方添加班级一方的引用,班级一端增加对学生集合的引用,建立双向关联

实体类
public class Classes {
	private int id;
	private String name;
         private List students; //不可以用set否则会出错
	
	public List getStudents() {
		return students;
	}
	public void setStudents(List students) {
		this.students = students;
	}
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
}

public class Student {
	private int id;
	private String name;
	private String sex;
	private Classes classes;
	
	public Classes getClasses() {
		return classes;
	}
	public void setClasses(Classes classes) {
		this.classes = classes;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}

}


Classes.xml文件信息:
	<typeAlias alias="Classes" type="com.lzh.ibatis.Classes"/>

	<insert id="saveClasses" parameterClass="Classes">
		insert into t_classes values (null,#name#)
		<selectKey resultClass="int" keyProperty="id">
			select @@identity as id//存储时必须将id返回,以备学生所用
		</selectKey>
	</insert>

	<resultMap class="Classes" id="classes-result">
		<result property="id"/>
		<result property="name" column="cname"/>
		<result property="students" column="id" select="findStudentByCid"/>
	</resultMap>
	
	<select id="findClassesById" resultMap="classes-result" parameterClass="int">
		select * from t_classes where id=#id#
	</select>
	
	<select id="findClasses" resultMap="classes-result" parameterClass="int">
		select * from t_classes where id=#id#
	</select>


Student.xml文件:
	<typeAlias alias="Student" type="com.lzh.ibatis.Student"/>
  
           <insert id="saveStudent"  parameterClass="Student">
		insert into t_student values (null,#name#,#sex#,#classes.id#)
	</insert>

	<resultMap class="Student" id="findStudent-result">
		<result property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="sex" column="sex"/>
		<result property="classes" column="cid" select="findClassesById"/>
	</resultMap>
	
	<select id="findStudent" resultMap="findStudent-result" parameterClass="int">
		select * from t_student where id=#id#
	</select>
	
	<select id="findStudentByCid" resultMap="findStudent-result" parameterClass="int">
		select * from t_student where cid=#cid#
	</select>

在sqlMapConfig.xml文件增加上面这两个映射文件,为了是大家能更清楚,xml文件中所变化的内容,我将xml文件全部贴出:
 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig SYSTEM "http://ibatis.apache.org/dtd/sql-map-config-2.dtd" >
<sqlMapConfig>
	<settings lazyLoadingEnabled="true"/>
	<transactionManager type="JDBC" commitRequired="false">
		<dataSource type="SIMPLE">
		<property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
		<property name="JDBC.ConnectionURL" value="jdbc:mysql://127.0.0.1/ibatis"/>
		<property name="JDBC.Username" value="root"/>
     	<property name="JDBC.Password" value="123"/>
		</dataSource>
	</transactionManager>
  <sqlMap resource="com/lzh/ibatis/Student.xml"/>
  <sqlMap resource="com/lzh/ibatis/Classes.xml"/>
</sqlMapConfig>


利用上面的方式,是可以实现的,不过需要明白为什么可以,如果在上面的xml配置文件中不增加lazyLoadingEnabled="true",程序将会陷入死循环,值栈溢出,同时集合映射时也必须指定为list,而无法使用set集合。
因此实现双向关联,需要完成下面两步操作

* 【双向关联】如果没有启用懒加载,将会出现StackOverFlow的异常!在设置lazyLoadingEnabled="true"(上面的xml文件中可以看到)
* 【双向关联】启用懒加载特性,而且将关联的集合定义为Set,无法进行双向关联定义(但定义成List就可以)

测试代码:
public void testSaveStudent()throws Exception{
		
		SqlMapClient sqlMapper = IbatisSQLMapConfig.getSqlMapInstance();
		Classes classes = new Classes();
		classes.setName("测试班级"+ new Random().nextInt(9999));
		sqlMapper.insert("saveClasses", classes);
		Student student = new Student();
		student.setName("学生"+new Random().nextInt(9999));
		student.setSex("男");
		student.setClasses(classes);
		sqlMapper.insert("saveStudent",student);
	}
	
	public void testFindClasses()throws Exception{
		
		SqlMapClient sqlMapper = IbatisSQLMapConfig.getSqlMapInstance();
		
		Classes cla = (Classes)sqlMapper.queryForObject("findClasses",1);
		System.out.println(cla.getName()+"有学生人数:"+cla.getStudents().size());
	}
    
         	public void testFindStudent()throws Exception{
		
		SqlMapClient sqlMapper = IbatisSQLMapConfig.getSqlMapInstance();
		
		Student stu = (Student)sqlMapper.queryForObject("findStudent",1);
		System.out.println(stu.getName()+"所属班级是:"+stu.getClasses().getName());
	}

下面来贴出sql语句:
CREATE TABLE t_student(
	id integer not null auto_increment,
	name varchar(255),
	sex varchar(255),
	cid integer,
	primary key(id)
);

CREATE TABLE t_classes(
	id integer not null auto_increment,
	cname varchar(255),
	primary key(id)
)


二、多态查询的映射策略

在设计数据库表的时候,需要提供一个辨别字段,来记录对象的类型,在插入数据的时候,我们要自己定义这个辨别字段的值,在查询数据的时候可以利用iBATIS提供的discriminator元素来映射多态的数据。
下面来贴出实体类代码:
/**
 * 基类
 * @author Administrator
 *
 */
public class Animal {
	private int id;
	private String name;
	private String sex;
	
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
}
/**
 * Bird子类
 * @author Administrator
 */
public class Bird extends Animal{
	private int height;

	public int getHeight() {
		return height;
	}

	public void setHeight(int height) {
		this.height = height;
	}
}
/**
 * Pig子类
 * @author Administrator
 */
public class Pig extends Animal{
	private int weight;

	public int getWeight() {
		return weight;
	}

	public void setWeight(int weight) {
		this.weight = weight;
	}
}
下面贴出Animal.xml配置文件的信息:
<sqlMap>
	<typeAlias alias="Animal" type="com.lzh.ibatis.Animal"/>
	<typeAlias alias="Bird" type="com.lzh.ibatis.Bird"/>
	<typeAlias alias="Pig" type="com.lzh.ibatis.Pig"/>

	<insert id="insertAnimal" parameterClass="Animal">
		insert into t_animal (name,sex,animal_type) values (#name#,#sex#,'Animal')
	</insert>
	<insert id="insertBird" parameterClass="Bird">
		insert into t_animal (name,sex,height,animal_type) values (#name#,#sex#,#height#,'Bird')
	</insert>
	<insert id="insertPig" parameterClass="Pig">
		insert into t_animal (name,sex,weight,animal_type) values (#name#,#sex#,#weight#,'Pig')
	</insert>
	
	<resultMap class="Animal" id="animal">
		<result property="id" column="id"/>
		<result property="name" column="name"/>
		<result property="sex" column="sex"/>
		<discriminator column="animal_type" javaType="string">
			<subMap value="Bird" resultMap="bird"/>
			<subMap value="Pig" resultMap="pig"/>
		</discriminator>
	</resultMap>
	<resultMap class="Bird" id="bird" extends="animal">
		<result property="height" column="height"/>
	</resultMap>
	<resultMap class="Pig" id="pig" extends="animal">
		<result property="weight" column="weight"/>
	</resultMap>
	<select id="findAllAnimals" resultMap="animal">
		select * from t_animal
	</select>
</sqlMap>


在sqlMapConfig.xml文件中增加下面的映射
  <sqlMap resource="com/lzh/ibatis/Animal.xml"/>


测试代码:
public void testSaveAnimal() throws Exception{
		
		//从配置文件中得到SqlMapClient对象 
		SqlMapClient sqlMapper = IbatisSQLMapConfig.getSqlMapInstance();
		
		Animal a = new Animal();
		a.setName("动物");
		a.setSex("1");
		sqlMapper.insert("insertAnimal", a);
		
		Bird b = new Bird();
		b.setName("鸟");
		b.setSex("0");
		b.setHeight(1000);
		sqlMapper.insert("insertBird", b);
		
		Pig p = new Pig();
		p.setName("猪");
		p.setSex("1");
		p.setWeight(500);
		sqlMapper.insert("insertPig", p);
	}
	
	public void testFindAllAnimals() throws Exception{
		
		//从配置文件中得到SqlMapClient对象 
		SqlMapClient sqlMapper = IbatisSQLMapConfig.getSqlMapInstance();;
		
		List animals = sqlMapper.queryForList("findAllAnimals");
		for (Iterator iterator = animals.iterator(); iterator.hasNext();) {
			Animal a = (Animal) iterator.next();
			System.out.println(a.getName()+","+a);
		}
	}

sql建表语句:
create table t_animal(
	ID integer not null auto_increment,
	NAME varchar(255),
	SEX varchar(255),
	HEIGHT integer,
	WEIGHT integer,
	ANIMAL_TYPE varchar(20),
	primary key(ID)
);
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics