MyBatis后端對數(shù)據(jù)庫進行增刪改查等操作實例
1.MyBatis 是什么?
MyBatis 是?款優(yōu)秀的持久層框架,它?持?定義 SQL、存儲過程以及?級映射。MyBatis 去除了很多JDBC 代碼以及設(shè)置的參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接?和 Java POJO (Plain Old Java Object。普通老式 Java對象)為數(shù)據(jù)庫中的記錄。
2. MyBatis 的重要性
對于后端開發(fā)來說,程序是由兩個重要部分組成的:
1.后端程序
2.數(shù)據(jù)庫
?這兩個重要的組成部分要通訊,就要依靠數(shù)據(jù)庫連接?具
1.JDBC
2. MyBatis
JDBC 的操作流程:
1. 創(chuàng)建數(shù)據(jù)庫連接池 DataSource
2. 通過 DataSource 獲取數(shù)據(jù)庫連接 Connection
3. 編寫要執(zhí)?帶 ? 占位符的 SQL 語句
4. 通過 Connection 及 SQL 創(chuàng)建操作命令對象 Statement
5. 替換占位符:指定要替換的數(shù)據(jù)庫字段類型,占位符索引及要替換的值
6. 使? Statement 執(zhí)? SQL 語句
7. 查詢操作:返回結(jié)果集 ResultSet,更新操作:返回更新的數(shù)量
8. 處理結(jié)果集
9. 釋放資源
對于 JDBC 來說,整個操作?常的繁瑣,我們不但要拼接每?個參數(shù),?且還要按照模板代碼的?式,?步步的操作數(shù)據(jù)庫,并且在每次操作完,還要?動關(guān)閉連接等,?所有的這些操作步驟都需要在每個?法中重復(fù)書寫。 對于 MyBatis ,它可以幫助我們更?便、更快速的操作數(shù)據(jù)庫。
3. MyBatis 查詢
框架交互流程

MyBatis 也是?個 ORM 框架, ORM(Object Relational Mapping),即對象關(guān)系映射。在?向?qū)?象編程語?中,將關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)與對象建?起映射關(guān)系,進??動的完成數(shù)據(jù)與對象的互相轉(zhuǎn)換:
1. 將輸?數(shù)據(jù)(即傳?對象)+SQL 映射成原? SQL
2. 將結(jié)果集映射為返回對象,即輸出對象ORM 把數(shù)據(jù)庫映射為對象:
數(shù)據(jù)庫表(table)--> 類(class)
記錄(record,?數(shù)據(jù))--> 對象(object)
字段(field) --> 對象的屬性(attribute)
?般的 ORM 框架,會將數(shù)據(jù)庫模型的每張表都映射為?個 Java 類。 也就是說使? MyBatis 可以像操作對象?樣來操作數(shù)據(jù)庫中的表,可以實現(xiàn)對象和數(shù)據(jù)庫表之間的轉(zhuǎn)換。
3.1 創(chuàng)建數(shù)據(jù)庫和表
使? MyBatis 的?式來讀取?戶表中的所有?戶
創(chuàng)建用戶表
drop table if exists userinfo;
create table userinfo(
id int primary key auto_increment,
username varchar(100) not null,
password varchar(32) not null,
photo varchar(500) default '',
createtime datetime default now(),
updatetime datetime default now(),
`state` int default 1
) default charset 'utf8mb4';
3.2 添加MyBatis框架?持
3.2.1 新項目添加MyBatis
在創(chuàng)建新項目時,來到這一步,只需將下面的勾選即可

3.2.1 老項?添加 MyBatis
在 pom.xml 文件頁面 鼠標(biāo)右鍵進行下面操作


3.3 配置連接字符串和MyBatis
3.3.1 配置連接字符串

