Mybatis deferred loading policy

1 delayed loading concept

Delayed loading:
Data is loaded only when it is needed. Data is not loaded when it is not needed. Lazy loading is also called lazy loading.
Benefits: query from a single table first, and then associate the query from the associated table when necessary, which greatly improves the database performance, because querying a single table is faster than associating multiple tables.
Disadvantages: database query can only be performed when data is needed. In this way, when large quantities of data are queried, because the query also consumes time, the user waiting time may become longer and the user experience may be reduced.

Requirement: query account information and associated query user information. If the requirements can be met by querying the account information first, we can query the user information when we need to query the user information. The on-demand query of user information is delayed loading.

2 realize delayed loading

2.1 delayed loading using assocation:

Demand: query account information and user information at the same time.

Persistent layer DAO interface of account

/**
* 
* <p>Title: IAccountDao</p>
* <p>Description: Persistent layer interface of account</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public interface IAccountDao {
/**
* Query all accounts, and obtain the user name and address information of the account
* @return
*/
List<Account> findAll();
}

Persistent layer mapping file of account

<?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">
<!-- Establish correspondence --> <resultMap type="account" id="accountMap"> <id column="aid" property="id"/>
<result column="uid" property="uid"/>
<result column="money" property="money"/>
<!-- It is used to specify the attribute of the referenced entity from the table side --> <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: fill in the id of the select map we want to call
column: fill in the parameters we want to pass to the select map

User's persistence layer interface and mapping file

/**
* <p>Title: IUserDao</p>
* <p>Description: User's business layer interface</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public interface IUserDao {
/**
* Query by 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">
<!-- according to id query --> <select id="findById" resultType="user" parameterType="int" >
select * from user where id = #{uid}
</select>
</mapper>

To enable the delayed loading policy of Mybatis, we need to use the configuration file sqlmapconfig Add a deferred load configuration to the XML file.

<!-- Enable support for delayed loading -->
<settings> <setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>

Write the test, only check the account information, not the user information.

/**
* 
* <p>Title: MybastisCRUDTest</p>
* <p>Description: One to many account operation</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. Perform the operation
List<Account> accounts = accountDao.findAll();
}
@Before//Execute before test method execution
public void init()throws Exception {
//1. Read the configuration file
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. Create builder object
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. Create SqlSession factory object
factory = builder.build(in);
//4. Create SqlSession object
session = factory.openSession();
//5. Create Dao's proxy object
accountDao = session.getMapper(IAccountDao.class);
}
@After//Execute after the test method execution is completed
public void destroy() throws Exception{
//7. Release resources
session.close();
in.close();
} }

Only the Account object is queried and put into the List collection, and the User object is not involved, so there is no
Issue a SQL statement to query the User object associated with the account. The test results are as follows:

2.2 delayed loading using Collection

Similarly, we can also configure the delayed loading strategy in the nodes with one to many relationship configuration. The node also has a select attribute and a column attribute. Requirement: query the account information owned by the user when loading the user object.
Add the List attribute to the User entity class

/**
* 
* <p>Title: User</p>
* <p>Description: User's entity class</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 + "]"; } }

Method of compiling user and account persistence layer interface

/**
* Query all users and get all account information under each user at the same time
* * @return
*/
List<User> findAll();
/**
* Query account information according to user id
* @param uid
* @return
*/
List<Account> findByUid(Integer uid);

Write user persistence layer mapping configuration

<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 It is used to establish the corresponding relationship of set attributes in one to many
ofType Specifies the data type of the collection element
select It is used to specify the unique ID of the query account (the name of the account) dao Fully qualified class name plus method name)
column Is used to specify which field value to use as the query criteria
--> <collection property="accounts" ofType="account"
select="com.itheima.dao.IAccountDao.findByUid"
column="id">
</collection>
</resultMap>
<!-- Configure query all operations --> <select id="findAll" resultMap="userMap">
select * from user
</select>

Label: mainly used to load associated collection objects
select attribute: used to specify the sql statement to query the account list, so the id of the sql mapping is filled in
Column attribute: used to specify the parameter source of the sql statement of the select attribute. The above parameter comes from the id column of the user, so it is written as the field name of id

Write account persistence layer mapping configuration

<!-- According to user id Query account information --> <select id="findByUid" resultType="account" parameterType="int">
select * from account where uid = #{uid}
</select>

The test only loads user information

/**
* 
* <p>Title: MybastisCRUDTest</p>
* <p>Description: One to many operation</p>
* <p>Company: http://www.itheima.com/ </p>
*/
public class UserTest {
private InputStream in ;
private SqlSessionFactory factory;
private SqlSession session;
private IUserDao userDao;
@Test
public void testFindAll() {
//6. Perform the operation
List<User> users = userDao.findAll();
}
@Before//Execute before test method execution
public void init()throws Exception {
//1. Read the configuration file
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2. Create builder object
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3. Create SqlSession factory object
factory = builder.build(in);
//4. Create SqlSession object
session = factory.openSession();
//5. Create Dao's proxy object
userDao = session.getMapper(IUserDao.class);
}
@After//Execute after the test method execution is completed
public void destroy() throws Exception{
session.commit();
//7. Release resources
session.close();
in.close();
} }

The test result does not load the Account information, as shown below:

Keywords: Java Database MySQL Mybatis

Added by sheen4him on Thu, 30 Dec 2021 12:24:06 +0200