1. 程式人生 > 其它 >mybatis 建立臨時表_MyBatis的多表查詢

mybatis 建立臨時表_MyBatis的多表查詢

技術標籤:mybatis 建立臨時表

64538ca82b4c37be5eaac0a356b64879.png
teacher表

e706e9625318f6991ce20a6ebffc2738.png
student表

多對一

結果巢狀

1:建立mybatis配置檔案(mybatis-config.xml)

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<properties resource="db.properties"/>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="${driver}" />
				<property name="url" value="${url}" />
				<property name="username" value="${username}" />
				<property name="password" value="${password}" />
			</dataSource>
		</environment>
	</environments> 
	<mappers>
		<mapper resource="cn/sxt/entity/student-mapper.xml" />
	</mappers>
</configuration>
  • 這裡使用了properties檔案,可以不使用
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbc
username=root
password=1234

2:建立工具類(MybatisUtils.java)用於獲取SqlSession物件

public class MybatisUtil {
	public static SqlSessionFactory getSqlSessionFactory() throws IOException{
		String resource = "mybatis-config.xml";
		InputStream inputStream = Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		return sqlSessionFactory;
	}
	public static SqlSession getSqlSession() throws IOException{
		SqlSession sqlsession = getSqlSessionFactory().openSession();
		return sqlsession;
	}
}
  • String resource ="mybatis-config.xml" 為“包名+檔名”,此處mybatis配置檔案直接放在src下,省略包名

3:建立實體類物件

public class Student {
	private int id;
	private String name;
	private int tid;
	private Teacher teacher;
	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 getTid() {
		return tid;
	}
	public void setTid(int tid) {
		this.tid = tid;
	}
	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
}
  • 從Student入手的多對一查詢,需要在Student中新增一個Teacher類屬性用於存放teacher表
public class Teacher {
	private int id;
	private String name;
	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;
	}
}

4:建立mapper對映檔案用於書寫SQL語句

<?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="cn.sxt.entity.student-mapper">
	<select id="getStudentAndTeacher" resultMap="getStudentAndTeacherMap">
		select s.id,s.name,s.tid,t.id,t.name from student s,teacher t where s.tid=t.id
	</select>
	<resultMap type="cn.sxt.entity.Student" id="getStudentAndTeacherMap">
		<id column="id" property="id"/>
		<result column="name" property="name"/>
		<result column="tid" property="tid"/>
		<!-- association為關聯物件,在進行多表查詢且相應返回型別的實體類中擁有其他類時使用。property表示資料庫中的表,JavaType表示對應的實體類 -->
		<association property="teacher" javaType="cn.sxt.entity.Teacher">
			<id column="id" property="id"/>
			<result column="name" property="name"/>
		</association>
	</resultMap>
</mapper>
  • 從Student入手的多對一查詢,需要在Student實體類中新增一個Teacher類屬性,同時在mapper對映檔案中使用resultMap標籤,在其內使用association標籤。association表示關聯物件,其內的property屬性表示資料庫中的表,JavaType表示對應的實體類
  • 資料庫中的兩個表的列名是相同的,為避免混亂,在查詢時最好使用別名,如下(不使用也可,如上)
<?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="cn.sxt.entity.student-mapper">
	<select id="getStudentAndTeacher" resultMap="getStudentAndTeacherMap">
		select s.id sid,s.name sname,s.tid stid,t.id tid,t.name tname from student s,teacher t where s.tid=t.id
	</select>
	<resultMap type="cn.sxt.entity.Student" id="getStudentAndTeacherMap">
		<id column="sid" property="id"/>
		<result column="sname" property="name"/>
		<result column="stid" property="tid"/>
		<!-- association為關聯物件,在進行多表查詢且相應返回型別的實體類中擁有其他類時使用。property表示資料庫中的表,JavaType表示對應的實體類 -->
		<association property="teacher" javaType="cn.sxt.entity.Teacher">
			<id column="tid" property="id"/>
			<result column="tname" property="name"/>
		</association>
	</resultMap>
</mapper>

5:建立Dao(StudentDao.java)

public class StudentDao {
	public List<Student> getStudentAndTeacher() throws IOException{
		SqlSession sqlsession = MybatisUtil.getSqlSession();
		List<Student> list = sqlsession.selectList("cn.sxt.entity.student-mapper.getStudentAndTeacher");
		sqlsession.commit();
		return list;
	}
}

測試類

public class Test {
	public static void main(String[] args) throws IOException {
		StudentDao dao = new StudentDao();
		List<Student> list = dao.getStudentAndTeacher();
		for(Student u:list){
			System.out.println(u.getId()+"  "+u.getName()+"  "+u.getTid()+"  "+u.getTeacher().getId()+"  "+u.getTeacher().getName());
		}
	}
}

測試結果

1  張一  1  1  張三
2  李二  1  1  張三
3  王三  1  1  張三

查詢巢狀

1:mapper對映檔案中association標籤的另一種使用方法

<?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="cn.sxt.entity.student-mapper">
	<select id="getStudentAndTeacher" resultMap="getStudentAndTeacherMap">
		select * from student
	</select>
	<resultMap type="cn.sxt.entity.Student" id="getStudentAndTeacherMap">
		<association property="teacher" column="tid" javaType="cn.sxt.entity.Teacher" select="cn.sxt.entity.teacher-mapper.getTeacher">
		</association>
	</resultMap>
</mapper>
  • association標籤中property屬性表示資料庫中的表,column屬性表示外來鍵,JavaType屬性表示實體類,select屬性表示對應表的查詢語句
  • select屬性表示對應表的查詢語句,用“包名+檔案名錶示”,一般對於另一表的查詢會寫在另一個mapper對映檔案之內。也可以寫在同一檔案內,若寫在同一檔案內,則包名可省略
  • 結果巢狀對資料庫查詢一次,查詢巢狀對資料庫查詢兩次,所以結果巢狀的效率會更高,但查詢巢狀看起來會更清爽點
