這是mybatis系列第2篇,沒看前文的建議先去【Java冢狐】公眾號中查看前文,方便理解和掌握這篇文章主要接著前文介紹了如何創建并使用Mybatis,
實戰演練
上一篇文章中我們大體介紹了MyBatis是如何使用的以及其內部的一些邏輯,也輔助了一些代碼進行了講解,下面我們就把這些代碼寫完,讓整個程式運行起來,
準備資料庫
mysql中運行下面腳本:創建一個資料庫
/*創建資料庫mybatisdemo*/
DROP DATABASE IF EXISTS `mybatisdemo`;
CREATE DATABASE `mybatisdemo`;
USE `mybatisdemo`;
/*創建表結構*/
DROP TABLE IF EXISTS `user`;
CREATE TABLE user (
id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主鍵,用戶id,自動增長',
`name` VARCHAR(32) NOT NULL DEFAULT '' COMMENT '姓名',
`age` SMALLINT NOT NULL DEFAULT 1 COMMENT '年齡',
`salary` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '薪水'
) COMMENT '用戶表';
SELECT * FROM user;
上面腳本中,創建了一個mybatisdemo資料庫,然后創建了一個用戶表,里面有4個欄位,id為主鍵且自動增長,
實作的功能
基于user表,我們主要使用mybatis來演示以下幾個功能
- 通用的插入操作:支持動態插入,根據傳入的欄位的值,動態生成insert陳述句
- 批量插入功能
- 通用的更新操作:支持動態更新,根據傳入的欄位的值,動態生成update陳述句
- 通用的查詢操作:支持各種組合條件查詢、分頁、排序等各種復雜查詢需求
創建maven專案
idea中創建maven專案,創建一個父專案mybatis-demo和一個子專案chat01,如下所示
專案結構
如下圖:


