1. 程式人生 > 資料庫 >Day135.SQL對映檔案②聯合查詢&分步查詢 -MyBatis

Day135.SQL對映檔案②聯合查詢&分步查詢 -MyBatis

SQL對映檔案②聯合查詢&分步查詢

一、聯合查詢【推薦】

1、級聯查詢

  • sql語句
SELECT k.id,k.`keyname`,k.`lockId`,l.`id` lid,l.`lockName` 
FROM t_key k 
LEFT JOIN t_lock l 
ON k.`lockId`=l.`id`
WHERE k.`id`=1

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-7RSmPbro-1608180164241)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217112812244.png)]

  • bean物件
public class Lock {
    private Integer id;//鎖編號
    private String LockName;//鎖名
    //省略get/set/toString/構造器
}
public class Key {
    private Integer id;//鑰匙編號
    private String keyName;//鑰匙名
    private Lock lock;//當前鑰匙能開哪把鎖
    //省略get/set/toString/構造器
}
  • keyDao
public interface keyDao {
//將鑰匙和鎖資訊一起查出
    public Key getKeyById(Integer id);
}
  • mybatis_config.xml
<mappers>
    <mapper resource="keyDao.xml"/>
    <mapper resource="EmployeeDao.xml"/>
</mappers>
  • keyDao.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="com.achang.dao.keyDao">
    <select id="getKeyById" resultMap="myKey">
        select k.id,k.`keyname`,k.`lockId`,l.`id` lid,l.`lockName` from t_key k left join t_lock l on k.`lockId`=l.`id`where k.`id`=1
    </select>
    <!--自定義封裝規則-->
    <resultMap id="myKey" type="com.achang.bean.Key">
        <id column="id" property="id"/>
        <result column="keyname" property="keyName"/>
        <!--級聯配置查詢-->
        <result column="lid" property="lock.id"/>
        <result column="lock.LockName" property="lockName"/>
    </resultMap>
</mapper>
  • test
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //keyDao測試
    @Test
    public void test6(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Key keyById = mapper.getKeyById(2);
        System.out.println(keyById);
        //Key{id=1, keyName='1號鑰匙', lock=Lock{id=1, LockName='null'}}
    }
}

2、聯合查詢association

下面的其他配置同上

用來自定義封裝規則中,再次套娃封裝bean物件屬性裡面的物件,若屬性裡面物件的屬性還是物件可繼續套娃封裝

  • keyDao.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="com.achang.dao.keyDao">
    <select id="getKeyById" resultMap="myKey">
        select k.id,k.`keyname`,k.`lockId`,l.`id` lid,l.`lockName` from t_key k left join t_lock l on k.`lockId`=l.`id`where k.`id`=#{id}
    </select>
    <resultMap id="myKey" type="com.achang.bean.Key">
        <id column="id" property="id"/>
        <result column="keyname" property="keyName"/>
        <!--若這個物件的屬性是一個物件,自定義規則;可使用association標籤定義聯合查詢

         private Integer id;//鑰匙編號
         private String keyName;//鑰匙名
         private Lock lock;//當前鑰匙能開哪把鎖

                property屬性:指定要聯合查詢的物件
                javaType屬性:指定這個javabean屬性的型別的全類名
        -->

        <association property="lock" javaType="com.achang.bean.Lock">
            <!--定義lock屬性對於這個Lock物件如何封裝
                property屬性:指定對於javabean物件的屬性
                column屬性:指定資料庫查詢結果的欄位名
            -->
            <id property="id" column="id"></id>
            <result property="LockName" column="lockName"></result>
        </association>
    </resultMap>
</mapper>
  • test
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //keyDao測試
    @Test
    public void test6(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Key keyById = mapper.getKeyById(2);
        System.out.println(keyById);
        //Key{id=1, keyName='1號鑰匙', lock=Lock{id=1, LockName='1號鎖'}}
    }
}

3、Collection查詢

  • sql
SELECT k.id,k.`keyname`,k.`lockId`,l.`id` lid,l.`lockName` 
FROM t_key k 
LEFT JOIN t_lock l 
ON k.`lockId`=l.`id`
WHERE k.`id`=3

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-z4sFOegD-1608180164244)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123100879.png)]

  • bean物件
public class Lock {
    private Integer id;//鎖編號
    private String LockName;//鎖名
    private List<Key> keys//很多把鑰匙可以開這把鎖
    //省略get/set/toString/構造器
}
public class Key {
    private Integer id;//鑰匙編號
    private String keyName;//鑰匙名
    private Lock lock;//當前鑰匙能開哪把鎖
    //省略get/set/toString/構造器
}
  • LockDao.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="com.achang.dao.LockDao">
    <select id="getLockById" resultMap="myLock">
        select k.kid,k.`keyname`,k.`lockId`,l.`id` id,l.`lockName` from t_key k left join t_lock l on k.`lockId`=l.`id`where k.`id`=#{id}
    </select>
    
    <resultMap id="myLock" type="com.achang.bean.Lock">
        <id column="id" property="id"/>
        <result column="keyname" property="keyName"/>
        <!-- 
		collection:定義集合元素的封裝
			property:指定bean物件屬性中哪個集合物件
			ofType:指定bean物件屬性的物件集合裡面元素的型別
		-->
        <collection property="keys" ofType="com.achang.bean.Key">
            <id property="id" column="kid"></id>
            <result property="keyName" column="keyname"></result>
        </collection>
    </resultMap>
    
</mapper>
  • test
public class EmployeeDaoTest {
    SqlSessionFactory factory;
    @Before
    public void initSqlSessionFactory() throws IOException {
        String resource = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        factory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //LockDao測試
    @Test
    public void test7(){
        SqlSession sqlSession = factory.openSession();
        keyDao mapper = sqlSession.getMapper(keyDao.class);
        Lock lockById = mapper.getLockById(3);
        System.out.println(keyById);
        //lock物件為null是因為沒自定義配置association;需要則可以在resultMap中繼續配置association來繼續套娃
        //Key{id=3, keyName='303號鑰匙1', lock=null}
       // Key{id=4, keyName='303號鑰匙2', lock=null}
       // Key{id=5, keyName='303號鑰匙3', lock=null}
    }
}

二、分步查詢【不推薦】

雖然sql簡單,但是會有大量效能浪費,雖然可以用過設定來減少效能浪費,但還是不推薦使用!!!

1、association-分段查詢

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-TF0YZ6yG-1608180164247)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123425360.png)]

select:呼叫目標的方法查詢當前屬性的值【方法全類名】

column:將指定欄位值傳入select屬性呼叫的目標方法中

2、association-分段查詢&延遲載入

開啟延遲載入和屬性按需載入

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-IAq4pypy-1608180164250)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123458781.png)]

  • 舊版本的MyBatis需要額外的支援包

–asm-3.3.1.jar

–cglib-2.2.2.jar

3、Collection-集合型別&巢狀結果集

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-ZR0h1DyK-1608180164253)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123543886.png)]

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-cicfGWWO-1608180164255)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123546507.png)]

4、Collection-分步查詢&延遲載入

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-IPuT2ekF-1608180164256)(C:\Users\PePe\AppData\Roaming\Typora\typora-user-images\image-20201217123600895.png)]