將當(dāng)前運行環(huán)境選擇開發(fā)環(huán)境的配置
application-dev.yml
#開發(fā)環(huán)境
#配置數(shù)據(jù)庫連接
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/myblog?characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 開啟 MyBatis SQL 打印
logging:
level:
com:
example:
demo: debug
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImplapplication.yml
選擇開發(fā)環(huán)境
spring:
profiles:
active: dev3.3.2 配置mybatis 中的 xml 保存路徑
MyBatis 的 XML 中保存是查詢數(shù)據(jù)庫的具體操作 SQL,配置在 application.yml 中
#配置mybatis xml 保存路徑 mybatis: mapper-locations: classpsth:mybatis/**Mapper.xml
3.4 添加后端代碼
下?按照后端開發(fā)的?程思路,也就是下?的流程來實現(xiàn) MyBatis 查詢所有?戶的功能

目錄結(jié)構(gòu):
3.4.1 添加實體類
先添加用戶實體類
/**
* 普通用戶實體類
*/
@Data
public class UserInfo {
private Integer id;
private String name;
private String password;
private String photo;
private String createtime;
private String updatetime;
private int state;
}3.4.2 添加 mapper 接口
數(shù)據(jù)持久層的接口定義:
/**
* 實現(xiàn)數(shù)據(jù)庫映射
*/
@Mapper
public interface UserMapper {
//查詢用戶 ID
public UserInfo getUserById(@Param("id") Integer id);
}3.4.3 添加UserMapper.xml
數(shù)據(jù)持久層的實現(xiàn),mybatis 的固定 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"> <!-- namespace 要設(shè)置是實現(xiàn)接口的具體包名加類名 --> <mapper namespace="com.example.demo.mapper.UserMapper"> </mapper>
UserMapper.xml 查詢所有?戶的具體實現(xiàn) SQL:
<?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">
<!-- namespace 要設(shè)置是實現(xiàn)接口的具體包名加類名 -->
<mapper namespace="com.example.demo.mapper.UserMapper">
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<!-- 主鍵映射 -->
<id column="id" property="id"></id>
<!-- 普通屬性映射 -->
<result column="username" property="name"></result>
</resultMap>
<!-- 根據(jù) id 查詢用戶 -->
<select id="getUserById" resultMap="BaseMap">
select * from userinfo where id=${id}
</select>
</mapper>標(biāo)簽說明:
<mapper>標(biāo)簽:需要指定 namespace 屬性,表示命名空間,值為 mapper 接?的全限定名,包括全包名.類名。
<select>查詢標(biāo)簽:是?來執(zhí)?數(shù)據(jù)庫的查詢操作的:
- id:是和 Interface(接?)中定義的?法名稱?樣的,表示對接?的具體實現(xiàn)?法。
- resultType:是返回的數(shù)據(jù)類型,也就是開頭我們定義的實體類

3.4.4 添加Service
決定調(diào)用哪個mapper
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public UserInfo getUserById(Integer id) {
return userMapper.getUserById(id);
}
}3.4.5 添加 Controller
@Controller
@ResponseBody
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/getuserbyid")
public UserInfo getUserById(Integer id) {
if (id == null) return null;
return userService.getUserById(id);
}
}以上代碼寫完,整個 MyBatis 的查詢功能就實現(xiàn)完了

4.增刪改操作
4.1 修改用戶操作
在 UserMapper 中增加修改的代碼
//修改方法根據(jù) ID 修改名稱
public int update(@Param("id") Integer id,
@Param("name") String username);UserMapper.xml 中增加接口的實現(xiàn)標(biāo)簽和具體的執(zhí)行SQL
<update id="update" >
update userinfo set username=#{name} where id=#{id}
</update>
通過單元測試,實現(xiàn)成功
@Test
void update() {
int result = userMapper.update(2,"fei");
Assertions.assertEquals(1,result);
}
查詢SQL語句可知,已經(jīng)修改了

