java - Restful服务 MyBatis 多表查询大量字段时结果集映射解决方案?
PHPz
PHPz 2017-04-18 09:14:48
0
6
407

MyBatis 无论是 resultType 还是 resultMap 都需要一个实体

例如我们这样一个SQL

<mapper namespace="com.savorgames.dao.MemberMapper">
   <select id="test" resultType="com.savorgames.domain.Member">
       SELECT username,password FROM "user";
  </select>
</mapper>

Member实体

public class Member {
    
    private int uid;
    private String username;
    private String password;
    private String email;
    private String nickname;
    
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getNickname() {
        return nickname;
    }
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
}

结果集映射Mapper

List<Member>

现在问题来了,做restful服务器时候,将实体转换成 json 会出现大量空值 并暴露数据库表字段,传输的json也相对变大了

例如:

[{"uid":0,"username":"阿斯达","password":null,"email":null,"nickname":null},{"uid":0,"username":"阿萨法","password":null,"email":null,"nickname":null},{"uid":0,"username":"阿斯达","password":null,"email":null,"nickname":null},{"uid":0,"username":"啊实打实的","password":null,"email":null,"nickname":null},{"uid":0,"username":"阿斯达啊","password":null,"email":null,"nickname":null},{"uid":0,"username":"是打算打","password":null,"email":null,"nickname":null},{"uid":0,"username":"阿斯达","password":"12312312","email":null,"nickname":null}]

总不能每一个sql语句都写一个实体类吧,如何灵活的处理 MyBatis 结果集,只返回查询字段?

PHPz
PHPz

学习是最好的投资!

全部回覆(6)
PHPzhong

正確的做法是不要改變實體類別(DO),

  1. 新建資料傳輸類別(DTO),例如MemberDTO,

  2. 寫一個方法吧DO轉換成DTO,一個DTO包含的數據可能來自好幾個DO,就像你現在需要傳輸Member的數據,如果需要其他表的一些屬性怎麼辦。

DO是保持和資料庫一致的,DTO是保持跟外界互動一致的,這樣在資料或業務發生變動的時候,可以靈活的調整。
千萬不要把DO直接拿來做資料傳輸,這樣不利於擴充

洪涛

這個跟Mybatis沒有半毛錢關係吧,應該是json序列化的配置問題。
我假設你用的是SpringMVC+Jackson,Jackson的序列化配置如下:

<mvc:annotation-driven>
    <mvc:message-converters register-defaults="true">
        <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
            <property name="objectMapper">
                <bean class="org.springframework.http.converter.json.Jackson2ObjectMapperFactoryBean">
            <property name="serializationInclusion" value="NON_NULL"/><!-- 重点:只输出非NULL字段 -->
        </bean>
    </mvc:message-converters>
</mvc:annotation-driven>

可以看一下@JsonInclude的几个枚举变量对应的含义,个人认为最理想的应该是用NON_EMPTY,这个会把空对象、空数组也不输出(例如:{}, [])。但要注意的是:0也会被认为是EMPTY从而不输出(意味着所有没赋值或为0的int类型或Integer物件都不會被輸出)。

Ty80

將物件轉換為JSON時(序列化過程),如果物件的某個屬性值為null,則該屬性不參與序列化,產生的JSON結果也不會包含該屬性。程式碼如下:

public String toNotifyBody(NotifyBean bean) {
        HashMap<String, Object> map = new HashMap<String, Object>();
        map.put("orderId", bean.orderId);
        map.put("title", bean.title);
        map.put("subject", bean.subject);
        map.put("operateType", bean.operateType);
        map.put("handlePerson", bean.handlePerson);
        map.put("extractPerson", bean.extractPerson);
        map.put("sla", bean.sla);
        return JSON.toJSONString(map);
    }

將上述參數,放在map中,然後呼叫json的方法JSON.toJSONString()的時候,對於null值,是不傳輸的。我們來看看JSON.toJSONString()方法的實作。

public static final String toJSONString(Object object) {
        return toJSONString(object, new SerializerFeature[0]);
    }
    public static final String toJSONString(Object object, SerializerFeature... features) {
        SerializeWriter out = new SerializeWriter();

        try {
            JSONSerializer serializer = new JSONSerializer(out);
            for (com.alibaba.fastjson.serializer.SerializerFeature feature : features) {
                serializer.config(feature, true);
            }

            serializer.write(object);

            return out.toString();
        } finally {
            out.close();
        }
    }
左手右手慢动作

如果沒有實體類,暴露資料表欄位是必然的。

不知道你使用的什麼方法產生 JSON,不過理論上,應該會有一個忽略空值的參數,找找看,如果實在找不到,可以用正規表示式把空屬性去掉。

伊谢尔伦

建構對應的實體類別是必須的,只顯示需要展示的內容,並對資料的格式進行轉換(例如date轉string等)

左手右手慢动作

你可以用HashMap接受mybatis查詢結果

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板