Mybatis 学习笔记 —— 动态SQL关联查询

Posted Johnny*

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis 学习笔记 —— 动态SQL关联查询相关的知识,希望对你有一定的参考价值。

where标签

会自动处理第一个标签中的 and,但不会处理之后中的and

personMapper.xml

	 <select id="selectPersonByIdorName" parameterType="person"  resultType="person"> 
	 	select * from person 
	 	<where> <!-- where 标签会自动去除第一个and -->
	 		<if test="id != null  and id != 0"> and id = #{id}</if>
	 		<if test="name != null  and name != '' "> and name like concat('%','${name}','%')</if>
	 	</where>
	 </select>

测试类

public static void selectPersonByIdorName() throws IOException {
		InputStream in = Resources.getResourceAsStream("config.xml");
		SqlSessionFactory sqlFactory =  new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sqlFactory.openSession();
		PersonMapper personMapper = session.getMapper(PersonMapper.class);
		Person per = new Person();
		per.setId(1);
		per.setName("j");
		List<Person> allPerson = personMapper.selectPersonByIdorName(per);
		for(Person person: allPerson)
			System.out.println(person);
	}

foreach标签

迭代的类型:数组、对象数组、集合(List)

普通数组

 <select id="selectPersonWithIdsArray" parameterType = "int[]" resultType="person">
	 	select * from person 
	 	<where>
	 		<if test="array != null  and array.length > 0">
	 			<foreach collection="array" open=" id in (" close=")" item="ids" separator=",">
	 				#{ids}
	 		</foreach>
	 		</if>
	 	</where>
	 </select>

测试类

public static void selectPersonWithIdsArray() throws IOException {
		InputStream in = Resources.getResourceAsStream("config.xml");
		SqlSessionFactory sqlFactory =  new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sqlFactory.openSession();
		PersonMapper personMapper = session.getMapper(PersonMapper.class);
		//查询id为1、2、52的人信息
		int[] ids= {1,2,52};
		List<Person> allPerson = personMapper.selectPersonWithIdsArray(ids);
		for(Person person: allPerson)
			System.out.println(person);
	}
	
无论编写代码时,传递的是什么参数名(ids),在mapper.xml中 都必须用array代替该数组 ## 对象数组
 <select id="selectPersonWithObjectArray" parameterType = "Object[]" resultType="person">
	 	select * from person 
	 	<where>
	 		<if test="array != null  and array.length > 0">
	 			<foreach collection="array" open=" id in (" close=")" item="person" separator=",">
	 				#{person.id}
	 		</foreach>
	 		</if>
	 	</where>
	 </select>

测试类

public static void selectPersonWithObjectArray() throws IOException {
		InputStream in = Resources.getResourceAsStream("config.xml");
		SqlSessionFactory sqlFactory =  new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sqlFactory.openSession();
		PersonMapper personMapper = session.getMapper(PersonMapper.class);
		Person p1 = new Person();
		Person p2 = new Person();
		Person p3 = new Person();
		p1.setId(2);
		p2.setId(4);
		p3.setId(52);
		Person[] persons= {p1,p2,p3};
		List<Person> allPerson = personMapper.selectPersonWithObjectArray(persons);
		for(Person person: allPerson)
			System.out.println(person);
	}

foreach 标签的collection属性值为array, parameterType属性值为Object[]

无论编写代码时,传递的是什么参数名(ids),在mapper.xml中 都必须用array代替该数组 ## 集合 集合:无论编写代码时,传递的是什么参数名(stuNos),在mapper.xml中 必须用list代替该数组

一对一

一对一关联查询可以使用业务类,该业务类必须包含查询结果的所有属性。另一种解决 方案是使用resultMap,

使用业务类

	 		<!-- 多表内连接查询 -->
	 		select p.* ,c.* from  person p 
	 		inner join idcard c 
	 		on p.card_id = c.card_id 
	 		where p.id = #{id}

需要创建一个业务类,该类具有Person 和IDcard的属性。

resultMap

IDcard 类

package com.johnny.entity;

public class IDcard {
	private int cardId;
	private String cardCode;
	public int getCardId() {
		return cardId;
	}
	public void setCardId(int cardId) {
		this.cardId = cardId;
	}
	public String getCardCode() {
		return cardCode;
	}
	public void setCardCode(String cardCode) {
		this.cardCode = cardCode;
	}
	

}

person.java,在从表对应类一端增加属性private IDcard idCard;

package com.johnny.entity;

