mybatis第四天

一、Mybatis中的延遲加載java

問題:在一對多中,當咱們有一個用戶,它有100個帳戶。
      在查詢用戶的時候,要不要把關聯的帳戶查出來?
      在查詢帳戶的時候,要不要把關聯的用戶查出來?
    
      在查詢用戶時,用戶下的帳戶信息應該是,何時使用,何時查詢的。
      在查詢帳戶時,帳戶的所屬用戶信息應該是隨着帳戶查詢時一塊兒查詢出來。

什麼是延遲加載
    在真正使用數據時才發起查詢,不用的時候不查詢。按需加載(懶加載)
什麼是當即加載
    無論用不用,只要一調用方法,立刻發起查詢。

在對應的四種表關係中:一對多,多對一,一對一,多對多
    一對多,多對多:一般狀況下咱們都是採用延遲加載。
    多對一,一對一:一般狀況下咱們都是採用當即加載。

二、Mybatis中的緩存sql

什麼是緩存
    存在於內存中的臨時數據。
爲何使用緩存
    減小和數據庫的交互次數,提升執行效率。
什麼樣的數據能使用緩存,什麼樣的數據不能使用
    適用於緩存:
        常常查詢而且不常常改變的。
        數據的正確與否對最終結果影響不大的。
    不適用於緩存:
        常常改變的數據
        數據的正確與否對最終結果影響很大的。
        例如:商品的庫存,銀行的匯率,股市的牌價。
Mybatis中的一級緩存和二級緩存
    一級緩存:
        它指的是Mybatis中SqlSession對象的緩存。
        當咱們執行查詢以後,查詢的結果會同時存入到SqlSession爲咱們提供一塊區域中。
        該區域的結構是一個Map。當咱們再次查詢一樣的數據,mybatis會先去sqlsession中
        查詢是否有,有的話直接拿出來用。
        當SqlSession對象消失時,mybatis的一級緩存也就消失了。
    
    二級緩存:
        它指的是Mybatis中SqlSessionFactory對象的緩存。由同一個SqlSessionFactory對象建立的SqlSession共享其緩存。
        二級緩存的使用步驟:
            第一步:讓Mybatis框架支持二級緩存(在SqlMapConfig.xml中配置)
            第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)
            第三步:讓當前的操做支持二級緩存(在select標籤中配置)

三、Mybatis中的註解開發數據庫

環境搭建
單表CRUD操做(代理Dao方式)
多表查詢操做
緩存的配置

1延遲加載的概念

爲何要延遲加載

延遲加載:緩存

就是在須要用到數據時才進行加載,不須要用到數據時就不加載數據。延遲加載也稱懶加載.session

好處:先從單表查詢,須要時再從關聯表去關聯查詢,大大提升數據庫性能,由於查詢單表要比關聯查詢多張錶速mybatis

度要快。app

壞處:框架

由於只有當須要用到數據時,纔會進行數據庫查詢,這樣在大批量數據查詢時,由於查詢工做也要消耗ide

時間,因此可能形成用戶等待時間變長,形成用戶體驗降低。性能

實現需求

需求:

查詢帳戶(Account)信息而且關聯查詢用戶(User)信息。若是先查詢帳戶(Account)信息便可知足要

求,當咱們須要查詢用戶(User)信息時再查詢用戶(User)信息。把對用戶(User)信息的按需去查詢就是延遲加

載。

mybatis第三天實現多表操做時,咱們使用了resultMap來實現一對一,一對多,多對多關係的操做。主要

是經過 association、collection 實現一對一及一對多映射。association、collection 具有延遲加載功

能。

經過assocation實現延遲加載

1.3.1 帳戶的持久層 DAO 接口

public interface IAccountDao {

/**

* 查詢全部帳戶,同時獲取帳戶的所屬用戶名稱以及它的地址信息

* @return

*/

List<Account> findAll();

}

1.3.2 帳戶的持久層映射文件

<?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.itheima.dao.IAccountDao">

<!-- 創建對應關係 -->

<resultMap type="account" id="accountMap">

<id column="id" property="id"/>

<result column="uid" property="uid"/>

<result column="money" property="money"/>

<!-- 它是用於指定從表方的引用實體屬性的 -->

<association property="user" javaType="user"

select="com.itheima.dao.IUserDao.findById"

column="uid">

</association>

</resultMap>

<select id="findAll" resultMap="accountMap">

select * from account

</select>

</mapper>

select: 填寫咱們要調用的 select 映射的 id

column : 填寫咱們要傳遞給 select 映射的參數

1.3.3 用戶的持久層接口和映射文件

* <p>Title: IUserDao</p>

