目錄
多表查詢
?查詢文章詳情
查詢一個用戶底下的所有文章
動態(tài)SQL的使用
if 標簽
trim 標簽
?where 標簽
set 標簽
foreach 標簽
多表查詢
現(xiàn)在有倆張表,一張是文章表,一張是用戶表.如下:
?查詢文章詳情
我們現(xiàn)在想查詢得到一張表,表里面的內(nèi)容和文章表大多一致,只是要在文章表的基礎上添加用戶表中的username字段,這就需要多表聯(lián)查來實現(xiàn)
用戶類(用戶表的映射)
@Data
public class UserEntity {
private int id;
private String username;
private String password;
private String photo;
private LocalDateTime createtime;
private LocalDateTime updatetime;
private int state;
}
文章類(文章表的映射)
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private LocalDateTime createtime;
private LocalDateTime updatetime;
private Integer uid;
private Integer rcount;
private int state;
}
文章表拓展(文章表加上用戶表中的username字段的表)
public class ArticleInfoVO extends ArticleInfo {
private String username;
//Lombok的toString方法默認是不打印父類的屬性的,所以這里我們要重寫toString方法
@Override
public String toString() {
return "ArticleInfoVO{" +
"username='" + username + '\'' +
"} " + super.toString();
}
}
這里因為Lombok的toString方法默認是不打印父類屬性的,所以我們進行了重寫(方便后續(xù)打印觀察結(jié)果)
實現(xiàn)mapper接口
@Mapper
public interface ArticleMapper {
//查詢文章詳情
ArticleInfoVO getDetail(@Param("id") Integer id);
}
實現(xiàn)對應的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="com.example.demo.mapper.ArticleMapper">
<select id="getDetail" resultType="com.example.demo.entity.vo.ArticleInfoVO">
select a.*,u.username from articleinfo a
left join userinfo u on u.id = a.uid
where a.id=#{id}
</select>
</mapper>
單元測試
@SpringBootTest
class ArticleMapperTest {
@Autowired
private ArticleMapper articleMapper;
@Test
void getDetail() {
ArticleInfoVO articleInfoVO = articleMapper.getDetail(1);
System.out.println(articleInfoVO);
}
}
結(jié)果
查詢一個用戶底下的所有文章
主表依然是文章表,對文章表先插入幾條數(shù)據(jù)
mapper接口
@Mapper
public interface ArticleMapper {
List<ArticleInfoVO> getArticleByUid(@Param("uid")Integer uid);
}
?xml
<select id="getArticleByUid" resultType="com.example.demo.entity.vo.ArticleInfoVO">
select a.*,u.username from articleinfo a
left join userinfo u on u.id = a.uid
where a.uid = #{uid}
</select>
單元測試
@Test
void getArticleByUid() {
Integer uid = 1;
List<ArticleInfoVO> list = articleMapper.getArticleByUid(uid);
list.stream().forEach(System.out::println);
}
結(jié)果
動態(tài)SQL的使用
動態(tài)SQL:允許我們在xml中寫一些邏輯判斷,來實現(xiàn)sql語句的拼接?
例如,在我們填寫表單的時候,一些字段是必須要填的,一些字段是非必須填的,我們要如何實現(xiàn)呢?
難點在于對于一些非必填的字段,我們?nèi)绾螌懖迦氲膕ql語句,這些字段是寫在sql語句中怎么實現(xiàn),用戶填寫這個字段的時候要寫,不填寫這個字段的時候又不需要寫.
if 標簽
現(xiàn)在要上傳用戶信息,我們需要傳遞username,password,photo這個三個字段,這其中username和password是必填的,photo是可填可不填的,我應該如何實現(xiàn)呢?
mapper
int addUser2(UserEntity user);
xml
<insert id="addUser2">
insert into userinfo(username,password
<if test="photo != null">
,photo
</if>
)values(#{username},#{password}
<if test="photo != null">
,#{photo}
</if>
)
</insert>
if標簽必須要有test(判斷條件),這里面除了要寫到sql語句中的屬性,我們可以直接拿到程序中的參數(shù),而寫入到sql語句中就需要使用#{},${}等方式獲取參數(shù).
單元測試
@Transactional
@Test
void addUser2() {
String username = "寶寶";
String password = "123456";
UserEntity user = new UserEntity();
user.setUsername(username);
user.setPassword(password);
int result = userMapper.addUser2(user);
System.out.println(result);
}
結(jié)果
可以看到我們傳入username和password生成的sql語句就只有這倆個字段
@Transactional
@Test
void addUser2() {
String username = "寶寶";
String password = "123456";
UserEntity user = new UserEntity();
user.setUsername(username);
user.setPassword(password);
user.setPhoto("cat.png");
int result = userMapper.addUser2(user);
System.out.println(result);
}
?可以看到同樣的代碼,我們這次多傳入了photo屬性,此時生成的sql語句就有username,password,photo字段了
trim 標簽
上面這個例子,如果username,password,photo都是非必填的(sql語句中的逗號不好處理),此時就需要<trim>標簽了
<trim>標簽的屬性
prefix: 表示整個語句塊,以prefix的值為前綴
suffix: 表示整個語句塊,以suffix的值為后綴
prefixOverrides: 表示整個語句塊要去除掉的前綴
suffixOverrides: 表示整個語句塊要去除掉的后綴
現(xiàn)在username,password,photo字段都為非必填,我們要如何實現(xiàn)?
mapper
int addUser3(UserEntity user);
xml?
<insert id="addUser3">
insert into userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">
username,
</if>
<if test="password != null">
password,
</if>
<if test="photo != null">
photo
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="username != null">
#{username},
</if>
<if test="password != null">
#{password},
</if>
<if test="photo != null">
#{photo}
</if>
</trim>
</insert>
單元測試
@Transactional
@Test
void addUser3() {
String username = "白楊";
String password = "123456";
UserEntity user = new UserEntity();
user.setUsername(username);
user.setPassword(password);
int result = userMapper.addUser3(user);
System.out.println(result);
}
結(jié)果
?where 標簽
想象一下這種場景:當我們在搜索框輸入文章標題的時候,搜索引擎會根據(jù)這個標題查詢,但是這個標題不是必須填的,我們也可以不輸入文章標題只是輸入了文章標題,搜索引擎會根據(jù)標題查詢,我們要如何實現(xiàn)這個功能呢?
例如現(xiàn)在在搜索框可以輸入標題或者id,或者什么都不輸入
mapper
List<ArticleInfoVO> getListByIdOrTitle(@Param("id")Integer id,@Param("title")String title);
xml
<select id="getListByIdOrTitle" resultType="com.example.demo.entity.vo.ArticleInfoVO">
select * from articleinfo
<where>
<if test="id!=null and id>0">
id = #{id}
</if>
<if test="title!=null">
and title like concat('%',#{title},'%')
</if>
</where>
</select>
使用了where標簽的好處:1.如果我們什么都沒傳,where后面的判斷語句都為Null,此時where標簽會自動幫我們去掉where.2.當我們只傳了一部分,where標簽會自動幫我們去掉前綴and
單元測試
@Test
void getListByIdOrTitle() {
List<ArticleInfoVO> list = articleMapper.getListByIdOrTitle(null,null);
System.out.println(list.size());
}
此時我們什么都沒傳,生成的sql語句沒有where
@Test
void getListByIdOrTitle() {
List<ArticleInfoVO> list = articleMapper.getListByIdOrTitle(null,"C語言");
System.out.println(list.size());
}
?
此時我們傳入了標題"C語言",這時生成的sql就有了where判斷語句, 且自動幫我們?nèi)サ袅薬nd
set 標簽
和where標簽很像,當我set標簽里面有信息,生成的sql語句就會生成set去修改內(nèi)容(set會自動幫我們去掉最后一個","),如果set標簽里面沒有信息,生成的sql語句就沒有set
foreach 標簽
<foreach>標簽允許我們傳入一個集合
<foreach>標簽屬性
collection: 綁定方法參數(shù)中的集合,如List,Set,Map或數(shù)組對象
item:遍歷時的每一個對象
open:語句塊開頭的字符串
close:語句塊結(jié)束的字符串
separator:每次遍歷之間間隔的字符串
利用foreach標簽來進行批量刪除
mapper
// 根據(jù)文章id集合批量刪除文章
int deleteByIdList(@Param("idList")List<Integer> idList);
xml
<delete id="deleteByIdList">
delete from articleinfo
where id in
<foreach collection="idList" item="id" open="(" close=")" separator="," >
#{id}
</foreach>
</delete>
單元測試
@Transactional
@Test
void deleteByIdList() {
List<Integer> idList = new ArrayList<>();
idList.add(1);
idList.add(2);
idList.add(3);
int result = articleMapper.deleteByIdList(idList);
System.out.println(result);
}
結(jié)果文章來源:http://www.zghlxwxcb.cn/news/detail-495696.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-495696.html
到了這里,關于MyBatis(多表查詢,動態(tài)SQL的使用)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!