1. 程式人生 > >Mybatis之表之間對映關係總結

Mybatis之表之間對映關係總結

1.什麼是表之間對映關係

就是多張表進行關聯,如果查詢等操作不只是與一張表有關係,同時其他表也要進行操作。

2.資料庫中的連線查詢

表結構:

          顧客表:customers                                                訂單表:orders                                         員工表emps                                             

內連線:查詢哪個顧客在訂單中買的什麼樣水果的名稱和價格

sql語句:

SELECT c.name,o.isbn,o.price FROM customers c INNER JOIN orders o on c.id=o.customers_id;

結果:


外連線之左外連線:通過顧客名稱分組,查詢每個顧客在訂單中購買商品的數量

sql語句:

select c.name,count(o.isbn) from customers c LEFT OUTER JOIN orders o on c.id=o.customers_id GROUP BY c.name;
結果:


外連線之右外連線:通過顧客名稱分組,查詢每個顧客在訂單中購買商品的數量

sql語句:

SELECT c.name,count(o.isbn) from orders o RIGHT OUTER JOIN customers c on o.customers_id=c.id GROUP BY c.name;
結果:


解釋:和左外連線的結果是一樣的,所以說左外連線和右外連線是差不多的,只是二者以哪個表為基準不同而已。

內自連線:求出員工表中AA的老闆是EE

sql語句:

SELECT user.ename AS '員工',boss.ename AS '員工對應的上級' from emps user INNER JOIN emps boss on user.mgr=boss.empno;
結果:


外左自連線:求出員工表中AA的老闆是EE

sql語句:

SELECT user.ename AS '員工',boss.ename AS '員工對應的上級' FROM emps user left OUTER JOIN emps boss on user.mgr=boss.empno;
結果:


外右自連線:求出員工表中AA的老闆是EE

sql語句:

SELECT user.ename AS '員工',boss.ename AS '員工對應的上級' FROM emps boss RIGHT OUTER JOIN emps user on user.mgr=boss.empno;
結果:


3.Mybatis準備工作

匯入jar包:

asm-3.3.1.jar cglib-2.2.2.jarcommons-logging-1.1.1.jarlog4j-1.2.16.jarmybatis-3.1.1.jarmysql-connector-java-5.1.26-bin.jar

日誌檔案:log4j.properties

