via: https://item.congci.com/-/content/mybatis-lazyloadingenabled-yanchi-jiazai-peizhi
1. What is lazy loading
resultMap can implement advanced mapping (using association and collection to achieve one-to-one and one-to-many mapping), and association and collection have the function of lazy loading.
Requirement: If the order is inquired and the user information is related to the query. If we query the order information first, we can meet the requirements, and then we query the user information when we need to query the user information. The on-demand query for user information is lazy loading.
Lazy loading : Query from a single table first, and then from the associated table to associate the query when needed, which greatly improves database performance, because querying a single table is faster than querying multiple tables by association.
Second, use association to implement lazy loading
You need to define the statement corresponding to the two mapper methods.
1. Only query the order information
SELECT * FROM orders
Use association in the statement of the query order to lazy load (execute) the satatement below (associate query user information)
2. Related query user information
Use the user_id in the order information queried above to associate and query the user information
The core code of lazy loading of OrderMapper.xml:
Use the select in the association to specify the id of the statement to be executed by lazy loading.
<!-- Query order association query user, user information delay loading resultMap definition--> <resultMap type="com.mybatis.entity.Orders" id="ordersUserLazyLoading"> <!--Mapping configuration for order information--> <id column="id" property="id"/> <result column="user_id" property="userid"/> <result column="number" property="number"/> <result column="createtime" property="createTime"/> <result column="note" property="note"/> <!-- Implement lazy loading of user information select: Specifies the id of the statement that needs to be executed for lazy loading (a statement that queries user information based on user_id) column: The column associated with the user information query in the order information, which is user_id The SQL of the associated query is understood as: SELECT orders.*, (SELECT username FROM USER WHERE orders.user_id = user.id)username, (SELECT sex FROM USER WHERE orders.user_id = user.id)sex FROM orders --> <association property="user" javaType="com.mybatis.entity.User" select="findUserById" column="user_id"/> </resultMap> <!-- Query users based on Id for testing lazy loading --> <select id="findUserById" parameterType="int" resultType="com.mybatis.entity.User" > select * from t_user where id=#{id} </select> <!-- Query order related users, user information lazy loading--> <select id="findOrdersUserLazyLoading" resultMap="ordersUserLazyLoading"> select * from orders </select>
The code of OrderMapper.java:
public interface OrdersCustomMapper { /**Query orders, associate query users, users delay loading on demand*/ public List<Orders>findOrdersUserLazyLoading(); /** Query users according to Id (this method should be placed in the UserMapper class, and the test is convenient to put here first)*/ public User findUserById(int id); }
Test ideas and code:
1. Execute the above mapper method (findOrdersUserLazyLoading), and internally call findOrdersUserLazyLoading in OrdersMapperCustom to query orders information (single table).
2. In the program, traverse the List<Orders> queried in the previous step. When we call the getUser method in Orders, the lazy loading starts.
3. Delay loading and call the findUserbyId method to obtain user information.
// Query user association query user, user information lazy loading @Test public void TestFindOrdersUserLazyLoading() { SqlSession sqlSession = sqlSessionFactory.openSession(); // create proxy object OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class); // call mapper's method List<Orders> list = oc.findOrdersUserLazyLoading(); for(Orders order: list){ //Execute getUser() to query user information, here to implement lazy loading User user = order.getUser(); System.out.println(user); } sqlSession.close(); }
3. Delay loading the configuration in the mybatis core configuration file sqlMapConfig.xml
Mybatis does not enable lazy loading by default, and needs to be configured in SqlMapConfig.xml.
Configure in the mybatis core configuration file:
lazyLoadingEnabled、aggressiveLazyLoading
setting item |
describe |
allowance |
Defaults |
lazyLoadingEnabled |
Lazy loading is set globally. If set to 'false', all associated ones will be initialized loaded. |
true | false |
false |
aggressiveLazyLoading |
When set to 'true', lazy loaded objects may be fully loaded by any lazy property. Otherwise, each property is loaded on demand. |
true | false |
true |
<!-- Configuration of global parameters --> <settings> <!--Turn on the switch of lazy loading--> <setting name="lazyLoadingEnabled" value="true"/> <!--Change active loading to passive loading and on-demand loading--> <setting name="aggressiveLazyLoading" value="false"/> </settings>
Summary: Using the lazy loading method, first query simple sql (preferably a single table, or associated query), and then load other information of the associated query as needed.
MyBatis lazy loading lazy loading
Mainly reflected in the related query
1. Turn on delayed loading
You need to make two necessary configurations in the core configuration file
<configuration>
<settings>
<!– general switch for lazy loading –>
<setting name="lazyLoadingEnabled" value="true" />
<!– disable aggressive loading –>
<setting name="aggressiveLazyLoading" value="false " />
</settings>
Two, one-to-many
for Person
An SQL statement to query the basic information of Person
An SQL statement to query Person's order (lazy loaded statement)
1. In PersonMapper
<resultMap type="com.yutouxiuxiu.model.Person" id="selectOrderByPersonIdLazyRM" extends="personRM">
<!–
column - a field in the result set of the main SQL statement query is passed as a parameter to the sub SQL statement
select - sub SQL statement –>
<collection property="orderList" column="person_id" select="com.yutouxiuxiu.Orders.selectOrderByPersonId">
</collection>
</resultMap>
<select id="selectOrderByPersonIdLazy" parameterType="int" resultMap= "selectOrderByPersonIdLazyRM">
select * from person where person_id = #{personId}
</select>
2. In OrdersMapper
<!– lazy loaded sub-SQL statement in one-to-many case–>
<select id="selectOrderByPersonId" parameterType="int" resultMap="BaseResultMap">
select * from orders o where o.person_id = #{personId}
< /select>
@Test
public void selectOrderByPersonIdLazy() {
// Get session
SqlSession session = sqlSessionFactory.openSession();
try {
Person person = session.selectOne("com.yutouxiuxiu.Person.selectOrderByPersonIdLazy", 1);
// Send out query for person information SQL statement
System.out.println(person);
// Issue SQL statement to query order information
System.out.println(person.getOrderList());
} finally {
session.close();
}
}
Results of the:
2014-02-11 11:17:30,550 [main] DEBUG [com.yutouxiuxiu.Person.selectOrderByPersonIdLazy] – ooo Using Connection [com.mysql.jdbc.Connection@4e94ac10]
2014-02-11 11:17:30,551 [main] DEBUG [com.yutouxiuxiu.Person.selectOrderByPersonIdLazy] – ==> Preparing: select * from person where person_id = ?
2014-02-11 11:17:30,602 [main] DEBUG [com.yutouxiuxiu.Person.selectOrderByPersonIdLazy] – ==> Parameters: 1(Integer)
2014-02-11 11:17:30,702 [main] DEBUG [com.yutouxiuxiu.Orders.selectOrderByPersonId] – ooo Using Connection [com.mysql.jdbc.Connection@4e94ac10]
2014-02-11 11:17:30,702 [main] DEBUG [com.yutouxiuxiu.Orders.selectOrderByPersonId] – ==> Preparing: select * from orders o where o.person_id = ?
2014-02-11 11:17:30,703 [main] DEBUG [com.yutouxiuxiu.Orders.selectOrderByPersonId] – ==> Parameters: 1(Integer)
Person [id=1, name=赵四, birthday=Mon Feb 10 00:00:00 CST 2014, address=象牙山, salary=1000, orderList=[Orders [orderId=1, orderSum=1000.0, orderTime=Sun Feb 09 16:28:26 CST 2014, personId=1, detialList=null, person=null], Orders [orderId=2, orderSum=200.0, orderTime=Sun Feb 09 09:09:00 CST 2014, personId=1, detialList=null, person=null]], roleList=null]
[Orders [orderId=1, orderSum=1000.0, orderTime=Sun Feb 09 16:28:26 CST 2014, personId=1, detialList=null, person=null], Orders [orderId=2, orderSum=200.0, orderTime=Sun Feb 09 09:09:00 CST 2014, personId=1, detialList=null, person=null]]
Three, many to one
For Orders
An SQL statement to query the basic information of the Order
An SQL statement to query the owner of an Order (lazy loaded statement)
1. Order mapping file
<resultMap type="com.yutouxiuxiu.model.Orders" id="selectPersonByOrderIdLazyRM" extends="BaseResultMap">
<association property="person" column="person_id" select="com.yutouxiuxiu.Person.selectPersonByOrderId">
</association>
</resultMap>
<select id="selectPersonByOrderIdLazy" parameterType="int" resultMap="selectPersonByOrderIdLazyRM">
select * from orders where order_id = #{orderId}
</select>
2.Person's mapping file
<select id="selectPersonByOrderId">
select * from person where person_id = #{personId}
</select>
@Test
public void selectPersonByOrderIdLazy() {
// Get session
SqlSession session = sqlSessionFactory.openSession();
try {
Orders orders = session.selectOne("com.yutouxiuxiu.Orders.selectPersonByOrderIdLazy", 1);
// Send out the person information query SQL statement
System.out.println(orders);
// Issue SQL statement to query order information
System.out.println(orders.getPerson());
} finally {
session.close();
}
}