如果僅僅是為了測試功能是否實現(xiàn),而不修改數(shù)據(jù)庫中的內(nèi)容,可以加入注解 @Transactional
@Test
@Transactional // 添加此注解后,執(zhí)行完單元測試,不會修改數(shù)據(jù)庫中的內(nèi)容,即事務(wù)回滾
void update() {
int result = userMapper.update(2,"fei");
Assertions.assertEquals(1,result);
}4.2 刪除用戶操作
在 UserMapper 中增加刪除的代碼
//刪除方法
public int del(@Param("id") Integer id);UserMapper.xml 中增加接口的實現(xiàn)標(biāo)簽和具體的執(zhí)行SQL
<!--刪除操作-->
<delete id="del">
delete from userinfo where id=#{id};
</delete>單元測試
@Test
@Transactional
void del() {
int result = userMapper.del(2);
System.out.println("刪除行數(shù): " + result);
Assertions.assertEquals(1,result);
}
4.3 增加用戶操作
在 UserMapper 中添加增加的代碼
//增加用戶方法
// 傳過來的是對象而不是某個成員變量
public int add(UserInfo userInfo);UserMapper.xml 中增加接口的實現(xiàn)標(biāo)簽和具體的執(zhí)行SQL
<!--增加操作,返回受影響的行數(shù)-->
<insert id="add">
insert into userinfo(username,password,photo)
values(#{username}, #{password}, #{photo}); <!--和對象里面的屬性一一對應(yīng)-->
</insert>單元測試
@Test
//@Transactional
void add() {
UserInfo userInfo = new UserInfo();
userInfo.setName("y");
userInfo.setPassword("123");
userInfo.setPhoto("");
System.out.println("添加之前的 id: " + userInfo.getId());
int result = userMapper.add(userInfo);
System.out.println("添加之后的 id: " + userInfo.getId());
System.out.println("添加的行數(shù): " + result);
Assertions.assertEquals(1,result);
}
4.4 增加用戶并有自增ID
在 UserMapper 中添加增加的代碼
//添加用戶,返回自增ID
public int addGetId(UserInfo userInfo);UserMapper.xml 中增加接口的實現(xiàn)標(biāo)簽和具體的執(zhí)行SQL
<!--增加操作,返回受影響的行數(shù)和自增ID-->
<insert id="addGetId" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into userinfo(username,password,photo)
values(#{name}, #{password}, #{photo}); <!--和對象里面的屬性一一對應(yīng)-->
</insert>單元測試
@Test
//@Transactional
void addGetId() {
UserInfo userInfo = new UserInfo();
userInfo.setName("yang");
userInfo.setPassword("123");
userInfo.setPhoto("");
System.out.println("添加之前的 id: " + userInfo.getId());
int result = userMapper.addGetId(userInfo);
System.out.println("添加之后的 id: " + userInfo.getId());
System.out.println("添加的行數(shù): " + result);
Assertions.assertEquals(1,result);
}

5. 參數(shù)占位符 #{} 和 ${}
#{}:預(yù)編譯處理 。處理時,成一個 問號? ,賦值時會加上 單引號 ‘ ’
${}:字符直接替換
區(qū)別:
1.定義不同
預(yù)編譯處理是指:MyBatis 在處理#{}時,會將 SQL 中的 #{} 替換為?號,使? PreparedStatement 的set ?法來賦值。
直接替換:是MyBatis 在處理 ${} 時,就是把 ${} 替換成變量的值。
2.使用不同:#{} 適用于所有類型的參數(shù)匹配,但${} 只適用于數(shù)值類型
3.安全性不同:#{} 性能高,并且沒有安全問題;但 ${} 存在SQL注入的安全問題
#{}:預(yù)編譯處理 占位符,當(dāng)成 value 值來使用, 即加上 ‘ ’
<select id="gerUserFullById" resultType="com.example.demo.model.UserInfo">
select * from userinfo where username=#{name}
</select> @Test
void gerUserFullById() {
UserInfo userInfo = userMapper.gerUserFullById("fei");
System.out.println("userInfo: " + userInfo);
}
${}:字符直接替換
不加任何符合,直接替換上去,連成一個SQL 命令
<select id="gerUserFullById" resultType="com.example.demo.model.UserInfo">
select * from userinfo where username=${name}
</select>單元測試結(jié)果

5.1 desc 降序排序
//對用戶進行排序
public List<UserInfo> getOrderList(@Param("order") String order);此處使用的是 ${}, 如果使用 #{} 的話,會編譯出錯,因為它會把 desc 當(dāng)成 ‘desc’ 一個value 值來使用,不構(gòu)成一個 SQL命令語句
<select id="getOrderList" resultType="com.example.demo.model.UserInfo">
select * from userinfo order by createtime ${order}
</select>單元測試
@Test
void getOrderList() {
List<UserInfo> list = userMapper.getOrderList("desc");
log.info("列表: " + list);
}

5.2 登錄(SQL注入)
//登錄功能
public UserInfo login(@Param("name") String username,
@Param("password") String password);1) 在使用${} 時,需要加單引號,因為是直接替換
<select id="login" resultType="com.example.demo.model.UserInfo">
select * from userinfo where username='${name}' and password='${password}';
</select>單元測試
@Test
void login() {
String username = "Fly";
String password = "";
UserInfo userInfo = userMapper.login(username,password);
log.info("用戶信息: " + userInfo);
}
使用 " 'or 1=' 1" 時,SQL注入,密碼會泄露,如下,因此在登錄時應(yīng)使用#{}
@Test
void login() {
String username = "Fly";
//String password = "";
String password = "'or 1='1";
UserInfo userInfo = userMapper.login(username,password);
log.info("用戶信息: " + userInfo);
}
2)#{} 預(yù)編譯處理,不會出現(xiàn)密碼泄露
<!--登錄功能-->
<select id="login" resultType="com.example.demo.model.UserInfo">
<!--select * from userinfo where username='${name}' and password='${password}'; -->
select * from userinfo where username=#{name} and password=#{password};
</select>
5.3 like 查詢
//like 模糊查詢
public List<UserInfo> getUserByName(@Param("name") String username);1)直接使用 #{} 會報錯
因為賦值時會加上單引號 ‘’
select * from userinfo where username like '%#{name}%'就相當(dāng)于下面的語句,不符合查詢條件
select * from userinfo where username like '%'name'%'
2)使用${} 是不會報錯,但在業(yè)務(wù)層的值不能窮舉
3)#{} 在like中的正確用法,加上contat 拼接,演示如下

