亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

java - Mybatis 資料庫(kù)多表關(guān)聯(lián)分頁(yè)的問(wèn)題
黃舟
黃舟 2017-06-10 09:49:39
0
6
1718

舉例:
有兩個(gè)實(shí)體類(lèi)別 User 和 Address

#
public class User {
    private int id;
    private String username; // 用戶名
    private List<Address> addresses;
    // getter setter...
}

public class Address {
    private int id;
    private String detail; // 詳細(xì)地址
    private User user;    //所屬用戶
    // getter setter...
}

資料庫(kù):

create table t_user(
    id int(10) primary key auto_increment,
    username varchar(50)
);


create table t_address(
    id int(10) primary key auto_increment,
    detail varchar(255),
    user_id int(10),
    CONSTRAINT FOREIGN KEY (user_id) REFERENCES t_user(id)
);

mybatis映射配置:


<?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="org.mkh.shop.model.User">
    <resultMap type="User" id="userMap" autoMapping="true">
        <id property="id" column="u_id"/>
        <collection property="address" ofType="Address">
            <id property="id" column="a_id"/>
            <result property="detail" column="detail"/>
        </collection>
    </resultMap>

    <select id="find" resultType="User" parameterType="map">
        select  *,
                ta.id as 'a_id',
                tu.id as 'u_id' 
        from t_user tu 
            left join t_address ta on ta.user_id=tu.id 
        <where> 
            <if test="name != null">
                (username like #{name})
            </if>
        </where>
        <if test="sort != null">
            order by ${sort} 
            <choose>
                <when test="order != null">${order}</when>
                <otherwise>asc</otherwise>
            </choose> 
        </if>
        limit #{pageOffset},#{pageSize}
    </select>
    
    <select id="find_count" resultType="int" parameterType="map">
        select count(*) 
        from t_user tu 
            left join t_address ta on ta.user_id=tu.id 
        <where> 
            <if test="name != null">
                (username like #{name})
            </if>
        </where>
    </select>    
</mapper> 

用戶和地址的關(guān)係為:一個(gè)用戶有多個(gè)地址,一個(gè)地址只能屬於一個(gè)用戶,一對(duì)多
假設(shè)現(xiàn)在的需求是,分頁(yè)查詢用戶,用表格顯示,並把每個(gè)用戶的所有位址顯示出來(lái)
那麼問(wèn)題來(lái)了
按照上面的查詢返回的分頁(yè)的資料是沒(méi)有問(wèn)題的,但是分頁(yè)的總記錄數(shù)卻是不對(duì)的。
例如查出來(lái)的數(shù)據(jù)(資料庫(kù)數(shù)據(jù),非頁(yè)面顯示)如下:

u_id username a_id detail
1 user1 1 北京市海淀區(qū)
1 user1 2 北京市朝陽(yáng)區(qū)
2 user2 3 天津市

因?yàn)槲业男枨笫欠猪?yè)顯示用戶,所以一個(gè)用戶就是一條數(shù)據(jù)在頁(yè)面顯示大概是這樣子,理論上是兩個(gè)數(shù)據(jù),

用戶id 使用者名稱(chēng) 地址
1 user1 1. 北市海淀區(qū) 2. 北京市朝陽(yáng)區(qū)
2 user2 1. 天津市
共1頁(yè),共2條數(shù)據(jù),每頁(yè)顯示10條

但是,按mybatis的find_count配置 查出來(lái)是3條,這種問(wèn)題如何解決?
查詢count(*)的時(shí)候?qū)⑺衛(wèi)eft join 後面關(guān)聯(lián)的表格移除嗎?這樣會(huì)不會(huì)導(dǎo)致回傳的資料不準(zhǔn)確


補(bǔ)充說(shuō)明:感覺(jué)大家是理解錯(cuò)我的意思了,其實(shí)我這個(gè)問(wèn)題主要是在SQL 上,而不再mybatis上,因?yàn)槲也樵兂鰜?lái)的資料映射完畢之後是完全沒(méi)有問(wèn)題的,只是在分頁(yè)的總記錄數(shù)上出現(xiàn)了問(wèn)題,導(dǎo)致分頁(yè)不正確