<?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="cn.sxt.entity.teacher-mapper">
	<select id="getTeacher" resultType="cn.sxt.entity.Teacher">
		select * from teacher
	</select>
</mapper>

測試類

public class Test {
	public static void main(String[] args) throws IOException {
		StudentDao dao = new StudentDao();
		List<Student> list = dao.getStudentAndTeacher();
		for(Student u:list){
			System.out.println(+u.getId()+"  "+u.getName()+"  "+u.getTid()+"  "+u.getTeacher().getId()+"  "+u.getTeacher().getName());
		}
	}

測試結果

1  張一  0  1  張三
2  李二  0  1  張三
3  王三  0  1  張三
  • 此處Student的tid無法查詢,原因未知

一對多

結果巢狀

1:建立mybatis配置檔案(mybatis-config.xml)

2:建立工具類(MybatisUtils.java)用於獲取SqlSession物件

3:建立實體類物件

package cn.sxt.entity;

import java.util.List;

public class Teacher {
	private int id;
	private String name;
	private List<Student> student;
	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 List<Student> getStudent() {
		return student;
	}
	public void setStudent(List<Student> student) {
		this.student = student;
	}
}
  • 因為是從Teacher入手的一對多查詢,所以Teacher實體類中需要有list集合的Student屬性
package cn.sxt.entity;

public class Student {
	private int id;
	private String name;
	private int tid;
	/*private Teacher teacher;*/
	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 getTid() {
		return tid;
	}
	public void setTid(int tid) {
		this.tid = tid;
	}
/*	public Teacher getTeacher() {
		return teacher;
	}
	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}*/
}

4:建立mapper對映檔案(teacher-mapper.xml)用於書寫SQL語句

<?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="cn.sxt.entity.teacher-mapper">
	<select id="getTeacher" resultType="cn.sxt.entity.Teacher">
		select * from teacher
	</select>
	<select id="getTeacherAndStudent" resultMap="getTeacherAndStudentMap">
		select s.id sid,s.name sname,s.tid stid,t.id tid,t.name tname from student s,teacher t where s.tid=t.id and t.id=1
	</select>
	<resultMap type="cn.sxt.entity.Teacher" id="getTeacherAndStudentMap">
		<id column="tid" property="id"/>
		<result column="tname" property="name"/>
		<collection property="student" ofType="cn.sxt.entity.Student">
			<id column="sid" property="id"/>
			<result column="sname" property="name"/>
			<result column="stid" property="tid"/>
		</collection>
	</resultMap>
</mapper>
  • select s.id sid,s.name sname,s.tid stid,t.id tid,t.name tname from student s,teacher t where s.tid=t.id and t.id=1
  • 由於Teacher實體類中使用的是關於Student的集合,所以在對映檔案中的resultMap中需要使用collection標籤而不是association標籤
  • collection標籤中,property屬性表示資料庫中的表,ofType屬性表示實體類
  • 若資料庫中兩個表的列名是相同的,則在查詢時,SQL語句最好要使用別名,便於在resultMap標籤中標明清楚(如上),否則容易出現問題(原因未明)

5:Dao(TeacherDao.java)

public class TeacherDao {
	public Teacher getStudentAndTeacher(int id) throws IOException{
		SqlSession sqlsession = MybatisUtil.getSqlSession();
		Teacher teacher = sqlsession.selectOne("cn.sxt.entity.teacher-mapper.getTeacherAndStudent", id);
		sqlsession.commit();
		return teacher;
	}

測試類

public class Test {
	public static void main(String[] args) throws IOException {
		TeacherDao dao = new TeacherDao();
		Teacher teacher = dao.getStudentAndTeacher(1);
		System.out.println(teacher.getId()+"  "+teacher.getName());
		List<Student> list = teacher.getStudent();
		for(Student s:list){
			System.out.println(s.getId()+"  "+s.getName()+"  "+s.getTid());
		}
	}

測試結果

1  張三
1  張一  1
2  李二  1
3  王三  1

查詢巢狀

1:mapper對映檔案(teacher-mapper.xml)

<?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="cn.sxt.entity.teacher-mapper">
	<select id="getTeacherAndStudent2" resultMap="getTeacherAndStudent2Map">
		select * from teacher where id = #{id}
	</select>
	<resultMap type="cn.sxt.entity.Teacher" id="getTeacherAndStudent2Map">
		<collection property="student" javaType="ArrayList" ofType="cn.sxt.entity.Student" column="id" select="cn.sxt.entity.student-mapper.getStudent">
		</collection>
	</resultMap>
</mapper>

2:Dao

public class TeacherDao {
	public Teacher getStudentAndTeacher(int id) throws IOException{
		SqlSession sqlsession = MybatisUtil.getSqlSession();
		Teacher teacher = sqlsession.selectOne("cn.sxt.entity.teacher-mapper.getTeacherAndStudent2", id);
		sqlsession.commit();
		return teacher;
	}
}

測試類

public class Test {
	public static void main(String[] args) throws IOException {
		TeacherDao dao = new TeacherDao();
		Teacher teacher = dao.getStudentAndTeacher(1);
		System.out.println(teacher.getId()+"  "+teacher.getName());
		List<Student> list = teacher.getStudent();
		for(Student s:list){
			System.out.println(s.getId()+"  "+s.getName()+"  "+s.getTid());
		}
	}

測試結果

0  張三
1  張一  1
2  李二  1
3  王三  1
  • 由於在mapper對映檔案的resultMap標籤的collection標籤中使用了column="id",導致測試結果中Teacher的id無法獲取(原因未知)