public class Person {
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return this.id+"- "+ this.name+"- " +this.age+" - 性别:"+this.sex+" 卡:"+this.idCard.getCardId()+" "+this.idCard.getCardCode();
	}
	
	public Person() {}
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public Person(int id,String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public boolean isSex() {
		return sex;
	}
	public void setSex(boolean sex) {
		this.sex = sex;
	}

	public IDcard getIdCard() {
		return idCard;
	}
	public void setIdCard(IDcard idCard) {
		this.idCard = idCard;
	}
	
	private int id;
	private String name;
	private int age;
	private boolean sex;
	
}

	 <!-- 一对一映射 -->
	 
	 <select id="queryPersonByIdWithIDcard" parameterType="int" resultMap="personWithIDcard">
	 		<!-- 多表内连接查询 -->
	 		select p.* ,c.* from  person p 
	 		inner join idcard c 
	 		on p.card_id = c.card_id 
	 		where p.id = #{id}
	 </select>
	 
	 <resultMap id="personWithIDcard" type="person">
	 	<id property="id" column="id"/>
	 	<result property="name" column="name"/>
	 	<result property="age" column="age"/>
	 	<result property="sex" column="perSex"/>
	 	<association property="idCard">
	 		<id property="cardId" column="card_id" />
	 		<result property="cardCode"  column="card_code" />
	 	</association>
	 </resultMap>
	public static void queryPersonByIdWithIDcard() throws IOException {
		InputStream in = Resources.getResourceAsStream("config.xml");
		SqlSessionFactory sqlFactory =  new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sqlFactory.openSession();
		PersonMapper personMapper = session.getMapper(PersonMapper.class);
		Person person = personMapper.queryPersonByIdWithIDcard(2);
		System.out.println(person);
	}

一对多

民族与个人为一对多关系:一个民族下有多个人。而一个人只属于一个民族。
personMapper.xml

<!-- 一对多映射 根据nation_id查询该民族下的所有人-->
	<select id="queryNationByIdWithPerson" parameterType="int" resultMap="personWithNation">
		select p.*, n.* from person p 
		inner join nation n
		on p.nation_id = n.nation_id
		where p.nation_id = #{nation_id}
	</select>
	<resultMap id="personWithNation" type="nation">
		<id property="nationId"  column="nation_id" />
		<result property="nationName" column="nation_name" />
		<!-- 属性类型则使用jdbcType   属性的元素类型则使用ofType -->
		<collection property="persons" ofType="person">
			<id property="id" column="id"/>
			<result property="name" column="name"/>
			<result property="age" column="age"/>
			<result property="sex" column="perSex"/>
		</collection>
	</resultMap>

测试类

	//一对多关联查询
	public static void queryNationByIdWithPerson() throws IOException {
		InputStream in = Resources.getResourceAsStream("config.xml");
		SqlSessionFactory sqlFactory =  new SqlSessionFactoryBuilder().build(in);
		SqlSession session = sqlFactory.openSession();
		PersonMapper personMapper = session.getMapper(PersonMapper.class);
		Nation nation = personMapper.queryNationByIdWithPerson(1);
		System.out.println(nation);
		List<Person> persons = nation.getPersons();
		System.out.println(persons);
	}

nation.java

package com.johnny.entity;

import java.util.List;

public class Nation {
	public List<Person> getPersons() {
		return persons;
	}
	public void setPersons(List<Person> persons) {
		this.persons = persons;
	}
	private int nationId;
	private String nationName;
	//在多端增加属性
	private List<Person>  persons;
	public int getNationId() {
		return nationId;
	}
	public void setNationId(int nationId) {
		this.nationId = nationId;
	}
	public String getNationName() {
		return nationName;
	}
	public void setNationName(String nationName) {
		this.nationName = nationName;
	}
	@Override
	public String toString() {
		return this.nationId+" - "+this.nationName;
	}
}

person.java

package com.johnny.entity;

public class Person {
	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 int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return this.id+"- "+ this.name+"- " +this.age+" - 性别:"+this.sex;//+" 卡:"+this.idCard.getCardId()+" "+this.idCard.getCardCode();
	}
	
	public Person() {}
	public Person(String name, int age) {
		this.name = name;
		this.age = age;
	}
	public Person(int id,String name, int age) {
		this.id = id;
		this.name = name;
		this.age = age;
	}

	public boolean isSex() {
		return sex;
	}
	public void setSex(boolean sex) {
		this.sex = sex;
	}

	public IDcard getIdCard() {
		return idCard;
	}
	public void setIdCard(IDcard idCard) {
		this.idCard = idCard;
	}
	
	private int id;
	private String name;
	private int age;
	private boolean sex;
	private IDcard idCard;
}

以上是关于Mybatis 学习笔记 —— 动态SQL关联查询的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis学习笔记:动态SQL

Mybatis 学习笔记总结

MyBatis学习笔记 —— 动态SQL

mybatis动态SQL操作之插入学习笔记

Mybatis 学习笔记 —— 动态SQL关联查询

Mybatis学习笔记8:动态sql