正確用法
因為#{} 在賦值的時候,會帶上單引號‘’ ,所以下面的#{}不需要帶單引號
<!--like 模糊查詢-->
<select id="getUserByName" resultType="com.example.demo.model.UserInfo">
<!-- select * from userinfo where username like '%#{name}%'-->
select * from userinfo where username like concat('%',#{name},'%')
</select>單元測試
@Test
void getUserByName() {
String username = "l";
List<UserInfo> list= userMapper.getUserByName(username);
log.info("用戶列表: " + list);
}
6.多表查詢
6.1 返回類型:resultType
絕大數(shù)查詢場景可以使用 resultType 進行返回,如下
<!-- 根據(jù) id 查詢用戶 -->
<select id="getUserById" resultType="com.example.demo.model.UserInfo">
select * from userinfo where id=${id}
</select>它的優(yōu)點是使??便,直接定義到某個實體類即可 6.2 返回字典映射:resultMap 使用場景:
字段名稱和程序中的屬性名不同的情況, 可使? resultMap 配置映射; 一對一和一對多關(guān)系可以使用 resultMap 映射并查詢數(shù)據(jù)
1)字段名程序中的屬性名不一致

userMapper.xml 代碼如下
<!-- 根據(jù) id 查詢用戶 -->
<select id="getUserById" resultType="com.example.demo.model.UserInfo">
select * from userinfo where id=${id}
</select>查詢結(jié)果

這個時候就可以使? resultMap 了,resultMap 的使?如下

