1. 程式人生 > >mybatis中collection association優化使用及多引數傳遞

mybatis中collection association優化使用及多引數傳遞

mybatis都會用,但要優雅的用就不是那麼容易了

今天就簡單舉例,拋磚引玉,供大家探討

1.主表

CREATE TABLE `test_one` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

對應的java實體類如下(自動生成的程式碼,省略get set)

@JsonIgnoreProperties(ignoreUnknown = true, value = {"handler"})
public class TestOne implements Serializable {
    private static final long serialVersionUID = 1L;
    
    private Integer id;

    private String nickname;

    @JsonIgnoreProperties(ignoreUnknown = true, value = {"testOne"})
    private List<TestTwo> testTwos = new LinkedList<>();

注意:JsonIgnoreProperties請忽略,這是解決物件間迴圈依賴在json序列化時出錯的,不在本次內容中

 

2.從表

CREATE TABLE `test_two` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `nickname` varchar(255) NOT NULL,
  `one_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  KEY `test_two_ibfk_1` (`one_id`),
  CONSTRAINT `test_two_ibfk_1` FOREIGN KEY (`one_id`) REFERENCES `test_one` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

對應的java實體類如下(自動生成的程式碼,省略get set)

@JsonIgnoreProperties(ignoreUnknown = true, value = {"handler"})
public class TestTwo implements Serializable {
    private Integer id;

    private String nickname;

    private Integer oneId;

    @JsonIgnoreProperties(ignoreUnknown = true, value = {"testTwos"})
    private TestOne testOne;

注意:JsonIgnoreProperties請忽略,這是解決物件間迴圈依賴在json序列化時出錯的,不在本次內容中

 

細心的同學發現,兩個表用同名欄位,後續會告訴為什麼這麼舉例,而且這種情況專案中是非常常見的

3.TestOneMapper.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 3 <mapper namespace="info.zycloud.xcx.merchant.dao.TestOneMapper">
 4     <resultMap id="BaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne">
 5         <constructor>
 6             <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER"/>
 7             <arg column="nickname" javaType="java.lang.String" jdbcType="VARCHAR"/>
 8         </constructor>
 9     </resultMap>
10 
11  <!--一次查詢查出collection-->
    這裡會一次查詢就查詢出主物件和關聯的list物件, 查詢語句是一個join語句 12 <resultMap id="OnceQueryBaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne" extends="BaseResultMap"> 13 <collection property="testTwos" resultMap="info.zycloud.xcx.merchant.dao.TestTwoMapper.BaseResultMap" 14 columnPrefix="two_"/> 由於兩個表有同名欄位,所以需要做區分,這裡可以採用字首,就可以共用之前的ResultMap了 15 </resultMap> 16
17 <select id="onceQuery4Collection" resultMap="OnceQueryBaseResultMap"> 18 SELECT 19 one.*,  為什麼要用*,是為了防止主表字段變了,因為這裡是引用的生成的baseresultMap 20 two.id AS two_id, 21 two.nickname AS two_nickname, 22 two.one_id AS two_one_id 23 FROM 24 `test_one` one 25 LEFT JOIN test_two two ON one.id = two.one_id 26 </select> 27 28 <!-- 多次查詢查出collection--> 29 <resultMap id="MultipleQueryBaseResultMap" type="info.zycloud.xcx.merchant.model.TestOne" extends="BaseResultMap"> 30 <collection property="testTwos" column="{oneId=id,nickname=nickname}" 多引數時在column中用"{}"將引數包起來, =左側的為mapper中定義的param, =右側為主查詢的資料庫欄位名   31 select="info.zycloud.xcx.merchant.dao.TestTwoMapper.selectByOneId"/> 32 </resultMap> 33 34 <select id="multipleQuery4Collection" parameterType="java.lang.Integer" resultMap="MultipleQueryBaseResultMap"> 35 select 36 <include refid="Base_Column_List"/> 37 from test_one 38 where id = #{id,jdbcType=INTEGER} 39 </select> 40 41 </mapper>

對應的介面定義

1 public interface TestOneMapper {
2 
3     List<TestOne> onceQuery4Collection();
4 
5     TestOne multipleQuery4Collection(Integer id);
6 }

 

3.TestTwoMapper.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="info.zycloud.xcx.merchant.dao.TestTwoMapper">
    <resultMap id="BaseResultMap" type="info.zycloud.xcx.merchant.model.TestTwo">
        <constructor>
            <idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER"/>
            <arg column="nickname" javaType="java.lang.String" jdbcType="VARCHAR"/>
            <arg column="one_id" javaType="java.lang.Integer" jdbcType="INTEGER"/>
        </constructor>
    </resultMap>

    <select id="selectByOneId" resultMap="BaseResultMap">
        select
        <include refid="Base_Column_List"/>
        from test_two
        where one_id=#{oneId} and nickname =#{nickname}
    </select>
</mapper>
1 public interface TestTwoMapper {
2     List<TestTwo> selectByOneId(@Param("oneId") Integer oneId, @Param("nickname") String nickname);
3 }

 

解釋瞭然後我們執行看下效果:

onceQuery4Collection:

 

 

multipleQuery4Collection:

&n