* <p>Description: 用戶的業務層接口</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public interface IUserDao {

/**

* 根據 id 查詢

* @param userId

* @return

*/

User findById(Integer userId);

}

<?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.itheima.dao.IUserDao">

<!-- 根據 id 查詢 -->

<select id="findById" resultType="user" parameterType="int" >

select * from user where id = #{uid}

</select>

</mapper>

1.3.4 開啓 Mybatis 的延遲加載策略

image.png

1.3.5 編寫測試只查帳戶信息不查用戶信息

/**

*

* <p>Title: MybastisCRUDTest</p>

* <p>Description: 一對多帳戶的操做</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public class AccountTest {

private InputStream in ;

private SqlSessionFactory factory;

private SqlSession session;

private IAccountDao accountDao;

@Test

public void testFindAll() {

//6.執行操做

List<Account> accounts = accountDao.findAll();

}

@Before//在測試方法執行以前執行

public void init()throws Exception {

//1.讀取配置文件

in = Resources.getResourceAsStream("SqlMapConfig.xml");

//2.建立構建者對象

SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//3.建立 SqlSession 工廠對象

factory = builder.build(in);

//4.建立 SqlSession 對象

session = factory.openSession();

//5.建立 Dao 的代理對象

accountDao = session.getMapper(IAccountDao.class);

}

@After//在測試方法執行完成以後執行

public void destroy() throws Exception{

//7.釋放資源

session.close();
in.close();

}

}

測試結果以下:

咱們發現,由於本次只是將 Account對象查詢出來放入 List 集合中,並無涉及到 User對象,因此就沒有
image.png
image.png
發出 SQL 語句查詢帳戶所關聯的 User 對象的查詢。

經過collection實現延遲加載

一樣咱們也能夠在一對多關係配置的<collection>結點中配置延遲加載策略。

<collection>結點中也有 select 屬性,column 屬性。

需求:

完成加載用戶對象時,查詢該用戶所擁有的帳戶信息。

1.4.1 在 User 實體類中加入 List<Account>屬性

/**

*

* <p>Title: User</p>

* <p>Description: 用戶的實體類</p>

* <p>Company: http://www.itheima.com/ </p>

*/

public class User implements Serializable {

private Integer id;

private String username;

private Date birthday;

private String sex;

private String address;

private List<Account> accounts;

public List<Account> getAccounts() {

return accounts;

}

public void setAccounts(List<Account> accounts) {

this.accounts = accounts;

}

public Integer getId() {

return id;

}

public void setId(Integer id) {

this.id = id;

}

public String getUsername() {

return username;

}

public void setUsername(String username) {

this.username = username;

}

public Date getBirthday() {

return birthday;

}

public void setBirthday(Date birthday) {

this.birthday = birthday;

}

public String getSex() {

return sex;

}

public void setSex(String sex) {

this.sex = sex;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

@Override

public String toString() {

return "User [id=" + id + ", username=" + username + ", birthday=" + birthday

+ ", sex=" + sex + ", address="

+ address + "]";

}

}

1.4.2 編寫用戶和帳戶持久層接口的方法

/**

* 查詢全部用戶,同時獲取出每一個用戶下的全部帳戶信息傳智播客——專一於 Java、.Net 和 Php、網頁平面設計工程師的培訓

北京市昌平區建材城西路金燕龍辦公樓一層 電話:400-618-9090

* @return

*/

List<User> findAll();

/**

* 根據用戶 id 查詢帳戶信息

* @param uid

* @return

*/

List<Account> findByUid(Integer uid);

1.4.3 編寫用戶持久層映射配置

<resultMap type="user" id="userMap">

<id column="id" property="id"></id>

<result column="username" property="username"/>

<result column="address" property="address"/>

<result column="sex" property="sex"/>

<result column="birthday" property="birthday"/>

<!-- collection 是用於創建一對多中集合屬性的對應關係

ofType 用於指定集合元素的數據類型

select 是用於指定查詢帳戶的惟一標識(帳戶的 dao 全限定類名加上方法名稱)

column 是用於指定使用哪一個字段的值做爲條件查詢

-->

<collection property="accounts" ofType="account"

select="com.itheima.dao.IAccountDao.findByUid"

column="id">

</collection>

</resultMap>

<!-- 配置查詢全部操做 -->

<select id="findAll" resultMap="userMap">

select * from user

</select>

<collection>標籤:

主要用於加載關聯的集合對象

select 屬性:

用於指定查詢 account 列表的 sql 語句,因此填寫的是該 sql 映射的 id

column 屬性:

用於指定 select 屬性的 sql 語句的參數來源,上面的參數來自於 user 的 id 列,因此就寫成 id 這一

個字段名了

相關文章
相關標籤/搜索