#
黃舟
黃舟

人生最曼妙的風(fēng)景,竟是內(nèi)心的淡定與從容!

全部回覆(6)
漂亮男人

剛才寫(xiě)了個(gè)例子測(cè)了一下

`

兩個(gè)實(shí)體類(lèi)別
public class User {


private int id;
private String username; // 用戶名
private List<Address> addresses;

public class Address {

private int id;
private String detail; // 詳細(xì)地址
private int user_id; // 所屬用戶

映射檔

    <result property="id" column="u_id"/>
    <collection property="addresses" ofType="com.atguigu.mybatis.entity.Address" autoMapping="true">
        <result property="id" column="a_id"/>
        <result property="user_id" column="u_id"/>
    </collection>
</resultMap>

<select id="select_all_user_address"  resultMap="userMap" >





        
         select   tu.*,ta.*,
            ta.id as 'a_id',
            tu.id as 'u_id' 
    from t_user tu 
        left join t_address ta on ta.user_id=tu.id 
</select>

測(cè)試結(jié)果

封裝成的 List的size是沒(méi)問(wèn)題的

左手右手慢動(dòng)作

關(guān)鍵字group by 自己查一下具體操作

學(xué)霸
SELECT 
    *, ta.id AS 'a_id', tu.id AS 'u_id'
FROM
    t_user tu
        LEFT JOIN
    t_address ta ON ta.user_id = tu.id;

你希望想要兩個(gè) 但是你的sql查出三條,所以顯示錯(cuò)誤,
應(yīng)該拆分邏輯:
應(yīng)該先查出你想要的用戶

<select id="find" resultType="User" parameterType="map">
        select  *
        from t_user tu 
        <where> 
            <if test="name != null">
                (username like #{name})
            </if>
        </where>
        <if test="sort != null">
            order by ${sort} 
            <choose>
                <when test="order != null">${order}</when>
                <otherwise>asc</otherwise>
            </choose> 
        </if>
        limit #{pageOffset},#{pageSize}
    </select>

然後在

    <resultMap type="User" id="userMap" autoMapping="true">
        <id property="id" column="u_id"/>
        <collection " property="addresses" javaType= "ArrayList" column="u_id"
 ofType="Address" select= "??" />
    </resultMap>

??是自己實(shí)作個(gè) 用userId查L(zhǎng)ist

的方法
學(xué)霸

這種情況不能這麼分頁(yè),你需要將主表資料分頁(yè)。

本來(lái)查詢出100條數(shù)據(jù),由於一對(duì)多會(huì)折疊去重很多數(shù)據(jù),導(dǎo)致實(shí)際結(jié)果少於100條。

這種情況下可以採(cǎi)取巢狀查詢方式解決,就是需要N+1次執(zhí)行,可以懶載入。

或看這裡:https://my.oschina.net/flags/...

有關(guān) MyBatis 內(nèi)容可以訪問(wèn):http://mybatis.tk

扔個(gè)三星炸死你
<select id="find_count" resultType="int" parameterType="map">
    select count(*) 
    from t_user tu 
        left join t_address ta on ta.user_id=tu.id 
    <where> 
        <if test="name != null">
            (username like #{name})
        </if>
    </where>
</select> 

改:

<select id="find_count" resultType="int" parameterType="map">
    select count(*) 
    from t_user tu
   <where> 
        <if test="name != null">
            (username like #{name})
        </if>
    </where>

    group by username
</select> 
曾經(jīng)蠟筆沒(méi)有小新

用子查詢就不會(huì)有問(wèn)題了

select count(*) from (
   // query 在這里即使關(guān)聯(lián)100張表, 也不可能存在問(wèn)題
)

樓主可以看一下Mybatis-PageHelper count sql 轉(zhuǎn)換實(shí)作

建議樓主直接使用 Mybatis-PageHelper 實(shí)現(xiàn)分頁(yè)

最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板