userMapper.xml 代碼如下
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<!--主鍵映射-->
<id column="id" property="id"></id>
<!--普通屬性映射-->
<result column="username" property="name"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
</resultMap>
<!-- 根據(jù) id 查詢用戶 -->
<select id="getUserById" resultMap="BaseMap">
select * from userinfo where id=${id}
</select>單元測試
@Test
void getUserById() {
UserInfo userInfo = userMapper.getUserById(1);
//Assertions.assertNotNull(userInfo);
log.info("查詢行數(shù):" + userInfo);
}查詢結(jié)果

6.3 一對一表查詢
創(chuàng)建文章實體類 ArticleInfo
@Data
public class ArticleInfo {
private int id;
private String title;
private String content;
private String createtime;
private String updatetime;
private int uid;
private int rcount;
private int state;
private UserInfo userInfo;
}mapper 實現(xiàn)數(shù)據(jù)庫映射 ArticleMapper
@Mapper
public interface ArticleMapper {
//根據(jù)文章 id 獲取文章
public ArticleInfo getArticleById(@Param("id") Integer id); //文章id
}數(shù)據(jù)庫命令,數(shù)據(jù)持久層的實現(xiàn), ArticleMapper.xml
<mapper namespace="com.example.demo.mapper.ArticleMapper">
<resultMap id="BaseMap" type="com.example.demo.model.ArticleInfo">
<!--主鍵映射-->
<id column="id" property="id"></id>
<!--普通屬性映射-->
<result column="title" property="title"></result>
<result column="content" property="content"></result>
<result column="createtime" property="createtime"></result>
<result column="uid" property="uid"></result>
<result column="rcount" property="rcount"></result>
<result column="state" property="state"></result>
<association property="userInfo"
resultMap="com.example.demo.mapper.UserMapper.BaseMap"
columnPrefix="u_"></association>
</resultMap>
<select id="getArticleById" resultMap="BaseMap">
select a.*,u.* from articleinfo a left join userinfo u on a.uid=u.id
</select>
</mapper>以上使? <association>標(biāo)簽,表示?對?的結(jié)果映射:
property 屬性:指定 Article 中對應(yīng)的屬性,即?戶。
resultMap 屬性:指定關(guān)聯(lián)的結(jié)果集映射,將基于該映射配置來組織?戶數(shù)據(jù)。
columnPrefix 屬性:綁定?對?對象時,因為對應(yīng)的是用戶表 ,所以是“u-”是通過 columnPrefix+association.resultMap.column 來映射結(jié)果集字段。 association.resultMap.column是指 <association>標(biāo)簽中 resultMap屬性,對應(yīng)的結(jié)果集映射中,column字段

單元測試
//將類屬性注入
@Resource
private ArticleMapper articleMapper;
@Test
void getArticleById() {
ArticleInfo articleInfo = articleMapper.getArticleById(1);
log.info("查詢結(jié)果:" + articleInfo );
}查詢結(jié)果

6.4 一對多
一個用戶對應(yīng)多篇文章
實體類
@Data
public class UserInfo {
private Integer id;
//private String username;//用于resultType
private String name; //用于 resultMap
private String password;
private String photo;
private String createtime;
private String updatetime;
private int state;
//一對多
private List<ArticleInfo> artlist;
}mapper
//一對多,多表查詢
//根據(jù)用戶 id 查詢用戶及用戶發(fā)表的所有文章
public UserInfo getUserAndArticleByUid(@Param("uid") Integer uid);XML
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<!--主鍵映射-->
<id column="id" property="id"></id>
<!--普通屬性映射-->
<result column="username" property="name"></result>
<result column="password" property="password"></result>
<result column="photo" property="photo"></result>
<result column="createtime" property="createtime"></result>
<result column="updatetime" property="updatetime"></result>
<result column="state" property="state"></result>
<!--多表查詢-->
<collection property="artlist"
resultMap="com.example.demo.mapper.ArticleMapper.BaseMap"
columnPrefix="a_">
</collection>
</resultMap>
<!--多表查詢-->
<select id="getUserAndArticleByUid" resultMap="BaseMap">
select u.*,a.id a_id,a.title a_title,a.content a_content,
a.createtime a_createtime,
a.updatetime a_updatetime from userinfo u left join articleinfo a
on u.id=a.uid where u.id=#{uid}
</select>
單元測試
@Test
void getUserAndArticleByUid() {
UserInfo userInfo = userMapper.getUserAndArticleByUid(1);
log.info("用戶詳情:" + userInfo);
}7.動態(tài)SQL使用
動態(tài)SQL是mybatis 的強大特性之一,能夠完成不同條件的SQL拼接
7.1 <if> 標(biāo)簽
在填寫個人信息時,會經(jīng)常遇到一些必填項,一些非必填項,如下