引入mybatis依賴
mybatis-demo/pom.xml內容如下:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 配置maven編譯的時候采用的編譯器版本 -->
<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
<!-- 指定源代碼是什么版本的,如果原始碼和這個版本不符將報錯,maven中執行編譯的時候會用到這個配置,默認是1.5,這個相當于javac命令后面的-source引數 -->
<maven.compiler.source>1.8</maven.compiler.source>
<!-- 該命令用于指定生成的class檔案將保證和哪個版本的虛擬機進行兼容,maven中執行編譯的時候會用到這個配置,默認是1.5,這個相當于javac命令后面的-target引數 -->
<maven.compiler.target>1.8</maven.compiler.target>
<mybatis.version>3.5.3</mybatis.version>
<mysql.version>5.1.47</mysql.version>
<lombok.version>1.18.10</lombok.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
</dependencies>
</dependencyManagement>
chat01/pom.xml內容如下:
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies>
上面我們引入了mybatis需要的包、mysql jdbc驅動、lombok、單元測驗需要的junit包、日志輸出需要的logback包,
配置logback
mybatis在運行程序中會輸出一些日志,比如sql資訊、sql的引數資訊、執行的結果等資訊,mybatis中會通過logback輸出出來,
在chat01/src/main/resources目錄中新建檔案logback.xml,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<appender name="STDOUT" >
<encoder>
<pattern>%d{mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="zhonghu" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
</logger>
</configuration>
創建mybatis相關檔案
user.xml
chat01/src/main/resources目錄中新建user.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="zhonghu.mybatis.chat01.UserMapper">
<!-- 插入 -->
<insert id="insert" parameterType="zhonghu.mybatis.chat01.UserModel" keyProperty="id" useGeneratedKeys="true">
<![CDATA[ INSERT INTO `user` ]]>
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id!=null">
<![CDATA[ `id`, ]]>
</if>
<if test="name!=null">
<![CDATA[ `name`, ]]>
</if>
<if test="age!=null">
<![CDATA[ `age`, ]]>
</if>
<if test="salary!=null">
<![CDATA[ `salary`, ]]>
</if>
</trim>
<![CDATA[ VALUES ]]>
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id!=null">
<![CDATA[ #{id}, ]]>
</if>
<if test="name!=null">
<![CDATA[ #{name}, ]]>
</if>
<if test="age!=null">
<![CDATA[ #{age}, ]]>
</if>
<if test="salary!=null">
<![CDATA[ #{salary}, ]]>
</if>
</trim>
</insert>
<!-- 批量插入 -->
<insert id="insertBatch" parameterType="map">
<![CDATA[ INSERT INTO `user` (`id`, `name`, `age`, `salary`) VALUES ]]>
<foreach collection="list" separator="," item="item">
(#{item.id}, #{item.name}, #{item.age}, #{item.salary})
</foreach>
</insert>
<!-- 更新 -->
<update id="update" parameterType="zhonghu.mybatis.chat01.UserModel">
<![CDATA[ UPDATE `user` ]]>
<set>
<if test="name!=null">
<![CDATA[ `name` = #{name}, ]]>
</if>
<if test="age!=null">
<![CDATA[ `age` = #{age}, ]]>
</if>
<if test="salary!=null">
<![CDATA[ `salary` = #{salary}, ]]>
</if>
</set>
<where>
<if test="id!=null">
<![CDATA[ AND `id` = #{id} ]]>
</if>
</where>
</update>
<!-- 更新 -->
<update id="updateByMap" parameterType="map">
<![CDATA[ UPDATE `user` ]]>
<set>
<if test="name!=null">
<![CDATA[ `name` = #{name}, ]]>
</if>
<if test="age!=null">
<![CDATA[ `age` = #{age}, ]]>
</if>
<if test="salary!=null">
<![CDATA[ `salary` = #{salary}, ]]>
</if>
</set>
<where>
<if test="id!=null">
<![CDATA[ AND `id` = #{id} ]]>
</if>
</where>
</update>
<!-- 洗掉 -->
<delete id="delete" parameterType="map">
<![CDATA[
DELETE FROM `user`
]]>
<where>
<if test="id!=null">
<![CDATA[ AND `id` = #{id} ]]>
</if>
</where>
</delete>
<!-- 查詢記錄 -->
<select id="getModelList" parameterType="map" resultType="zhonghu.mybatis.chat01.UserModel">
<![CDATA[
SELECT
]]>
<choose>
<when test="tableColumnList!=null and tableColumnList.size() >= 1">
<foreach collection="tableColumnList" item="item" separator=",">
<![CDATA[ ${item} ]]>
</foreach>
</when>
<otherwise>
<![CDATA[
`id`,
`name`,
`age`,
`salary`
]]>
</otherwise>
</choose>
<![CDATA[
FROM
`user` a
]]>
<where>
<if test="id!=null and id.toString()!=''">
<![CDATA[ AND a.`id` = #{id} ]]>
</if>
<if test="idList!=null and idList.size() >= 1">
<![CDATA[ AND a.`id` IN ]]>
<foreach collection="idList" item="item" open="(" separator="," close=")">
<![CDATA[ #{item} ]]>
</foreach>
</if>
<if test="name!=null and name.toString()!=''">
<![CDATA[ AND a.`name` = #{name} ]]>
</if>
<if test="age!=null and age.toString()!=''">
<![CDATA[ AND a.`age` = #{age} ]]>
</if>
<if test="salary!=null and salary.toString()!=''">
<![CDATA[ AND a.`salary` = #{salary} ]]>
</if>
<if test="nameLike!=null and nameLike.toString()!=''">
<![CDATA[ AND a.`name` like '%${nameLike}%' ]]>
</if>
<if test="salaryGte!=null and salaryGte.toString()!=''">
<![CDATA[ AND a.`salary` >= #{salaryGte} ]]>
</if>
</where>
<if test="sort!=null and sort.toString()!=''">
<![CDATA[ order by ${sort} ]]>
</if>
<if test="skip!=null and pageSize!=null">
<![CDATA[ LIMIT #{skip},#{pageSize} ]]>
</if>
</select>
</mapper>
mybatis-config.xml
chat01/src/main/resources目錄中新建mybatis-config.xml,內容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties>
<property name="driver" value="https://www.cnblogs.com/javazhonghu/p/com.mysql.jdbc.Driver"/>
<property name="url" value="https://www.cnblogs.com/javazhonghu/p/jdbc:mysql://localhost:3306/mybatisdemo?characterEncoding=UTF-8"/>
<property name="username" value="https://www.cnblogs.com/javazhonghu/p/root"/>
<property name="password" value="https://www.cnblogs.com/javazhonghu/p/123456"/>
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="https://www.cnblogs.com/javazhonghu/p/${driver}"/>
<property name="url" value="https://www.cnblogs.com/javazhonghu/p/${url}"/>
<property name="username" value="https://www.cnblogs.com/javazhonghu/p/${username}"/>
<property name="password" value="https://www.cnblogs.com/javazhonghu/p/${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/user.xml"/>
</mappers>
</configuration>
UserMapper介面
package zhonghu.mybatis.chat01;
import java.util.List;
import java.util.Map;
public interface UserMapper {
/**
* 插入用戶資訊
*
* @param userModel
* @return
*/
void insert(UserModel userModel);
/**
* 批量插入用戶資訊
*
* @param userModelList
*/
void insertBatch(List<UserModel> userModelList);
/**
* 更新用戶資訊
*
* @param userModel
* @return
*/
int update(UserModel userModel);
/**
* 通過map來更新用戶記錄
*
* @param map
* @return
*/
int updateByMap(Map<String, Object> map);
/**
* 通過map來洗掉用戶記錄
*
* @param map
* @return
*/
int delete(Map<String, Object> map);
/**
* 查詢用戶串列
*
* @param map
* @return
*/
List<UserModel> getModelList(Map<String, Object> map);
}
UserModel類
package zhonghu.mybatis.chat01;
import lombok.*;
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class UserModel {
private Long id;
private String name;
private Integer age;
private Double salary;
}
這個類上面的注解都是都是lombok中的,通過這些注解,lombok可以幫助我們自動生成上面4個欄位的get方法、set方法、無參構造方法、有參有參構造方法、builder模式構建物件的代碼、重寫toString方法,這些都在代碼編譯為位元組碼之前會寫進去,通過lombok代碼是不是精簡了很多,
UserUtil類
package zhonghu.mybatis.chat01;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
@Slf4j
public class UserUtil {
private static SqlSessionFactory sqlSessionFactory = build();
public static SqlSessionFactory build() {
try {
return new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
} catch (IOException e) {
log.error(e.getMessage(), e);
throw new RuntimeException(e);
}
}
@FunctionalInterface
public interface SessionCall<O> {
O call(SqlSession session) throws Exception;
}
@FunctionalInterface
public interface MapperCall<T, O> {
O call(T mapper) throws Exception;
}
public static <T, O> O callMapper(Class<T> tClass, MapperCall<T, O> mapper) throws Exception {
return call(session -> mapper.call(session.getMapper(tClass)));
}
public static <O> O call(SessionCall<O> sessionCall) throws Exception {
try (SqlSession session = sqlSessionFactory.openSession(true);) {
return sessionCall.call(session);
}
}
}
創建單元測驗類UserMapperTest
chat01\src\test\java\zhonghu\mybatis\chat01中創建UserMapperTest,代碼如下:
package zhonghu.mybatis.chat01;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.*;
import java.util.stream.Collectors;
@Slf4j
public class UserMapperTest {
//動態插入
@Test
public void insert() throws Exception {
UserModel userModel1 = UserModel.builder().name("Java冢狐").build();
UserUtil.callMapper(UserMapper.class, mapper -> {
mapper.insert(userModel1);
return null;
});
log.info("插入結果:{}", this.getModelById(userModel1.getId()));
log.info("---------------------");
UserModel userModel2 = UserModel.builder().name("冢狐").age(23).salary(50000.00).build();
UserUtil.callMapper(UserMapper.class, mapper -> {
mapper.insert(userModel2);
return null;
});
log.info("插入結果:{}", this.getModelById(userModel2.getId()));
}
//批量插入
@Test
public void insertBatch() throws Exception {
List<UserModel> userModelList = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
userModelList.add(UserModel.builder().name("Java冢狐-" + i).age(23 + i).salary(10000.00 * i).build());
userModelList.add(UserModel.builder().name("Mybatis-" + i).age(18 + i).salary(10000.00 * i).build());
}
UserUtil.callMapper(UserMapper.class, mapper -> {
mapper.insertBatch(userModelList);
return null;
});
List<UserModel> userModelList1 = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
log.info("結果:{}", userModelList1);
}
//根據用戶id洗掉資料
@Test
public void delete() throws Exception {
Map<String, Object> map = new HashMap<>();
//需要洗掉的用戶id
map.put("id", 1);
Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.delete(map));
log.info("洗掉行數:{}", count);
}
//動態更新
@Test
public void update() throws Exception {
//將userId=2的name修改為:修改冢狐
Long userId1 = 2L;
Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId1).name("修改冢狐").build()));
log.info("更新行數:{}", count);
log.info("---------------------");
//將userId=3的name修改為:修改冢狐,薪水為:6666.66
Long userId2 = 3L;
count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId2).name("修改冢狐").salary(6666.66D).build()));
log.info("更新行數:{}", count);
}
//按用戶id查詢
public UserModel getModelById(Long userId) throws Exception {
//查詢指定id的資料
Map<String, Object> map = new HashMap<>();
map.put("id", userId);
return UserUtil.callMapper(UserMapper.class, mapper -> {
List<UserModel> userModelList = mapper.getModelList(map);
if (userModelList.size() == 1) {
return userModelList.get(0);
}
return null;
});
}
//查詢所有資料
@Test
public void getModelList1() throws Exception {
List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
log.info("結果:{}", userModelList);
}
//查詢多個用戶id對應的資料
@Test
public void getModelListByIds() throws Exception {
List<Integer> idList = Arrays.asList(2, 3, 4).stream().collect(Collectors.toList());
Map<String, Object> map = new HashMap<>();
map.put("idList", idList);
List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
log.info("結果:{}", userModelList);
}
//多條件 & 指定回傳的列
@Test
public void getModelList2() throws Exception {
//查詢姓名中包含Java冢狐以及薪資大于3萬的用戶id、姓名
Map<String, Object> map = new HashMap<>();
map.put("nameLike", "Java冢狐");
map.put("salaryGte", 30000.00D);
//需要回傳的列
List<String> tableColumnList = new ArrayList<>();
tableColumnList.add("id");
tableColumnList.add("name");
map.put("tableColumnList", tableColumnList);
List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
log.info("結果:{}", userModelList);
}
//條件過濾 & 排序 & 分頁查詢資料 & 只回傳用戶id、salary
@Test
public void getPage() throws Exception {
//查詢姓名中包含Java冢狐以及薪資大于3萬的用戶id,按照薪資倒敘,每頁5條取第1頁
Map<String, Object> map = new HashMap<>();
map.put("nameLike", "Java冢狐");
map.put("salaryGte", 30000.00D);
//加入排序引數
map.put("sort", "salary desc");
//加入分頁引數
int page = 1;
int pageSize = 5;
map.put("skip", (page - 1) * pageSize);
map.put("pageSize", pageSize);
//加入需要回傳的列
List<String> tableColumnList = new ArrayList<>();
tableColumnList.add("id");
tableColumnList.add("salary");
map.put("tableColumnList", tableColumnList);
List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
log.info("結果:{}", userModelList);
}
}
專案最終結構如下

測驗:動態插入
運行動態插入,輸出如下:
29:45.734 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Preparing: INSERT INTO `user` ( `name` ) VALUES ( ? )
29:45.755 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Parameters: Java冢狐(String)
29:45.843 [main] DEBUG z.mybatis.chat01.UserMapper.insert - <== Updates: 1
29:45.859 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` = ?
29:45.859 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 1(Long)
29:45.871 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 1
29:45.871 [main] INFO z.mybatis.chat01.UserMapperTest - 插入結果:UserModel(id=1, name=Java冢狐, age=1, salary=0.0)
29:45.873 [main] INFO z.mybatis.chat01.UserMapperTest - ---------------------
29:45.873 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Preparing: INSERT INTO `user` ( `name`, `age`, `salary` ) VALUES ( ?, ?, ? )
29:45.874 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Parameters: 冢狐(String), 23(Integer), 50000.0(Double)
29:46.081 [main] DEBUG z.mybatis.chat01.UserMapper.insert - <== Updates: 1
29:46.082 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` = ?
29:46.082 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 2(Long)
29:46.083 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 1
29:46.083 [main] INFO z.mybatis.chat01.UserMapperTest - 插入結果:UserModel(id=2, name=冢狐, age=23, salary=50000.0)
- 資料庫資料變為:

這個方法主要有4步操作:
- 插入一條用戶記錄,用戶記錄只有name欄位有值
- 去db中查詢步驟1中插入的記錄
- 插入一條用戶記錄,這次插入的記錄所有欄位都指定了值
- 去db中查詢步驟3中插入的記錄
兩次插入呼叫都是mapper.insert方法,傳入的都是UserModel物件,唯一不同的是這個物件構建的時候欄位的值不一樣,最后再認真看一下上面輸出的sql,產生的2個insert也是不一樣的,這個mapper.insert方法可以根據UserModel物件欄位是否有值來組裝我們需要的sql,這就實作了動態插入
測驗:批量插入
運行批量插入,輸出如下:
33:49.134 [main] DEBUG z.m.chat01.UserMapper.insertBatch - ==> Preparing: INSERT INTO `user` (`id`, `name`, `age`, `salary`) VALUES (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?)
33:49.155 [main] DEBUG z.m.chat01.UserMapper.insertBatch - ==> Parameters: null, Java冢狐-1(String), 24(Integer), 10000.0(Double), null, Mybatis-1(String), 19(Integer), 10000.0(Double), null, Java冢狐-2(String), 25(Integer), 20000.0(Double), null, Mybatis-2(String), 20(Integer), 20000.0(Double), null, Java冢狐-3(String), 26(Integer), 30000.0(Double), null, Mybatis-3(String), 21(Integer), 30000.0(Double), null, Java冢狐-4(String), 27(Integer), 40000.0(Double), null, Mybatis-4(String), 22(Integer), 40000.0(Double), null, Java冢狐-5(String), 28(Integer), 50000.0(Double), null, Mybatis-5(String), 23(Integer), 50000.0(Double)
33:49.378 [main] DEBUG z.m.chat01.UserMapper.insertBatch - <== Updates: 10
33:49.387 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a
33:49.387 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters:
33:49.397 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 12
33:49.397 [main] INFO z.mybatis.chat01.UserMapperTest - 結果:[UserModel(id=1, name=Java冢狐, age=1, salary=0.0), UserModel(id=2, name=冢狐, age=23, salary=50000.0), UserModel(id=3, name=Java冢狐-1, age=24, salary=10000.0), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0), UserModel(id=5, name=Java冢狐-2, age=25, salary=20000.0), UserModel(id=6, name=Mybatis-2, age=20, salary=20000.0), UserModel(id=7, name=Java冢狐-3, age=26, salary=30000.0), UserModel(id=8, name=Mybatis-3, age=21, salary=30000.0), UserModel(id=9, name=Java冢狐-4, age=27, salary=40000.0), UserModel(id=10, name=Mybatis-4, age=22, salary=40000.0), UserModel(id=11, name=Java冢狐-5, age=28, salary=50000.0), UserModel(id=12, name=Mybatis-5, age=23, salary=50000.0)]
這次批量插入了10條用戶記錄,可以看到有這樣的輸出:
33:49.378 [main] DEBUG z.m.chat01.UserMapper.insertBatch - <== Updates: 10
上面這個表示插入影響的行數,10表示插入了10行,
批量插入之后,又執行了全表查詢,這次插入了10條,加上前面的2個單條插入,表中總計12條記錄,
- 資料庫資料變為:

測驗:根據用戶id洗掉資料
運行洗掉,輸出如下:
44:52.064 [main] DEBUG z.mybatis.chat01.UserMapper.delete - ==> Preparing: DELETE FROM `user` WHERE `id` = ?
44:52.083 [main] DEBUG z.mybatis.chat01.UserMapper.delete - ==> Parameters: 1(Integer)
44:52.383 [main] DEBUG z.mybatis.chat01.UserMapper.delete - <== Updates: 1
44:52.386 [main] INFO z.mybatis.chat01.UserMapperTest - 洗掉行數:1
- 資料庫結果如下:

測驗:動態更新
運行動態更新代碼,輸出如下:
45:44.648 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Preparing: UPDATE `user` SET `name` = ? WHERE `id` = ?
45:44.670 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Parameters: 修改冢狐(String), 2(Long)
45:44.788 [main] DEBUG z.mybatis.chat01.UserMapper.update - <== Updates: 1
45:44.790 [main] INFO z.mybatis.chat01.UserMapperTest - 更新行數:1
45:44.792 [main] INFO z.mybatis.chat01.UserMapperTest - ---------------------
45:44.793 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Preparing: UPDATE `user` SET `name` = ?, `salary` = ? WHERE `id` = ?
45:44.793 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Parameters: 修改冢狐(String), 6666.66(Double), 3(Long)
45:44.980 [main] DEBUG z.mybatis.chat01.UserMapper.update - <== Updates: 1
45:44.981 [main] INFO z.mybatis.chat01.UserMapperTest - 更新行數:1
2個更新,呼叫都是mapper.update方法,傳入的都是UserModel型別的引數,只是2個UserModel物件的欄位值不一樣,最后產生的2個update陳述句也是不一樣的,這個update陳述句是mybatis動態組裝的,mybatis可以根據UserModel中欄位是否為NULL,來拼裝sql,
- 資料庫結果

測驗:動態查詢
查詢所有資料
運行查詢有資料代碼,輸出如下:
46:56.345 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a
46:56.364 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters:
46:56.376 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 11
46:56.380 [main] INFO z.mybatis.chat01.UserMapperTest - 結果:[UserModel(id=2, name=修改冢狐, age=23, salary=50000.0), UserModel(id=3, name=修改冢狐, age=24, salary=6666.66), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0), UserModel(id=5, name=Java冢狐-2, age=25, salary=20000.0), UserModel(id=6, name=Mybatis-2, age=20, salary=20000.0), UserModel(id=7, name=Java冢狐-3, age=26, salary=30000.0), UserModel(id=8, name=Mybatis-3, age=21, salary=30000.0), UserModel(id=9, name=Java冢狐-4, age=27, salary=40000.0), UserModel(id=10, name=Mybatis-4, age=22, salary=40000.0), UserModel(id=11, name=Java冢狐-5, age=28, salary=50000.0), UserModel(id=12, name=Mybatis-5, age=23, salary=50000.0)]
可以看到sql是沒有查詢條件的,
查詢多個用戶id對應的資料
運行查詢多個用戶id對應資料,輸出如下:
47:46.118 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` IN ( ? , ? , ? )
47:46.139 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 2(Integer), 3(Integer), 4(Integer)
47:46.150 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 3
47:46.151 [main] INFO z.mybatis.chat01.UserMapperTest - 結果:[UserModel(id=2, name=修改冢狐, age=23, salary=50000.0), UserModel(id=3, name=修改冢狐, age=24, salary=6666.66), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0)]
上面這個按照id串列查詢也是比較常用的,比如我們在電商中查詢訂單串列,還需要查詢每個訂單對應的商品,此時可以先查詢訂單串列,然后在通過訂單串列拿到所有的商品id集合,然后通過商品id集合去通過上面的方式檢索商品資訊,只需要2次查詢就可以查詢出訂單及商品的資訊了,
多條件 & 指定回傳的列
運行多條件查詢陳述句,查詢姓名中包含Java冢狐以及薪資大于3萬的用戶id、姓名,輸出如下:
48:34.925 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT id , name FROM `user` a WHERE a.`name` like '%Java冢狐%' AND a.`salary` >= ?
48:34.945 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 30000.0(Double)
48:34.955 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 3
48:34.955 [main] INFO z.mybatis.chat01.UserMapperTest - 結果:[UserModel(id=7, name=Java冢狐-3, age=null, salary=null), UserModel(id=9, name=Java冢狐-4, age=null, salary=null), UserModel(id=11, name=Java冢狐-5, age=null, salary=null)]
看一下上面select陳述句,select后面只有id,name2個欄位,where后面有多個條件,這種查詢也是比較常用的,有些表可能有幾十個欄位,可能我們只需要幾個欄位,就可以使用上面這種查詢,
條件過濾 & 排序 & 分頁查詢資料 & 只回傳用戶id、salary
運行分頁查詢,查詢姓名中包含Java冢狐以及薪資大于3萬的用戶id,按照薪資倒敘,每頁5條取第1頁,輸出如下:
49:03.709 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Preparing: SELECT id , salary FROM `user` a WHERE a.`name` like '%Java冢狐%' AND a.`salary` >= ? order by salary desc LIMIT ?,?
49:03.728 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 30000.0(Double), 0(Integer), 5(Integer)
49:03.739 [main] DEBUG z.m.chat01.UserMapper.getModelList - <== Total: 3
49:03.740 [main] INFO z.mybatis.chat01.UserMapperTest - 結果:[UserModel(id=11, name=null, age=null, salary=50000.0), UserModel(id=9, name=null, age=null, salary=40000.0), UserModel(id=7, name=null, age=null, salary=30000.0)]
大家主要看一下輸出的sql,如下:
SELECT id , salary FROM `user` a WHERE a.`name` like '%Java冢狐%' AND a.`salary` >= ? order by salary desc LIMIT ?,?
這個sql會根據查詢條件,自動構建出我們需要的sql,十分的方便和簡潔
案例總結
上面列舉的一些用例基本上包含了我們對db所需的大部分操作,動態sql處理方面體現的最為強勁,如果讓我們自己寫,我們需要寫很多判斷,而用mybatis這么簡單就實作了,我們在java代碼中沒有看到一個判斷拼接陳述句,而這些sql的判斷拼接都在一個檔案中:user.xml中,這個就是mybatis中核心的檔案,我們需要寫的sql及判斷邏輯基本上都在這個xml中,大家可以認真去看一下這個xml檔案,
最后
- 如果覺得看完有識訓,希望能關注一下,順便給我點個贊,這將會是我更新的最大動力,感謝各位的支持
- 歡迎各位關注我的公眾號【java冢狐】,專注于java和計算機基礎知識,保證讓你看完有所識訓,不信你打我
- 求一鍵三連:點贊、轉發、在看,
- 如果看完有不同的意見或者建議,歡迎多多評論一起交流,感謝各位的支持以及厚愛,
——我是冢狐,和你一樣熱愛編程,
歡迎關注公眾號“Java冢狐”獲取最新訊息
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/256605.html
標籤:Java
上一篇:抽象類
下一篇:微服務呼叫鏈日志追蹤分析
