MySQL多表查询

    网上好多Mybatis的映射都有点老了,我自己查的时候发现多数都有问题或者描述不清,所以我参考Mybatis官网文档实现下多表联合查询。

    

   2个表的左连接(A LEFT JOIN B 意思就是以A为主表连接B表,查出A表存在的行,如果该行B表不存在则B表查出数据为null)

    Mybtis的XML配置如下:

    customer_base_info(会员基本信息表)关联brand_integral_account(会员积分表)

     这个映射方法是用Mybatis官网上的方法,这种的方法关联查询可以避免N+1查询问题。

<span style="font-family:Microsoft YaHei;font-size:14px;"><!-- 查询会员基本信息 -->
  <resultMap id="MemberInfoResultMap" type="cn.wonhigh.retail.crm.common.model.CustomerBaseInfo" >
    <id column="id" property="id" jdbcType="CHAR" />
    <result column="no" property="no" jdbcType="VARCHAR" />
    <result column="real_name" property="realName" jdbcType="VARCHAR" />
    <result column="gender" property="gender" jdbcType="TINYINT" />
    <result column="sex" property="sex" jdbcType="VARCHAR" />
    <result column="age" property="age" jdbcType="VARCHAR" />
    <result column="birth_day" property="birthDay" jdbcType="DATE" />
    <result column="identity_card" property="identityCard" jdbcType="VARCHAR" />
    <result column="mob" property="mob" jdbcType="VARCHAR" />
    <result column="referral_id" property="referralId" jdbcType="BIGINT" />  
    <!-- 关联brand_integral_account表    
    Column:The column name from the database, or the aliased column label that holds the value that will be passed to the nested statement as an input parameter.  
    property:会从model获取数据
    -->  
        <association  property="brandIntegralAccount"  resultMap="BrandIntegralAccountResult"/>  
  </resultMap>
  
  <resultMap id="BrandIntegralAccountResult" type="cn.wonhigh.retail.crm.common.model.BrandIntegralAccount" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="customer_id" property="customerId" jdbcType="BIGINT" />
    <result column="brand_no" property="brandNo" jdbcType="VARCHAR" />
    <result column="account_no" property="accountNo" jdbcType="VARCHAR" />
    <result column="level_id" property="levelId" jdbcType="BIGINT" />
    <result column="accumulated_score" property="accumulatedScore" jdbcType="BIGINT" />
    <result column="remain_score" property="remainScore" jdbcType="BIGINT" />
    <result column="status" property="status" jdbcType="TINYINT" />
    <result column="join_date" property="joinDate" jdbcType="TIMESTAMP" />
    <result column="join_shop_no" property="joinShopNo" jdbcType="VARCHAR" />
    <result column="join_shop_name" property="joinShopName" jdbcType="VARCHAR" />
  </resultMap>
</span>
   

<span style="font-family:Microsoft YaHei;font-size:14px;"> <association  property="brandIntegralAccount"  resultMap="BrandIntegralAccountResult"/>  </span>
解释下这句话

    association这个是一对一映射的语法结构, 但是其实这两个表是一对多的关系, 正如我上一篇博客所说的Mybatis是面向结果的,很灵活,因为这个查询的结果被SQL(下面会提供)语句限制为一对一的结果, 所以映射的时候只要一对一映射就行了, 和表间关系无关。 


    property这个对应于你在Model层的属性,比如这个就是在CustomerBaseInfo.java这个Model里面写了

<span style="font-family:Microsoft YaHei;font-size:14px;">private BrandIntegralAccount brandIntegralAccount;
public BrandIntegralAccount getBrandIntegralAccount () {
    return brandIntegralAccount;
}
public void set BrandIntegralAccount(BrandIntegralAccount brandIntegralAccount) {
   this.brandIntegralAccount = BrandIntegralAccount;
}</span>
这样在ResultSet映射的时候,关联的数据就注入到这个属性里面了。


    resultMap=“BrandIntegralAccountResult”这个属性表示关联对象里面映射了哪写字段,“BrandIntegralAccountResult”就对应到了下面的那个resultMap   id = “BrandIntegralAccountResult” 下的所有字段。


其他的属性:column对应你数据库表里面的字段名,property对应你Model里面定义的属性名,这样通过以上的配置,一对一的Mybatis就配置完了。



最后一步,也是最关键的一步,MySQL的编写:

<select id="selectMemberList" resultMap="MemberInfoResultMap">  
        SELECT 
        customer_base_info.id,
        customer_base_info.real_name,
        customer_base_info.no,
        customer_base_info.mob,
        CASE gender WHEN 0 THEN '男' ELSE '女' END AS sex,
        customer_base_info.birth_day,
        brand_integral_account.status,
        brand_integral_account.brand_no,
        brand_integral_account.join_date,
        brand_integral_account.join_shop_name,
        (year(now())-year(customer_base_info.birth_day)-1) + ( DATE_FORMAT(customer_base_info.birth_day, '%m%d') <= DATE_FORMAT(NOW(), '%m%d') ) as age
        FROM
        customer_base_info
        LEFT JOIN
        brand_integral_account
        ON
        brand_integral_account.customer_id=customer_base_info.id
        WHERE 1=1
	    <include refid="memberlistcondition" />
        <if test="orderByField != null and ''!=orderByField" >
          order by ${orderByField}
          <if test="orderByField" >
            ${orderBy}
          </if>
        </if>
        LIMIT #{page.startRowNum} ,#{page.pageSize}
    </select>  
id是你在DAO层或者说DAL层调用时用到的方法名,resultMap就是在上面配置的关联映射。

这句话就将生日转换成年龄用的:

(year(now())-year(customer_base_info.birth_day)-1) + ( DATE_FORMAT(customer_base_info.birth_day, '%m%d') <= DATE_FORMAT(NOW(), '%m%d') ) as age

注意上面这句话的<(小于号)在xml里面得做个转换如下表:


                     &lt;                                 

                     <

                     小于号                                           

                     &gt;

                     >                                      

                     大于号

                     &amp;

                     &

                     和

                     &apos;

                     ’

                     单引号

                     &quot;

                     "

                     双引号




根据两个表的customer_id和id关联的结果如下:

MySQL多表查询_第1张图片



你可能感兴趣的:(mysql,数据库,mybatis)