log4j.rootLogger=debug,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
資料庫配置檔案:db.properties
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/relation?characterEncoding=utf-8
mysql.username=root
mysql.password=
工具類:
public class MybatisUtil {
	private static ThreadLocal<SqlSession> threadLocal =new ThreadLocal<SqlSession>();
	private static SqlSessionFactory sqlSessionFactory;
	static{
		try {
			Reader reader =Resources.getResourceAsReader("mybatis.xml");
			sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
	private MybatisUtil(){}
	public static SqlSession getSqlSession(){
		SqlSession sqlSession =threadLocal.get();
		if(sqlSession ==null){
			sqlSession =sqlSessionFactory.openSession();
			threadLocal.set(sqlSession);
		}
		
		return sqlSession;
	}
	
	public static void closeSqlSession(){
		
		SqlSession sqlSession =threadLocal.get();
		if(sqlSession !=null){
			sqlSession.close();
			threadLocal.remove();
		}
	}
	public static void main(String[] args) {
		Connection conn =MybatisUtil.getSqlSession().getConnection();
		System.out.println(conn !=null ?"連線成功":"連線失敗");
		MybatisUtil.closeSqlSession();
	}
}

4.Mybatis實現一對一關係

需求就是:查詢一個學生的學號、查詢一個id號對應的學生

Mybatis總配置檔案:

<?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"></properties>
	<typeAliases>
		<typeAlias type="cn.spy.model.Student" alias="Student"/>
		<typeAlias type="cn.spy.model.Card" alias="Card"/>
	</typeAliases>
	<environments default="mysql_developer">
		<!-- mysql環境資訊 -->
		<environment id="mysql_developer">
			<!-- mybatis使用jdbc事務管理方式 -->
			<transactionManager type="jdbc"></transactionManager>
			<!-- mybatis使用連線池方式來獲取連線 -->
			<dataSource type="pooled">
				<!-- 配置與資料庫互動的四個必要屬性 -->
				<property name="driver" value="${mysql.driver}"/>
				<property name="url" value="${mysql.url}"/>
				<property name="username" value="${mysql.username}"/>
				<property name="password" value="${mysql.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="cn\spy\model\CardMapper.xml"/>
		<mapper resource="cn\spy\model\StudentMapper.xml"/>
	</mappers>
</configuration>
model模型及對應的mapper:

Student:

public class Student {
	private Integer id;
	private String name;
	private Card card;
	public Student(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Card getCard() {
		return card;
	}
	public void setCard(Card card) {
		this.card = card;
	}
	@Override
	public String toString() {
		return "Student [id=" + id + ", name=" + name + ", card=" + card + "]";
	}
}
StudentMapper.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="studentNamespace">
	
	<resultMap type="Student" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>
		<!-- 引入CardMapper.xml檔案中的對映資訊 
			property表示Student類的關聯屬性
			resultMap表示引入 CardMapper.xml檔案的對映型別
		-->
		<association property="card" resultMap="cardNamespace.cardMap"></association>
	</resultMap>

	<select id="findById" parameterType="int" resultMap="studentMap">
		select * from students s inner join cards c on s.sid=c.cid and s.sid=#{id};
	</select>
	
	<select id="findByName" parameterType="string" resultMap="studentMap">
		select * from students s inner join cards c on s.sid=c.cid and s.sname=#{name};
	</select>
</mapper>
Card:
public class Card {
	private Integer id;
	private String num;
	public Card(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getNum() {
		return num;
	}
	public void setNum(String num) {
		this.num = num;
	}
	@Override
	public String toString() {
		return "Card [id=" + id + ", num=" + num + "]";
	}
}
CardMapper.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="cardNamespace">
	<resultMap type="Card" id="cardMap">
		<id property="id" column="cid"/>
		<result property="num" column="cnum"/>
	</resultMap>
</mapper>
dao實現類:
public class StudentCardDaoImpl implements IStudentCardDao{

	@Override
	public Student findById(Integer id) throws Exception {
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectOne("studentNamespace.findById", id);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	@Override
	public Student findByName(String name) throws Exception {
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectOne("studentNamespace.findByName", name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	public static void main(String[] args) throws Exception {
		IStudentCardDao scd =new StudentCardDaoImpl();
		Student stu =scd.findByName("哈哈");
		System.out.println(stu);
	}
}
結果:


5.Mybatis實現一對多關係

需求:就是一個學生在哪個班級,哪個方向班級裡又有哪些學生

Mybatis總配置檔案:

<?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"></properties>
	<typeAliases>
		<typeAlias type="cn.spy.model.Student2" alias="Student2"/>
		<typeAlias type="cn.spy.model.Grade" alias="Grade"/>
	</typeAliases>
	<environments default="mysql_developer">
		<!-- mysql環境資訊 -->
		<environment id="mysql_developer">
			<!-- mybatis使用jdbc事務管理方式 -->
			<transactionManager type="jdbc"></transactionManager>
			<!-- mybatis使用連線池方式來獲取連線 -->
			<dataSource type="pooled">
				<!-- 配置與資料庫互動的四個必要屬性 -->
				<property name="driver" value="${mysql.driver}"/>
				<property name="url" value="${mysql.url}"/>
				<property name="username" value="${mysql.username}"/>
				<property name="password" value="${mysql.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="cn\spy\model\GradeMapper.xml"/>
		<mapper resource="cn\spy\model\Student2Mapper.xml"/>
	</mappers>
</configuration>
model模型及對應的mapper

Student2類:

public class Student2 {
	private Integer id;
	private String name;
	private Grade grade;
	public Student2(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Grade getGrade() {
		return grade;
	}
	public void setGrade(Grade grade) {
		this.grade = grade;
	}
	@Override
	public String toString() {
		return "Student2 [id=" + id + ", name=" + name + ", grade=" + grade
				+ "]";
	}
}
Student2Mapper.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="studentNamespace">
	
	<resultMap type="Student2" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>
		<association property="grade" resultMap="gradeNamespace.gradeMap"></association>
	</resultMap>

	<select id="findAllByName" parameterType="string" resultMap="studentMap">
		select * from students2 s2 inner join grades g on s2.sgid=g.gid and g.gname=#{name}
	</select>
</mapper>
Grade類:
public class Grade {
	private Integer id;
	private String name;
	private List<Student2> list =new ArrayList<Student2>();
	public Grade(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Student2> getList() {
		return list;
	}
	public void setList(List<Student2> list) {
		this.list = list;
	}
	@Override
	public String toString() {
		return "Grade [id=" + id + ", name=" + name + ", list=" + list + "]";
	}
}	
GradeMapper.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="gradeNamespace">

	<resultMap type="Grade" id="gradeMap">
		<id property="id" column="gid"/>
		<result property="name" column="gname"/>
	</resultMap>
	
	<select id="findGradeByName" parameterType="string" resultMap="gradeMap">
		select * from students2 s2 inner join grades g on s2.sgid=g.gid and s2.sname=#{name}
	</select>
	
</mapper>
dao實現類:
public class StudentGradeDaoImpl implements IStudentGradeDao{

	/*功能:查詢學軟體工程的人有哪些
	 * name表示學科名*/
	@Override
	public List<Student2> findAllByName(String name) throws Exception {
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectList("studentNamespace.findAllByName", name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	/*
	 * 查詢張三是屬於哪個方向的
	 * 
	 * */
	public Grade findGradeByName(String name) throws Exception{
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectOne("gradeNamespace.findGradeByName", name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	
	
	public static void main(String[] args) throws Exception {
		IStudentGradeDao sgd =new StudentGradeDaoImpl();
//		List<Student2> list =sgd.findAllByName("軟體工程");
//		for(Student2 student2 :list){
//			System.out.println(student2);
//		}
		Grade grade =sgd.findGradeByName("張三");
		System.out.println(grade);
	}
	
}

6.Mybatis實現多對多關係

需求:一個學生選修了多個課程、一個課程被多個學生選修了。

Mybatis總配置檔案:

<?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"></properties>
	<settings>
		<!-- 開啟延遲載入開關 -->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!-- 按需載入 -->
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>
	<typeAliases>
		<typeAlias type="cn.spy.model.Student3" alias="Student3"/>
		<typeAlias type="cn.spy.model.Course" alias="Course"/>
	</typeAliases>
	
	<environments default="mysql_developer">
		<!-- mysql環境資訊 -->
		<environment id="mysql_developer">
			<!-- mybatis使用jdbc事務管理方式 -->
			<transactionManager type="jdbc"></transactionManager>
			<!-- mybatis使用連線池方式來獲取連線 -->
			<dataSource type="pooled">
				<!-- 配置與資料庫互動的四個必要屬性 -->
				<property name="driver" value="${mysql.driver}"/>
				<property name="url" value="${mysql.url}"/>
				<property name="username" value="${mysql.username}"/>
				<property name="password" value="${mysql.password}"/>
			</dataSource>
		</environment>
	</environments>
	
	<mappers>
		<mapper resource="cn\spy\model\CourseMapper.xml"/>
		<mapper resource="cn\spy\model\Student3Mapper.xml"/>
	</mappers>
</configuration>
Student3類:
public class Student3 {
	private Integer id;
	private String name;
	private List<Course> courseList =new ArrayList<Course>();
	public Student3(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Course> getCourseList() {
		return courseList;
	}
	public void setCourseList(List<Course> courseList) {
		this.courseList = courseList;
	}
	@Override
	public String toString() {
		return "Student3 [id=" + id + ", name=" + name + ", courseList="
				+ courseList + "]";
	}
}
Student3Mapper.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="studentNamespace">
	
	<resultMap type="Student3" id="studentMap">
		<id property="id" column="sid"/>
		<result property="name" column="sname"/>
	</resultMap>

	<select id="findStudent3ByName" parameterType="string" resultMap="studentMap">
		select s3.sid,s3.sname from students3 s3 inner join middles m on s3.sid= m.msid inner join courses c on c.cid=m.mcid and c.cname=#{name};
	</select>
</mapper>
Course類:
public class Course {
	private Integer id;
	private String name;
	private List<Student3> student3List =new ArrayList<Student3>();
	public Course(){}
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public List<Student3> getStudent3List() {
		return student3List;
	}
	public void setStudent3List(List<Student3> student3List) {
		this.student3List = student3List;
	}
	@Override
	public String toString() {
		return "Course [id=" + id + ", name=" + name + ", student3List="
				+ student3List + "]";
	}
}
CourseMapper.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="courseNamespace">

	<resultMap type="Course" id="courseMap">
		<id property="id" column="cid"/>
		<result property="name" column="cname"/>
	</resultMap>
	
	<select id="findCourseByName" parameterType="string" resultMap="courseMap"> 
		select * from students3 s3 inner join middles m on s3.sid=m.msid inner join courses c on m.mcid=c.cid and s3.sname=#{name};
	</select>
</mapper>
dao實現類:
public class StudentCourseDaoImpl implements IStudentCourseDao{

	public static void main(String[] args) throws Exception {
		IStudentCourseDao scd =new StudentCourseDaoImpl();
//		List<Course> list =scd.findCourseByName("張三");
//		for(Course course :list){
//			System.out.println(course);
//		}
		List<Student3> list =scd.findStudent3ByName("軟體工程");
		for(Student3 student3 :list){
			System.out.println(student3);
		}
	}
	//通過學生名,檢視其選學了哪些課程
	@Override
	public List<Course> findCourseByName(String name) throws Exception {
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectList("courseNamespace.findCourseByName",name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
	//通過課程名,檢視有哪些學生選擇學習該課程
	@Override
	public List<Student3> findStudent3ByName(String name) throws Exception {
		SqlSession sqlSession =null;
		try{
			sqlSession =MybatisUtil.getSqlSession();
			return sqlSession.selectList("studentNamespace.findStudent3ByName", name);
		}catch(Exception e){
			e.printStackTrace();
			throw e;
		}finally{
			MybatisUtil.closeSqlSession();
		}
	}
}
結果:


解釋:

多對多其實就是將兩個表之間再建立一箇中間轉換表,現在就三個表,讓兩個表與中間表形成一對多的關係,多對多就可以轉化為兩個一對多的關係了。