提示:在阅读本篇文章之前,大家应该熟练掌握SQL的多表联查语句,有助于提高大家对本篇文章的理解,用到的工具依旧是我们熟悉的eclipse。
前言:
mybatis作为一个半自动的ORM模型,内部封装了jdbc,并且通过注解或者xml文件的形式完成了加载驱动,创建连接,创建Statement等繁琐过程,并通过java对象和statement中sql的动态参数进行银蛇生成最终执行的sql语句,最后由mybatis框架执行SQL并将返回结果映射称java对象并返回。本篇文章将用注解和xml文件两种方式对多表联查进行讲解。
实现mybatis多表联查的步骤如下:
①首先我们先来熟悉要用到的两张表的表关系:
学生表(student)
班级表(class)
从上图两张表中我们可以看出,
对于学生表来说,一个学生只能对应一个班级信息,所以学生=》班级就是一对一关系。
对于班级表来说,一个班级可以有多名学生信息,所以班级=》学生就是一对多关系。
②创建项目以及创建学生和班级实体类,和sqlsession的封装
创建普通java项目,导入相关jar包,如下图:
封装sqlsession,创建Daoutil
package com.ape.dao;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class DaoUtil {
private static SqlSessionFactory build;
static {
try {
// 1. 加载配置文件
InputStream istem = Resources.getResourceAsStream("mybatis-config.xml");
// 2. 构建 sqlsession工厂对象(工厂模式)
build = new SqlSessionFactoryBuilder().build(istem);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static SqlSession getSqlSession() {
return build.openSession();
}
public static void closeSource(SqlSession sqlSession) {
sqlSession.close();
}
}
**创建学生和班级类 **
**学生类(Student): **
**我们会将banji类的对象做为外部属性封装到Student类中 **
package com.ape.bean;
import java.util.Date;
public class Student {
private int sid;
private String sname;
private Date birthday;
private String ssex;
private int classid;
//外部属性
Banji bj = new Banji();
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getSsex() {
return ssex;
}
public void setSsex(String ssex) {
this.ssex = ssex;
}
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public Banji getBj() {
return bj;
}
public void setBj(Banji bj) {
this.bj = bj;
}
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int sid, String sname, Date birthday, String ssex, int classid, Banji bj) {
super();
this.sid = sid;
this.sname = sname;
this.birthday = birthday;
this.ssex = ssex;
this.classid = classid;
this.bj = bj;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", birthday=" + birthday + ", ssex=" + ssex + ", classid="
+ classid + ", bj=" + bj + "]";
}
}
班级类(Banji)java中不能将类名设置成class
**我们会将Studnet类的集合作为外部属性封装到Banji类中 **
package com.ape.bean;
import java.util.List;
public class Banji {
private int classid;
private String classname;
//外部属性
List<Student> list;
public int getClassid() {
return classid;
}
public void setClassid(int classid) {
this.classid = classid;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public List<Student> getList() {
return list;
}
public void setList(List<Student> list) {
this.list = list;
}
public Banji() {
super();
// TODO Auto-generated constructor stub
}
public Banji(int classid, String classname, List<Student> list) {
super();
this.classid = classid;
this.classname = classname;
this.list = list;
}
@Override
public String toString() {
return "Banji [classid=" + classid + ", classname=" + classname + ", list=" + list + "]";
}
}
③完成上述步骤后,我们将从xml文件和注解两种方式对多表联查进行讲解
XML文件形式:
一对一:(学生=》班级):
创建StudentMapper接口:
package com.ape.mapper;
import java.util.List;
import com.ape.bean.Student;
public interface StudentMapper {
//一对一查找学生和班级
public List<Student> findStudentAndBanji();
}
创建StudentMapper的xml文件:
这里我们用到了标签<association>,标签内的属性property中间依旧写实体类中外部属性的对象名称,在标签中间,照常写外部属性的信息映射,字段和属性关系映射。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ape.mapper.StudentMapper">
<!-- 类路径 -->
<!-- 一对以学生和班级 -->
<resultMap type="Student" id="StudentMapper">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="birthday" property="birthday"/>
<result column="ssex" property="ssex"/>
<result column="classid" property="classid"/>
<association property="bj">
<result column="classid" property="classid"/>
<result column="classname" property="classname"/>
</association>
</resultMap>
<select id="findStudentAndBanji" resultMap="StudentMapper">
select * from Student left join class on student.classid = class.classid
</select>
</mapper>
测设类:
package com.ape.test;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.StudentMapper;
public class TestfindStudentAndBanji {
public static void main(String[] args) {
SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = mapper.findStudentAndBanji();
for (Student s:list) {
System.out.println(s);
}
sqlSession.close();
}
}
可以看到其中班级信息显示出来了,证明一对一多表联查映射成功!!!
一对多(班级=》学生):
创建BanjiMapper接口:
package com.ape.mapper;
import java.util.List;
import com.ape.bean.Banji;
public interface BanjiMapper {
//一对多映射(班级学生)
public List<Banji> findBanjiAndStudent();
}
创建BanjiMapper的xml文件:
这里我们用到了标签<collection>,其中属性property写实体类中外部属性Studnet集合的名称,ofYupe写集合中元素的类型,这里就写Student类。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ape.mapper.BanjiMapper">
<!-- 类路径 -->
<!-- 一对多结果集关系映射 -->
<resultMap type="Banji" id="BanjiMapper">
<id column="classid" property="classid"/>
<result column="classname" property="classname"/>
<collection property="list" ofType="Student">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<result column="birthday" property="birthday"/>
<result column="ssex" property="ssex"/>
<result column="classid" property="classid"/>
</collection>
</resultMap>
<!-- 班级和学生全查 -->
<select id="findBanjiAndStudent" resultMap="BanjiMapper">
select * from class inner join student on class.classid = student.classid
order by class.classid
</select>
</mapper>
测试类:
package com.ape.test;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.ape.bean.Banji;
import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.BanjiMapper;
public class TestfindBanjiAndStudent {
public static void main(String[] args) {
SqlSession sqlSession = DaoUtil.getSqlSession();
BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
List<Banji> list = mapper.findBanjiAndStudent();
for (Banji b : list) {
System.out.println("班级名称:"+b.getClassname());
for (Student s : b.getList()) {
int sid = s.getSid();
String sname = s.getSname();
Date birthday = s.getBirthday();
String ssex = s.getSsex();
int classid = s.getClassid();
System.out.println("学生编号:"+sid+" 学生姓名:"+sname+" 学生生日:"+birthday+" 学生性别:"+ssex+" 班级编号:"+classid);
}
System.out.println("================");
}
}
}
注解的形式:
一对一(学生=》班级):
创建StudentMapper接口文件:
用@Results和@Result写对应字段和属性的关系映射。
用@One注解写实体类中外部属性的关系映射,select中写调用方法的类路径,这里相当于将classid字段信息传入findAllBanjiByClassid方法中,通过classid查询学生信息之后返回到结果集中。
package com.ape.mapper;
import java.util.List;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.jdbc.SQL;
import com.ape.bean.Student;
public interface StudentMapper {
//根据班级classid查询学生信息
@Select("select * from Student where classid=#{classid}")
public List<Student> findAllStudentByClassid();
//一对一映射(学生班级)
@Results(id = "StudentAndBanjiMapper",value = {
@Result(column = "classid",property = "classid"),
@Result(column = "classid",property = "bj",
one=@One(select = "com.ape.mapper.BanjiMapper.findAllBanjiByClassid")
)
})
@Select("select * from student")
public List<Student> findAllStudentAndBanji();
}
测试类:
package com.ape.teat;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.ape.bean.Student;
import com.ape.dao.DaoUtil;
import com.ape.mapper.StudentMapper;
public class TestfindAllStudentAndBanji {
public static void main(String[] args) {
SqlSession sqlSession = DaoUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> list = mapper.findAllStudentAndBanji();
for (Student student : list) {
System.out.println(student);
}
sqlSession.close();
}
}
一对多(班级=》学生):
创建BanjiMapper接口:
依旧使用@Results和@Result进行字段和属性的映射,对于外部属性Studnet集合我们使用@Many注解进行关系映射,select中还是写入调用的方法,相当于对奥用方法查询班级中所有的学生信息放入集合中,然后映射到结果集中。
package com.ape.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import com.ape.bean.Banji;
public interface BanjiMapper {
//通过classid查询班级信息
@Select("select * from class where classid=#{classid}")
public List<Banji> findAllBanjiByClassid();
//一对多映射(班级和学生)
@Results(id = "findAllBanjiAndStudent",value = {
@Result(column = "classid",property = "list",many=@Many(select = "com.ape.mapper.StudentMapper.findAllStudentByClassid")
)
})
@Select("select * from class")
public List<Banji> findAllBanjiAndStudent();
}
测试类:
package com.ape.teat;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.ape.bean.Banji;
import com.ape.dao.DaoUtil;
import com.ape.mapper.BanjiMapper;
public class TestfindAllBanjiAndStudent {
public static void main(String[] args) {
SqlSession sqlSession = DaoUtil.getSqlSession();
BanjiMapper mapper = sqlSession.getMapper(BanjiMapper.class);
List<Banji> list = mapper.findAllBanjiAndStudent();
for (Banji banji : list) {
System.out.println(banji);
}
sqlSession.close();
}
}
总结:
方式一:sqlMapper配置文件
**一对一:在resultMap标签中使用 association 标签 **
一对多:在resultMap 标签中使用collection 标签
**方式二:注解 **
**一对一:在@Results 注解中的@Result注解中使用@One注解 **
一对多:在@Results 注解中的@Result 注解中使用@Many注解
最后的最后!!!分享一句从顿顿老师那里听到的名言:
让你的生活如夏花一般绚烂,让不开心的事情像秋叶一般宁静❥(^_-)
Let life be beautiful like summer flowers and death like autumn leaves.
——泰戈尔《生如夏花》
版权归原作者 飘飘~ 所有, 如有侵权,请联系我们删除。