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关联查询的主要内容,如果未能解决你的问题,请参考以下文章