注冊分為兩種字段:必填字段和?必填字段,那如果在添加?戶的時候有不確定的字段傳?,程序應(yīng)該如何實現(xiàn)呢? 這個時候就需要使?動態(tài)標(biāo)簽 <if> 來判斷了:
判斷一個參數(shù)是否有值,如果沒值,就會隱藏 if 中的SQL

現(xiàn)在有一張用戶表
在新增用戶的時候,將 photo 設(shè)為非比傳參數(shù)

1)傳入photo 時
mapper
//動態(tài)SQL,添加用戶,photo為非必傳參數(shù)
public int add2(UserInfo userInfo);UserMapper.xml
<!--動態(tài)SQL,添加用戶-->
<insert id="add2">
insert into userinfo(username,password
<if test="photo !=null">
,photo
</if>
) values(#{name}, #{password}
<if test="photo !=null">
, #{photo}
</if>
)
</insert>注意 test 中的 photo 和 #{},是傳?對象中的屬性,不是數(shù)據(jù)庫字段
單元測試
@Test
void add2() {
UserInfo userInfo = new UserInfo();
userInfo.setName("楊通");
userInfo.setPassword("123");
userInfo.setPhoto("123.jpg");
int result = userMapper.add2(userInfo);
log.info("添加用戶:" + result);
}添加結(jié)果


2)不傳入 photo 時
不用像沒使用動態(tài)SQL時,將 userInfo.setPhoto(""); 設(shè)為空,直接忽略不寫就行了
@Test
void add2() {
UserInfo userInfo = new UserInfo();
userInfo.setName("黃空");
userInfo.setPassword("123");
//userInfo.setPhoto("123.jpg");
int result = userMapper.add2(userInfo);
log.info("添加用戶:" + result);
}動態(tài)SQL直接忽略photo,添加成功


7.2 <trim> 標(biāo)簽
最主要的作用:去除SQL語句前后多余的某個字符
語法:

<trim>標(biāo)簽中有如下屬性:
prefix: 表示這個語句快,以prefix的值作為前綴
suffix:表示整個語句塊,以suffix的值作為后綴
prefixOverrides:表示整個語句塊要去除掉的前綴
suffixOverrides:表示整個語句塊要去除掉的后綴
UserMapper
//動態(tài)SQL, <trim> 標(biāo)簽。添加用戶,photo為非必傳參數(shù)
public int add3(UserInfo userInfo);UserMapper.xml
<!--動態(tài)SQL,<trim> 標(biāo)簽。添加用戶-->
<insert id="add3">
insert into userinfo
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
<!--這里拼接的是數(shù)據(jù)庫中的字段-->
username,
</if>
<if test="password != null">
password,
</if>
<if test="photo != null">
photo
</if>
</trim>
values
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">
#{name},
</if>
<if test="password != null">
#{password},
</if>
<if test="photo != null">
#{photo}
</if>
</trim>
</insert>單元測試
這里不傳photo,看拼接的字段前的一個逗號是否還在
@Test
void add3() {
UserInfo userInfo = new UserInfo();
userInfo.setName("黃小小");
userInfo.setPassword("123");
//userInfo.setPhoto("123.jpg"); 這里不傳,看拼接的字段前的一個逗號是否還在
int result = userMapper.add2(userInfo);
log.info("添加用戶:" + result);
}

