Mybatis聯(lián)合查詢XML與注解對比分析
測試類容
XML配置轉(zhuǎn)注解方式
實體類
為了測試請忽略設計是否合理…
User.java
@Alias("User")
public class User {
private Integer id;
private String username;
private String password;
private Timestamp birthday;
private Boolean sex;
}UserInfo.java
@Alias("UserInfo")
public class UserInfo {
private Integer id;
private User user;
private String name;
}UserMessage.java
@Alias("UserMessage")
public class UserMessage {
private Integer userId;
private UserInfo userInfo;
private List<Message> messages;
}Message.java
@Alias("Message")
public class Message {
private Integer id;
private Integer userId;
private String content;
private Timestamp time;
}三表之間的關(guān)聯(lián)為 userId
XML配置方式
XML配置
<select id="selectUserInfoAndMessages" resultMap="UserMessages">
select
ui.id as uiid,
ui.name as name,
ui.user_id as info_user_id,
u.id as user_id,
u.username
as username,
u.password as password,
u.birthday as birthday,
u.sex as
sex,
um.id as umid,
um.user_id as um_user_id,
um.content as content,
um.time as um_time
from user_info ui
left outer join user u on u.id = ui.user_id
left outer join user_message um
on u.id = um.user_id
where u.id = #{id}
</select>
<resultMap type="UserMessage" id="UserMessages">
<id property="userId" column="user_id" />
<association property="userInfo" column="info_user_id"
javaType="UserInfo">
<id property="id" column="uiid" />
<result property="name" column="name" />
<association property="user" column="user_id" javaType="User">
<id property="id" column="user_id" />
<result property="username" column="username" />
<result property="password" column="password" />
<result property="birthday" column="birthday" />
<result property="sex" column="sex" />
</association>
</association>
<collection property="messages" javaType="ArrayList"
ofType="Message">
<id property="id" column="umid" />
<result property="userId" column="user_id" />
<result property="content" column="content" />
<result property="time" column="um_time" />
</collection>
</resultMap>查詢方法
public List<UserMessage> testSelectUserInfoAndMessages(Integer userId) {
try (SqlSession session = sessionFactory.openSession()) {
//映射器方式調(diào)用
//return session.getMapper(UserMapper.class).selectUserInfoAndMessage(userId);
return session.selectList("mybatis.dao.mappers.UserMapper.selectUserInfoAndMessages", userId);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}執(zhí)行過程
==> Preparing: select ui.id as uiid, ui.name as name, ui.user_id as info_user_id, u.id as user_id, u.username as username, u.password as password, u.birthday as birthday, u.sex as sex, um.id as umid, um.user_id as um_user_id, um.content as content, um.time as um_time from user_info ui left outer join user u on u.id = ui.user_id left outer join user_message um on u.id = um.user_id where u.id = ?
==> Parameters: 9(Integer)
<== Columns: uiid, name, info_user_id, user_id, username, password, birthday, sex, umid, um_user_id, content, um_time
<== Row: 5, 江流, 9, 9, test中文2, 1234567, 2018-07-17 17:04:09.0, 0, 1, 9, 信息1, 2018-07-18 11:36:58.0
<== Row: 5, 江流, 9, 9, test中文2, 1234567, 2018-07-17 17:04:09.0, 0, 2, 9, 信息2, 2018-07-18 11:37:05.0
<== Total: 2
結(jié)果
[UserMessage [userId=9, userInfo=UserInfo [id=5, user=User [id=9, username=test中文2, password=1234567, birthday=2018-07-17 17:04:09.0, sex=false], name=江流], messages=[Message [id=1, userId=9, content=信息1, time=2018-07-18 11:36:58.0], Message [id=2, userId=9, content=信息2, time=2018-07-18 11:37:05.0]]]]
此種方式只查詢了一次,結(jié)果集被過濾了重復項目,最終集合中只有一個UserMessage對象。
注解方式
注解方法
@Select("select * from user where id = #{userId}")
@Results(value = {
@Result(property="userId" , column="id"),
@Result(property="userInfo" , column="id", one = @One(select="mybatis.dao.mappers.UserMapper.getUserInfoByAnnotation")),
@Result(property="messages" , column = "id" , many= @Many(select="mybatis.dao.mappers.UserMapper.getUserMessagesByAnnotation"))
})
public List<UserMessage> selectUserInfoAndMessagesByAnnotation(Integer userId);//查詢用戶信息和用戶消息
@Select("select * from user_info where user_id = #{userId}")
@Results(value={
@Result(property="id" , column="id"),
@Result(property="name" , column = "name"),
@Result(property="user" , column = "user_id" , one = @One(select="mybatis.dao.mappers.UserMapper.getUserByAnnotation"))
})
public UserInfo getUserInfoByAnnotation(Integer userId);//查詢用戶信息
@Select("select * from user where id = #{userId}")
public User getUserByAnnotation(Integer userId);//查詢用戶
@Select("select * from user_message where user_id = #{userId}")
public List<Message> getUserMessagesByAnnotation(Integer userId);//查詢用戶消息集合查詢方法
public List<UserMessage> testSelectUserMessagesByAnnotation(Integer userId) {
try (SqlSession session = sessionFactory.openSession()) {
return session.getMapper(UserMapper.class).selectUserInfoAndMessagesByAnnotation(userId);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}執(zhí)行過程
==> Preparing: select * from user where id = ?
==> Parameters: 9(Integer)
<== Columns: id, username, password, sex, birthday
<== Row: 9, test中文2, 1234567, 0, 2018-07-17 17:04:09.0
====> Preparing: select * from user_info where user_id = ?
====> Parameters: 9(Integer)
<==== Columns: id, user_id, name
<==== Row: 5, 9, 江流
======> Preparing: select * from user where id = ?
======> Parameters: 9(Integer)
<====== Columns: id, username, password, sex, birthday
<====== Row: 9, test中文2, 1234567, 0, 2018-07-17 17:04:09.0
<====== Total: 1
<==== Total: 1
====> Preparing: select * from user_message where user_id = ?
====> Parameters: 9(Integer)
<==== Columns: id, user_id, content, time
<==== Row: 1, 9, 信息1, 2018-07-18 11:36:58.0
<==== Row: 2, 9, 信息2, 2018-07-18 11:37:05.0
<==== Total: 2
<== Total: 1
可以看出執(zhí)行了幾次查詢語句。
結(jié)果
[UserMessage [userId=9, userInfo=UserInfo [id=5, user=User [id=9, username=test中文2, password=1234567, birthday=2018-07-17 17:04:09.0, sex=false], name=江流], messages=[Message [id=1, userId=9, content=信息1, time=2018-07-18 11:36:58.0], Message [id=2, userId=9, content=信息2, time=2018-07-18 11:37:05.0]]]]
總結(jié)
- XML執(zhí)行聯(lián)合查詢效率是要高一些的
- 注解方式方法倒是可以獨立使用,雖然XML也可以用select屬性
- 混合使用更好
套用官方的話
1、因為最初設計時,MyBatis 是一個 XML 驅(qū)動的框架。配置信息是基于 XML 的,而且映射語句也是定義在 XML 中的。而到了 MyBatis 3,就有新選擇了。MyBatis 3 構(gòu)建在全面且強大的基于 Java 語言的配置 API 之上。這個配置 API 是基于 XML 的 MyBatis 配置的基礎,也是新的基于注解配置的基礎。注解提供了一種簡單的方式來實現(xiàn)簡單映射語句,而不會引入大量的開銷。
2、注意 不幸的是,Java 注解的的表達力和靈活性十分有限。盡管很多時間都花在調(diào)查、設計和試驗上,最強大的 MyBatis 映射并不能用注解來構(gòu)建——并不是在開玩笑,的確是這樣。比方說,C#屬性就沒有這些限制,因此 MyBatis.NET 將會比 XML 有更豐富的選擇。也就是說,基于 Java 注解的配置離不開它的特性。
附 數(shù)據(jù)表SQL
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(25) DEFAULT NULL, `password` varchar(25) DEFAULT NULL, `sex` bit(1) DEFAULT b'1', `birthday` datetime DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8; CREATE TABLE `user_info` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `name` varchar(25) DEFAULT NULL, PRIMARY KEY (`id`), KEY `user_id` (`user_id`), CONSTRAINT `user_info_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8; CREATE TABLE `user_message` ( `id` int(11) NOT NULL AUTO_INCREMENT, `user_id` int(11) DEFAULT NULL, `content` varchar(255) DEFAULT NULL, `time` datetime DEFAULT NULL, PRIMARY KEY (`id`), KEY `message_ibfk_1` (`user_id`), CONSTRAINT `user_message_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實現(xiàn)基于UDP協(xié)議的聊天小程序操作
UDP是與TCP相對應的協(xié)議,UDP適用于一次只傳送少量數(shù)據(jù)、對可靠性要求不高的應用環(huán)境。正因為UDP協(xié)議沒有連接的過程,所以它的通信效率高;但也正因為如此,它的可靠性不如TCP協(xié)議高,本文給大家介紹java實現(xiàn)基于UDP協(xié)議的聊天小程序操作,感興趣的朋友一起看看吧2021-10-10
MessageUtils.message("user.jcaptcha.expire")問題及解決
文章介紹了若依項目中的國際化工具MessageUtils,用于根據(jù)不同語言環(huán)境獲取驗證碼過期提示信息,通過Spring的MessageSource讀取多語言配置文件實現(xiàn),并詳細描述了其作用、配置文件位置、底層原理及觸發(fā)場景2026-04-04

