Mybatis之表之間對映關係總結
阿新 • • 發佈:2019-02-15
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.jar 、commons-logging-1.1.1.jar 、log4j-1.2.16.jar 、mybatis-3.1.1.jar 、mysql-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();
}
}
}
結果:
解釋:
多對多其實就是將兩個表之間再建立一箇中間轉換表,現在就三個表,讓兩個表與中間表形成一對多的關係,多對多就可以轉化為兩個一對多的關係了。