7.3 <where> 標(biāo)簽
主要作用:實現(xiàn)查詢中的 where SQL替換,它可以實現(xiàn)如果沒有任何的查詢條件,那么他可以因此查詢中的 where SQL ,但如果存在查詢中條件,那么會生成where的 SQL查詢,并且使用 where 標(biāo)簽可以自動的去除最后一個 and字符。
1)SQL 替換
根據(jù) id 查詢用戶:
<!-- 根據(jù) id 查詢用戶 -->
<select id="getUserById" resultMap="BaseMap">
select * from userinfo
<where>
<if test="id != null">
id=#{id}
</if>
</where>
</select>
當(dāng)傳入的 id 為 null 時
@Test
void getUserById() {
UserInfo userInfo = userMapper.getUserById(null);
//Assertions.assertNotNull(userInfo);
log.info("查詢行數(shù):" + userInfo);
}
2)去除 and

或者通過 id 或者 username 來查詢時,如果username 為空就會去掉
7.4 <set> 標(biāo)簽
作用:進行修改操作是,配合 if 來處理非必傳字段,他的特點是主動去除最后一個英文逗號
語法:
update table_name
<set>
<if test="xxx">
...
</if>
...
</set>
where ...1)修改用戶名
UserMapper
//動態(tài)SQL, <set> 標(biāo)簽。修改用戶
public int update2(UserInfo userInfo);UserMapper.xml
<update id="update2">
update userinfo
<set>
<if test="name != null">
username=#{name},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="photo != null">
photo = #{photo}
</if>
</set>
</update>單元測試
@Test
void update2() {
UserInfo userInfo = new UserInfo();
userInfo.setId(1); //查找 id 為 1 的用戶
userInfo.setName("fei"); // 將用戶名修改為 fei
int result = userMapper.update2(userInfo);
log.info("修改結(jié)果: " + result);
}

7.5 <foreach> 標(biāo)簽
對集合進?遍歷時可以使?該標(biāo)簽。<foreach>標(biāo)簽有如下屬性:
collection: 綁定方法參數(shù)中的集合,如List 、Set、Map或數(shù)組對象
item: 遍歷時的每一個對象
open:語句塊開頭的字符串
close:語句塊結(jié)束的字符串
separator:每次遍歷之間間隔的字符串
示例:根據(jù)用戶 id 來對用戶進行刪除
UserMapper
//動態(tài)SQL,<foreach>,刪除多個用戶
public int delId(List<Integer> ids);UserMapper.xml
<!--動態(tài)SQL,刪除多個用戶-->
<delete id="delId">
delete from userinfo where id in
<foreach collection="ids" open="(" close=")" item="id" separator=",">
#{id}
</foreach>
</delete>單元測試
@Test
void delId() {
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(4);
int result = userMapper.delId(list);
log.info("刪除的行數(shù):" + result);
}結(jié)果


總結(jié)
到此這篇關(guān)于MyBatis后端對數(shù)據(jù)庫進行增刪改查等操作的文章就介紹到這了,更多相關(guān)MyBatis后端對數(shù)據(jù)庫操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java畢業(yè)設(shè)計實戰(zhàn)之圖片展覽館管理系統(tǒng)的實現(xiàn)
這是一個使用了java+Springboot+SpringMVC+JPA+Jsp+maven+mysql開發(fā)的圖片展覽館管理系統(tǒng),是一個畢業(yè)設(shè)計的實戰(zhàn)練習(xí),具有圖片展覽管理該有的所有功能,感興趣的朋友快來看看吧2022-01-01
Mybatis?Plus?中的LambdaQueryWrapper示例詳解
這篇文章主要介紹了Mybatis?Plus?中的LambdaQueryWrapper,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-03-03

