MyBatis高级结果映射(一对一、一对多、多对多的映射),延迟加载,查询缓存(一级缓存),二级缓存的学习记录;
1、学习中所使用到的例子,数据库基础分析
2、高级结果映射
3、延迟加载
4、一级缓存
5、二级缓存
2、高级结果映射
resultType与resultMap:
- resultType来进行结果映射,数据库中查询几条记录,那么在resultType就会映射成几条记录;resultType映射是一个平铺式的映射;
- resultMap比较繁琐一些,是一种层级式映射,在企业中如果没有特殊要求,一般使用的都是resultType来完成一对一的映射;
- resultType实现查询机制,需要自定义pojo,pojo属性名和sql查询的列名是一致的;企业开发中的resultType简单方便便于使用
- resultMap可以将sql查询结果信息中的部分属性映射到一个pojo中;需要的是映射配置;并且如果有查询到其他表中的内容首先要进行的是实体类关系的分析,以及映射关系的分析,并且分清一对一,一对多,多对多的关系;
下面的例子中会使用上述的购物车的数据库结构创建表,并且生成实体po类,进行操作(代码只会贴出关键代码块);
例子1:订单信息与用户信息
使用实体PO类:
OrderCustom.Java
<code class="language-java hljs has-numbering"><span class="hljs-keyword">package</span> com.mybatis.demo.po; <span class="hljs-javadoc">/** * 继承一个需要信息最多的类 *<span class="hljs-javadoctag"> @author</span> YQ * */</span> <span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">OrderCustom</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">Orders</span> {</span> <span class="hljs-comment">// 用户名称</span> <span class="hljs-keyword">private</span> String username; <span class="hljs-comment">// 用户地址</span> <span class="hljs-keyword">private</span> String address; <span class="hljs-keyword">public</span> String <span class="hljs-title">getUsername</span>() { <span class="hljs-keyword">return</span> username; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setUsername</span>(String username) { <span class="hljs-keyword">this</span>.username = username; } <span class="hljs-keyword">public</span> String <span class="hljs-title">getAddress</span>() { <span class="hljs-keyword">return</span> address; } <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setAddress</span>(String address) { <span class="hljs-keyword">this</span>.address = address; } }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul>
resultType的使用
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 需要使用resultType实现订单查询,关联用户信息 --></span> <span class="hljs-comment"><!-- resultType必须要包含所有的查询结果类 自定义POJO类 --></span> <span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findOrderUserList"</span> <span class="hljs-attribute">resultType</span>=<span class="hljs-value">"com.mybatis.demo.po.OrderCustom"</span>></span> SELECT orders.* , user.username , user.address FROM orders , USER WHERE orders.user_id = user.id <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
使用resultMap完成例子一中的需求:
<code class="language-java hljs has-numbering"><!-- 定义订单信息与用户信息的resultMap --> <!-- 将结果做一个映射 --> <resultMap type=<span class="hljs-string">"orders"</span> id=<span class="hljs-string">"ordersUserResultMap"</span>> <!-- id:订单信息的唯一约束 如果存在多个字段决定唯一记录,id标签需要定义多个 --> <id column=<span class="hljs-string">"id"</span> property=<span class="hljs-string">"id"</span>/> <result column=<span class="hljs-string">"order_number"</span> property=<span class="hljs-string">"order_number"</span>/> <result column=<span class="hljs-string">"user_id"</span> property=<span class="hljs-string">"user_id"</span>/> <!-- 配置用户映射信息 将sql查询的用户信息映射到orders中的user属性中 association:用于单个关联对象的映射 property:将关联信息映射到orders的哪一个属性 javaType:映射属性的类型 --> <association property=<span class="hljs-string">"user"</span> javaType=<span class="hljs-string">"com.mybatis.demo.po.User"</span>> <!-- id:关联用户信息的唯一约束 property:id指定的列映射到关联com.mybatis.demo.po.User --> <id column=<span class="hljs-string">"user_id"</span> property=<span class="hljs-string">"id"</span>/> <result column=<span class="hljs-string">"username"</span> property=<span class="hljs-string">"username"</span>/> <result column=<span class="hljs-string">"address"</span> property=<span class="hljs-string">"address"</span>/> </association> </resultMap></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li></ul>
使用resultMap
<code class="language-xml hljs has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findOrderUserListResultMap"</span> <span class="hljs-attribute">resultMap</span>=<span class="hljs-value">"ordersUserResultMap"</span>></span> SELECT orders.* , user.username , user.address FROM orders , USER WHERE orders.user_id = user.id <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li></ul>
例子2:订单与订单明细查询
resultMap定义如下:
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 定义订单以及订单明细的resultMap 如果是跨namespace就可以在前面加上namespace --></span> <span class="hljs-tag"><<span class="hljs-title">resultMap</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"orders"</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"ordersUserDetailResultMap"</span> <span class="hljs-attribute">extends</span>=<span class="hljs-value">"ordersUserResultMap"</span>></span> <span class="hljs-comment"><!-- 订单以及用户信息,继承于ordersUserResultMap --></span> <span class="hljs-comment"><!-- 映射订单明细信息 colllection:映射集合对象(表示的是多的关系) property:将明细信息映射到哪个集合属性中 ofType:集合中对象的类型 --></span> <span class="hljs-tag"><<span class="hljs-title">collection</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"orderdetails"</span> <span class="hljs-attribute">ofType</span>=<span class="hljs-value">"com.mybatis.demo.po.Orderdetail"</span>></span> <span class="hljs-comment"><!-- id:订单明细的唯一约束 --></span> <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"orderdetail_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_num"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_num"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_price"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_price"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">collection</span>></span> <span class="hljs-tag"></<span class="hljs-title">resultMap</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li></ul>
在Orders类中需要定义一个订单明细的集合对象:
<code class="language-java hljs has-numbering"> <span class="hljs-comment">//订单明细,需要给出该对象的get与set方法</span> <span class="hljs-keyword">private</span> List<Orderdetail> orderdetails;</code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
使用定义的resultMap
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 查询用户与订单明细信息 --></span> <span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findOrdersUserDetailList"</span> <span class="hljs-attribute">resultMap</span>=<span class="hljs-value">"ordersUserDetailResultMap"</span>></span> SELECT orders.*, user.username, user.address, orderdetail.item_id, orderdetail.item_num, orderdetail.item_price FROM orders, USER, orderdetail WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li></ul>
例子3:订单明细与商品信息
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 定义订单明细以及商品信息 --></span> <span class="hljs-tag"><<span class="hljs-title">resultMap</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"orders"</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"ordersUserDetailItemResultMap"</span> <span class="hljs-attribute">extends</span>=<span class="hljs-value">"ordersUserResultMap"</span>></span> <span class="hljs-comment"><!-- 订单与用户信息,继承自ordersUserResultMap --></span> <span class="hljs-comment"><!-- 映射订单信息collection:映射集合对象property;将明细信息映射到集合属性中! ofType:集合对象的类型 --></span> <span class="hljs-tag"><<span class="hljs-title">collection</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"orderdetails"</span> <span class="hljs-attribute">ofType</span>=<span class="hljs-value">"com.mybatis.demo.po.Orderdetail"</span>></span> <span class="hljs-comment"><!-- id:订单明细的唯一约束 --></span> <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"orderdetail_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_num"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_num"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_price"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_price"</span>/></span> <span class="hljs-comment"><!-- 映射商品信息 映射商品属性 --></span> <span class="hljs-tag"><<span class="hljs-title">association</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"items"</span> <span class="hljs-attribute">javaType</span>=<span class="hljs-value">"com.mybatis.demo.po.Items"</span>></span> <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_name"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_name"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_price"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_price"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"item_detail"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"item_detail"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">association</span>></span> <span class="hljs-tag"></<span class="hljs-title">collection</span>></span> <span class="hljs-tag"></<span class="hljs-title">resultMap</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li><li>27</li><li>28</li><li>29</li><li>30</li></ul>
使用上述定义的resultMap
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 查询订单以及订单明细信息以及商品信息 --></span> <span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findOrderUserDetailItemList"</span> <span class="hljs-attribute">resultMap</span>=<span class="hljs-value">"ordersUserDetailItemResultMap"</span>></span> SELECT orders.*, user.username, user.address, orderdetail.id orderdetail_id, orderdetail.item_id, orderdetail.item_num, orderdetail.item_price , items.item_detail, items.item_name, items.item_price FROM orders, USER, orderdetail, items WHERE orders.user_id = user.id AND orders.id = orderdetail.orders_id AND orderdetail.item_id = items.id <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li><li>22</li><li>23</li><li>24</li><li>25</li><li>26</li></ul>
PO类中的定义:
在OrderDerail类中需要添加以下对象:
<code class="language-java hljs has-numbering"> <span class="hljs-comment">//商品信息</span> <span class="hljs-keyword">private</span> Items items;<span class="hljs-comment">//明细对应的商品信息 </span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
3、延迟加载
- 延迟加载对于上述例子中的需求:首次只查询订单信息,当需要关联查询用户信息时,再查询用户信息。
- 延迟加载相对于之前学习的hibernate的概念就是懒加载,先去查询主表信息,如果用到从表的数据的话,再去查询从表的信息。Mybatis中resultMap可以实现延迟加载
在sqlMapConfig.xml中进行配置与开启:
<code class="language-xml hljs has-numbering"> <span class="hljs-comment"><!-- 全局参数的配置,开启延迟加载 --></span> <span class="hljs-tag"><<span class="hljs-title">settings</span>></span> <span class="hljs-tag"><<span class="hljs-title">setting</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"lazyLoadingEnabled"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"true"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">setting</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"aggressiveLazyLoading"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"false"</span>/></span> <span class="hljs-comment"><!-- 开启二级缓存总开关 --></span> <span class="hljs-tag"><<span class="hljs-title">setting</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"cacheEnabled"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"true"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">settings</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>
在mapper中使用延迟加载:
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 订单与用户的resultMap,实现延迟加载 --></span> <span class="hljs-tag"><<span class="hljs-title">resultMap</span> <span class="hljs-attribute">type</span>=<span class="hljs-value">"orders"</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"ordersUserResultMapLazy"</span>></span> <span class="hljs-comment"><!-- 配置订单信息的映射 --></span> <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"user_id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"user_id"</span>/></span> <span class="hljs-tag"><<span class="hljs-title">result</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"order_number"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"order_number"</span>/></span> <span class="hljs-comment"><!-- 配置延迟加载,加载用户信息 select:延迟加载时候调用的statement colum:将哪一列的值传到延迟加载的statement中 --></span> <span class="hljs-tag"><<span class="hljs-title">association</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"user"</span> <span class="hljs-attribute">javaType</span>=<span class="hljs-value">"com.mybatis.demo.po.User"</span> <span class="hljs-attribute">select</span>=<span class="hljs-value">"com.mybatis.demo.mapper.UserMapper.findUserById"</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"user_id"</span>></span> <span class="hljs-tag"><<span class="hljs-title">id</span> <span class="hljs-attribute">column</span>=<span class="hljs-value">"id"</span> <span class="hljs-attribute">property</span>=<span class="hljs-value">"id"</span>/></span> <span class="hljs-tag"></<span class="hljs-title">association</span>></span> <span class="hljs-tag"></<span class="hljs-title">resultMap</span>></span> <span class="hljs-comment"><!-- 订单信息查询,需要使用延迟加载 --></span> <span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findOrderList"</span> <span class="hljs-attribute">resultMap</span>=<span class="hljs-value">"ordersUserResultMapLazy"</span>></span> select * from orders <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>
调试效果如下:
首先调试测试方法:
<code class="language-java hljs has-numbering"><span class="hljs-comment">//测试延迟加载</span> <span class="hljs-annotation">@Test</span> <span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">findOrderList</span>() <span class="hljs-keyword">throws</span> Exception { SqlSession session = sqlSessionFactory.openSession(); OrdersMapperCustom orderMapperCustom = session.getMapper(OrdersMapperCustom.class); List<Orders> list = orderMapperCustom.findOrderList(); <span class="hljs-keyword">for</span> (Orders orders : list) { <span class="hljs-annotation">@SuppressWarnings</span>(<span class="hljs-string">"unused"</span>) <span class="hljs-keyword">int</span> order_id = orders.getId(); <span class="hljs-comment">//去订单ID;断点1</span> <span class="hljs-annotation">@SuppressWarnings</span>(<span class="hljs-string">"unused"</span>) User user = orders.getUser(); <span class="hljs-comment">//查询用户信息;断点2</span> } session.close(); }</code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li></ul>
4、一级缓存
首先先看一下一级缓存与二级缓存在mybatis中的关系:
- 一级缓存是SqlSession级别的缓存。在操作数据库时需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
- 二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。
一级缓存原理:
第一次查询id为X的用户,此时先去一级缓存查找,如果查找不到,则去数据库查询,把查询后的 结果存储到一级缓存中;
第二次查询id为X的用户,此时先去一级缓存查找,如果查找到,则直接从一级缓存中把数据取出,不去查询数据库;
只要中间发生增删改操作,那么一级缓存就清空;
5、二级缓存
- 原理
- 第一次查询id为1 的用户,此时先去二级缓存查找,如果查找不到,则去数据库查询,把查询后的 结果存储到二级缓存中。
- 第二次查询id为1 的用户,此时先去二级缓存查找,如果查找到,则直接从二级缓存中把数据取出,不去查询数据库。
- 只要中间发生增删改操作,那么二级缓存就清空。
- 二级缓存默认是不开启的。
步骤一:开启二级缓存:
在sqlMapConfig.xml中开启二级缓存总开关:
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 开启二级缓存总开关 --></span> <span class="hljs-tag"><<span class="hljs-title">setting</span> <span class="hljs-attribute">name</span>=<span class="hljs-value">"cacheEnabled"</span> <span class="hljs-attribute">value</span>=<span class="hljs-value">"true"</span>/></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
步骤二:开启二级缓存:
<code class="language-xml hljs has-numbering"><span class="hljs-comment"><!-- 开启二级缓存 --></span> <span class="hljs-tag"><<span class="hljs-title">cache</span>></span><span class="hljs-tag"></<span class="hljs-title">cache</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li></ul>
步骤三:对象序列化(必须)
implements Serializable
步骤四:测试即可
如何刷新缓存:
- 在映射文件的statement中设置flushCache=true可以刷新当前的二级缓存,默认情况下如果是select语句,那么flushCache是false。如果是insert、update、delete语句,那么flushCache是true;
- 如果查询语句设置成true,那么每次查询都是去数据库查询,即意味着该查询的二级缓存失效;
- 如果查询语句设置成false,即使用二级缓存,那么如果在数据库中修改了数据,而缓存数据还是原来的,这个时候就会出现脏读。
禁用缓存:
<code class="language-xml hljs has-numbering"><span class="hljs-tag"><<span class="hljs-title">select</span> <span class="hljs-attribute">id</span>=<span class="hljs-value">"findUserById"</span> <span class="hljs-attribute">parameterType</span>=<span class="hljs-value">"int"</span> <span class="hljs-attribute">resultType</span>=<span class="hljs-value">"user"</span> <span class="hljs-attribute">useCache</span>=<span class="hljs-value">"false"</span>></span> SELECT * FROM USER WHERE id = #{id} <span class="hljs-tag"></<span class="hljs-title">select</span>></span></code><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul><ul style="" class="pre-numbering"><li>1</li><li>2</li><li>3</li></ul>