閱讀提示: 本文預設已經預裝預裝maven 1、MyBatis概述 1.1 MyBatis概述 持久層框架,用於簡化JDBC開發,是對JDBC的封裝 持久層: 負責將數據保存到資料庫的代碼部分 Java EE三層架構:表現層、業務層、持久層 1.2 JDBC缺點 硬編碼,不利於維護 註冊驅動、獲取連 ...
目錄
閱讀提示:
本文預設已經預裝預裝maven
1、MyBatis概述
1.1 MyBatis概述
-
持久層框架,用於簡化JDBC開發,是對JDBC的封裝
持久層:
- 負責將數據保存到資料庫的代碼部分
- Java EE三層架構:表現層、業務層、持久層
1.2 JDBC缺點
- 硬編碼,不利於維護
- 註冊驅動、獲取連接
- SQL語句
- 操作繁瑣
- 手動設置參數
- 手動封裝結果集
1.3 MyBatis優化
- 硬編碼 --> 配置文件
- 繁瑣慚怍 --> 框架封裝自動完成
2、MyBatis快速入門
-
需求:查詢user表中的所有數據
-
SQL
create database mybatis; use mybatis; drop table if exists tb_user; create table tb_user( id int primary key auto_increment, username varchar(20), password varchar(20), gender char(1), addr varchar(30) ); INSERT INTO tb_user VALUES (1, 'zhangsan', '123', '男', '北京'); INSERT INTO tb_user VALUES (2, '李四', '234', '女', '天津'); INSERT INTO tb_user VALUES (3, '王五', '11', '男', '西安');
-
代碼實現
-
創建模塊,導入坐標
在pom.xml中配置文件中添加依賴的坐標
註意:需要在項目的resources目錄下創建logback的配置文件
<dependencies> <!--mybatis 依賴--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.5</version> </dependency> <!--mysql 驅動--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!--junit 單元測試--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!-- 添加slf4j日誌api --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.20</version> </dependency> <!-- 添加logback-classic依賴 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency> <!-- 添加logback-core依賴 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> </dependencies>
-
編寫MyBatis核心文件
核心文件用於替換信息,解決硬編碼問題
在模塊下的resources目錄下創建mybatis的配置文件
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> <environments default="development"> <environment id="development"> <!-- 採用JDBC的事務管理方式 --> <transactionManager type="JDBC"/> <!-- 資料庫連接信息 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- 載入SQL映射文件 --> <mappers> <mapper resource="UserMapper.xml"/> </mappers> </configuration>
-
編寫SQL映射文件
SQL映射文件用於統一管理SQL語句,解決硬編碼問題
在模塊的resources目錄下創建映射配置文件
UserMaooer.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:命名空間 --> <mapper namespace="test"> <!-- statement --> <select id="selectAll" resultType="priv.dandelion.entity.User"> select * from tb_user; </select> </mapper>
-
編碼
-
實體類
package priv.dandelion.entity; public class User { private Integer id; private String username; private String password; private String gender; private String address; public User() { } public User(Integer id, String username, String password, String gender, String address) { this.id = id; this.username = username; this.password = password; this.gender = gender; this.address = address; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } 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 getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", gender='" + gender + '\'' + ", address='" + address + '\'' + '}'; } }
-
測試類
public static void main(String[] args) throws IOException { // 載入mybatis的核心配置文件,獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取Session對象,執行SQL語句 SqlSession sqlSession = sqlSessionFactory.openSession(); // 執行SQL,處理結果 List<User> users = sqlSession.selectList("test.selectAll"); System.out.println(users); // 釋放資源 sqlSession.close(); }
-
-
3、Mapper代理開發
3.1 Mapper代理開發概述
解決形如上述測試類中
List<User> users = sqlSession.selectList("test.selectAll");
的硬編碼問題
- 解決原生方式中的硬編碼
- 簡化後期的SQL執行
3.2 使用Mapper代理要求
-
定義與SQL映射文件同名的Mapper介面,並且將Mapper介面和SQL映射文件放置在同一目錄下
maven項目開發時要求code和resources分開,可在resources中創建相同包文件來是實現上述效果
-
設置SQL映射文件的
namespace
屬性未Mapper介面的全限定名 -
在Mapper介面中定義方法,方法名就是SQL映射文件中SQL語句的
id
,並且參數類型和返回值類型一致
3.3 案例代碼實現
-
修改SQL映射文件
UserMapper.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:命名空間 --> <mapper namespace="priv.dandelion.mapper.UserMapper"> <select id="selectAll" resultType="priv.dandelion.entity.User"> select * from tb_user; </select> </mapper>
-
創建對應的Mapper介面
UserMapper.interface
public interface UserMapper { List<User> selectAll(); }
-
修改mybatis核心配置文件中載入SQL映射的
<mapper></mapper>
的路徑<mappers> <mapper resource="priv/dandelion/mapper/UserMapper.xml"/> </mappers>
-
測試代碼
public static void main(String[] args) throws IOException { // 載入mybatis的核心配置文件,獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取Session對象,執行SQL語句 SqlSession sqlSession = sqlSessionFactory.openSession(); // 執行SQL,處理結果 // 獲取UserMapper介面的代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> users = userMapper.selectAll(); System.out.println(users); // 釋放資源 sqlSession.close(); }
-
改進
如果Mapper介面名稱和SQL映射文件名稱相同,併在同一目錄下,則可以使用包掃描的方式簡化SQL映射文件的載入,簡化mybatis核心配置文件
<mappers> <!--載入sql映射文件--> <!-- <mapper resource="priv/dandelion/mapper/UserMapper.xml"/>--> <!--Mapper代理方式--> <package name="priv.dandelion.mapper"/> </mappers>
4、核心配置文件
4.1 多環境配置
在核心配置文件的
environments
標簽中其實是可以配置多個environment
,使用id
給每段環境起名,在environments
中使用default='環境id'
來指定使用哪兒段配置。我們一般就配置一個environment
即可
<?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>
<typeAliases>
<package name="priv.dandelion.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 採用JDBC的事務管理方式 -->
<transactionManager type="JDBC"/>
<!-- 資料庫連接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!-- JDBC連接資料庫,SSL,Unicode字元集,UTF-8編碼 -->
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
<environment id="test">
<transactionManager type="JDBC"/>
<!-- 資料庫連接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///mybatis?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- 載入SQL映射文件 -->
<mappers>
<!-- <mapper resource="priv/dandelion/mapper/UserMapper.xml"/>-->
<package name="priv.dandelion.mapper"/>
</mappers>
</configuration>
4.2 類型別名
映射配置文件中的
resultType
屬性需要配置數據封裝的類型(類的全限定名),繁瑣Mybatis 提供了
類型別名
(typeAliases) 可以簡化這部分的書寫
<configuration>
<!-- name屬性未實體類所在的包 -->
<typeAliases>
<package name="priv.dandelion.entity"/>
</typeAliases>
</configuration>
<mapper namespace="priv.dandelion.mapper.UserMapper">
<!-- resultType的值不區分大小寫 -->
<select id="selectAll" resultType="user">
select * from tb_user;
</select>
</mapper>
5、配置文件實現CRUD
5.1 環境準備
-
SQL
-- 刪除tb_brand表 drop table if exists tb_brand; -- 創建tb_brand表 create table tb_brand ( -- id 主鍵 id int primary key auto_increment, -- 品牌名稱 brand_name varchar(20), -- 企業名稱 company_name varchar(20), -- 排序欄位 ordered int, -- 描述信息 description varchar(100), -- 狀態:0:禁用 1:啟用 status int ); -- 添加數據 insert into tb_brand (brand_name, company_name, ordered, description, status) values ('三隻松鼠', '三隻松鼠股份有限公司', 5, '好吃不上火', 0), ('華為', '華為技術有限公司', 100, '華為致力於把數字世界帶入每個人、每個家庭、每個組織,構建萬物互聯的智能世界', 1), ('小米', '小米科技有限公司', 50, 'are you ok', 1); SELECT * FROM tb_brand;
-
實體類
public class Brand { private Integer id; private String brand_name; private String company_name; private Integer ordered; private String description; private Integer status; public Brand() { } public Brand( Integer id, String brand_name, String company_name, Integer ordered, String description, Integer status ) { this.id = id; this.brand_name = brand_name; this.company_name = company_name; this.ordered = ordered; this.description = description; this.status = status; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getBrand_name() { return brand_name; } public void setBrand_name(String brand_name) { this.brand_name = brand_name; } public String getCompany_name() { return company_name; } public void setCompany_name(String company_name) { this.company_name = company_name; } public Integer getOrdered() { return ordered; } public void setOrdered(Integer ordered) { this.ordered = ordered; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } @Override public String toString() { return "Brand{" + "id=" + id + ", brand_name='" + brand_name + '\'' + ", company_name='" + company_name + '\'' + ", ordered=" + ordered + ", description='" + description + '\'' + ", status=" + status + '}'; } }
-
安裝插件MyBatisX
-
步驟
- 編寫介面方法
Mapper介面
- 參數
- 返回值
- 在SQL映射文件中編寫SQL語句
- MyBatisX插件自動補全
- 編寫SQL
- 若資料庫欄位名和實體類欄位名不同,則需要解決該問題(見 5.2 SQL映射文件)
- 編寫執行測試
- 獲取SqlSessionFactory
- 獲取sqlSession對象
- 獲取mapper介面的代理對象
- 執行方法
- 釋放資源
- 編寫介面方法
5.2 查詢所有數據
本節要點:
- 測試類的編寫方式
- 解決資料庫欄位和實體類欄位名不同的問題
-
編寫介面方法
public interface BrandMapper { public List<Brand> selectAll(); }
-
編寫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:命名空間 --> <mapper namespace="priv.dandelion.mapper.BrandMapper"> <!-- 起別名解決資料庫和實體類欄位名不同問題 <sql id="brand_column"> id, brand_name as brandName, company_name as companyName, ordered, description, status </sql> <select id="selectAll" resultType="priv.dandelion.entity.Brand"> select * from tb_brand; select <include refid="brand_column"/> from tb_brand; </select> --> <!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName" /> <result column="company_name" property="companyName" /> </resultMap> <!-- 不使用resultType, 使用resultMap --> <select id="selectAll" resultMap="brandResultMap"> select * from tb_brand; </select> </mapper>
-
編寫測試方法
@Test public void testSelectAll() throws IOException { // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 List<Brand> brands = brandMapper.selectAll(); System.out.println(brands); // 釋放資源 sqlSession.close(); }
5.3 查詢
本節要點:
- MyBatis的SQL映射文件中,SQL語句如何接收對應參數
-
使用占位符進行參數傳遞
-
占位符名稱和參數保持一致
-
占位符
#{占位符名}
:會替換為?
,防止SQL註入,一般用於替換欄位值${占位符名}
:存在SQL註入問題,一般用於執行動態SQL語句,如表名列名不固定的情況(見)
-
-
編寫介面方法
void update(Brand brand);
-
SQL映射文件查詢代碼標簽
<resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName" /> <result column="company_name" property="companyName" /> </resultMap> <select id="selectById" resultMap="brandResultMap"> select * from tb_brand where id = #{id}; </select>
-
測試方法
@Test public void testSelectByCondition() throws IOException { // 接收參數 int status = 1; String companyName = "華為"; String brandName = "華為"; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName); System.out.println(brands); // 釋放資源 sqlSession.close(); }
5.4 多條件查詢
本節要點:
- 多條件查詢:如果有多個參數,需要使用
@Paran("SQL參數占位符名稱")
註解- 多條件的動態條件查詢:對象屬性名稱要和參數占位符名稱一致
(詳見5-2解決資料庫欄位和實體類欄位名不同的問題)- 單條件的動態條件查詢:保證key要和參數占位符名稱一致
-
多條件查詢
-
SQL映射文件
<!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap> <!-- 條件查詢 --> <select id="selectByCondition" resultMap="brandResultMap"> select * from tb_brand where status = #{status} and company_name like #{companyName} and brand_name like #{brandName} </select>
-
散裝參數
-
介面
// 散裝參數 List<Brand> selectByCondition( @Param("status")int status, @Param("companyName")String companyName, @Param("brandName")String brandName );
-
測試方法
@Test public void testSelectByCondition() throws IOException { // 接收參數 int status = 1; String companyName = "華為"; String brandName = "華為"; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 companyName = "%" + companyName + "%"; brandName = "%" + brandName + "%"; List<Brand> brands = brandMapper.selectByCondition( status, companyName, brandName); System.out.println(brands); // 釋放資源 sqlSession.close(); }
-
-
對象參數
-
介面
// 對象參數 List<Brand> selectByCondition(Brand brand);
-
測試方法
// 細節不表,僅展示執行方法 // 執行方法 Brand brand = new Brand(); brand.setStatus(status); brand.setCompanyName("%" + companyName + "%"); brand.setBrandName("%" + brandName + "%"); List<Brand> brands = brandMapper.selectByCondition(brand); System.out.println(brands);
-
-
map集合參數
-
介面
// 集合參數 List<Brand> selectByCondition(Map map);
-
測試方法
// 細節不表,僅展示執行方法 // 執行方法 Map map = new HashMap(); map.put("status", status); map.put("companyName", "%" + companyName + "%"); map.put("brandName", "%" + brandName + "%"); List<Brand> brands = brandMapper.selectByCondition(map); System.out.println(brands);
-
-
-
多條件動態條件查詢
優化條件查詢,如頁面上表單存在多個條件選項,但實際填寫表單僅使用部分條件篩選的情況
-
SQL映射文件
<!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap> <!-- 動態條件查詢 --> <select id="selectByCondition" resultMap="brandResultMap"> select * from tb_brand <where> <if test="status != null"> status = #{status} </if> <if test="companyName != null"> and company_name like #{companyName} </if> <if test="brandName != null"> and brand_name like #{brandName} </if> </where> </select>
註:
-
if
標簽的test
屬性中可以包含邏輯或等邏輯判斷,使用and
、or
進行連接 -
若條件SQL中同時包含
AND
等連接符- 對所有的條件前都加
AND
,併在WHERE
後加任意真判斷,即WHERE 1=1 AND ... AND ...
- 加入
<if></if>
判斷標簽造輪子,自行決定添加AND
的條件 - 使用
<where></where>
標簽替換原SQL中的WHERE
關鍵字,MyBatis將自動進行語法修正,如示例所示
- 對所有的條件前都加
-
-
-
單條件的動態條件查詢
優化條件查詢:如表單中存在多個條件篩選,但僅有其中一個生效的情況
- 使用
標簽 choose
標簽類似於Java
中的switch
when
標簽類似於Java
中的case
otherwise
標簽類似於Java
中的default
-
SQL映射文件
<!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap> <!-- 單條件動態查詢 --> <select id="selectByConditionSingle" resultMap="brandResultMap"> select * from tb_brand <where> <choose> <when test="status != null"> status = #{status} </when> <when test="companyName != null and companyName != ''"> company_name like #{companyName} </when> <when test="brandName != null and brandName != ''"> brand_name like #{brandName} </when> </choose> </where> </select>
- 使用
5.6 添加數據與MyBatis事務
-
添加
-
介面
// 添加 void add(Brand brand);
-
SQL映射文件
<insert id="add"> insert into tb_brand (brand_name, company_name, ordered, description, status) values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status}); </insert>
-
測試方法
@Test public void testAdd() throws IOException { // 接收參數 int status = 1; String companyName = "aaa"; String brandName = "xxx"; String description = "這是一段介紹"; int ordered = 100; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 // SqlSession sqlSession = sqlSessionFactory.openSession(); SqlSession sqlSession = sqlSessionFactory.openSession(true); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 Brand brand = new Brand(); brand.setStatus(1); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setDescription(description); brand.setOrdered(ordered); brandMapper.add(brand); System.out.println("添加成功"); // 提交事務 // sqlSession.commit(); // 釋放資源 sqlSession.close(); }
-
-
Mybatis事務
MyBatis預設手動事務,執行添加等操作時會自動回滾
-
MyBayis事務處理的方法
// 方法一:在獲取sqlSession對象時設置參數,開啟自動事務 SqlSession sqlSession = sqlSessionFactory.openSession(true); sqlSession.close(); // 方法二:手動提交事務 SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.commit(); sqlSession.close();
-
-
添加 - 主鍵返回
傳入實體類對象進行數據添加,在數據添加完成後,會將
id
信息寫回該實體類對象-
SQL映射文件
<insert id="add" useGeneratedKeys="true" keyProperty="id"> insert into tb_brand (brand_name, company_name, ordered, description, status) values (#{brandName}, #{companyName}, #{ordered}, #{description}, #{status}); </insert>
-
獲取寫回信息
Integer id = brand.getId();
-
5.7 修改
-
修改整條數據
-
介面
// 修改,可使用int返回值,返回受影響行數 void update(Brand brand);
-
SQL映射文件
<update id="update"> update tb_brand set brand_name = #{brandName}, set company_name = #{companyName}, set ordered = #{ordered}, set description = #{description}, set status = #{status} where id = #{id}; </update>
-
-
修改部分欄位
優化上述代碼應對僅修改部分屬性導致其他屬性數據丟失問題
使用
<set></set>
標簽替換set關鍵字列表,區別於<where></where>
標簽,註意語法-
SQL映射文件
<update id="update"> update tb_brand <set> <if test="brandName != null and brandName != ''"> brand_name = #{brandName}, </if> <if test="companyName != null and companyName != ''"> company_name = #{companyName}, </if> <if test="ordered != null"> ordered = #{ordered}, </if> <if test="description != null and description != ''"> description = #{description}, </if> <if test="status != null"> status = #{status}, </if> </set> where id = #{id}; </update>
-
測試代碼
@Test public void testUpdate() throws IOException { // 接收參數 int id = 5; int status = 0; String companyName = "AAA"; String brandName = "XXX"; int ordered = 300; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(true); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 Brand brand = new Brand(); brand.setId(id); brand.setStatus(status); brand.setBrandName(brandName); brand.setCompanyName(companyName); brand.setOrdered(ordered); brandMapper.update(brand); System.out.println("修改成功"); // 釋放資源 sqlSession.close(); }
-
5.8 刪除數據
-
刪除一條數據
-
介面
// 刪除一條數據 void deleteById(int id);
-
SQL映射文件
<delete id="deleteById"> delete from tb_brand where id = #{id}; </delete>
-
測試
@Test public void testDeleteById() throws IOException { // 接收參數 int id = 5; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(true); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 brandMapper.deleteById(id); System.out.println("刪除成功"); // 釋放資源 sqlSession.close(); }
-
-
批量刪除數據
用於解決刪除時傳入參數為數組的情況
- 使用
<foreach></foreach>
標簽代替SQL語句中的id in (?, ?, ..., ?)
collection
屬性為MyBatis封裝後數組對應的key
,封裝後屬性值應為array
(見註釋)MyBatis
預設會將數組參數封裝為Map
集合,其key
為array
,即array = ids
- 可在介面中對參數數組使用
@Param
註解,將封裝後的key
手動命名,則可在映射文件中使用
separator
屬性為分隔符open
和close
屬性分別為在<foreach></foreach>
前後拼接字元,主要用於代碼規範,示例中未展示
-
介面
// 刪除多個數據 void deleteByIds(@Param("ids")int[] ids);
-
SQL映射文件
<delete id="deleteByIds"> delete from tb_brand where id in ( <!-- <foreach collection="array" item="id"> --> <foreach collection="ids" item="id" separator=","> #{id} </foreach> ); </delete>
-
測試
@Test public void testDeleteByIds() throws IOException { // 接收參數 int[] ids = {6, 7}; // 獲取SqlSessionFactory String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 獲取sqlSession對象 SqlSession sqlSession = sqlSessionFactory.openSession(true); // 獲取mapper介面的代理對象 BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class); // 執行方法 brandMapper.deleteByIds(ids); System.out.println("刪除成功"); // 釋放資源 sqlSession.close(); }
- 使用
5.9 MyBatis參數傳遞
-
概述
-
多個參數
設有如下代碼:
User select(@Param("username") String username,@Param("password") String password);
MyBatis會將散裝的多個參數封裝為Map集合
-
若不使用
@Param
註解,則會使用以下命名規則:map.put("arg0",參數值1); map.put("arg1",參數值2); map.put("param1",參數值1); map.put("param2",參數值2);
即Map集合中的參數的key分別為
arg0, arg1, param1, param2
-
使用
@Param
註解會將Map集合中的參數的arg替換為指定內容,增強其可讀性
-
-
單個參數
-
POJO類型:直接使用,要求屬性名和參數占位符名稱一致(見 5.2 SQL映射文件)
-
Map集合類型:直接使用,要求key和參數占位符名稱一致(見 5.2 SQL映射文件)
-
Collection集合類型:封裝Map集合,可以使用@Param註解替換Map集合中預設arg鍵名
map.put("arg0",collection集合); map.put("collection",collection集合;
-
List集合類型:封裝為Map集合,可以使用@Param註解,替換Map集合中預設的arg鍵名
map.put("arg0",list集合); map.put("collection",list集合); map.put("list",list集合);
-
Array類型:封裝為Map集合,可以使用@Param註解,替換Map集合中預設的arg鍵名
map.put("arg0",數組); map.put("array",數組);
-
其他類型:直接使用,與參數占位符無關,但儘量見名知意
-
6、通過註解實現CRUD
-
概述
- 用於簡化開發,可以對簡單的查詢使用註解進行操作,以替換
xml
中的statement
- 對於複雜的查詢,仍然建議使用
xml
配置文件,否則代碼會十分混亂
- 用於簡化開發,可以對簡單的查詢使用註解進行操作,以替換
-
使用方法
-
註解(部分)
- 查詢 :
@Select
- 添加 :
@Insert
- 修改 :
@Update
- 刪除 :
@Delete
- 查詢 :
-
示例
-
使用註解簡化查詢
-
原介面
Brand selectById(int id);
-
原SQL映射文件
<!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap> <select id="selectById" resultMap="brandResultMap"> select * from tb_brand where id = #{id}; </select>
-
使用註解進行開發
-
介面
@ResultMap("brandResultMap") // 解決資料庫和實體類欄位名稱不同 @Select("select * from tb_brand where id = #{id}") // 查詢語句 Brand selectById(int id);
-
SQL映射文件:不再需要原先的
statement
<!-- resultMap解決資料庫和實體類欄位不同問題 --> <resultMap id="brandResultMap" type="brand"> <result column="brand_name" property="brandName"/> <result column="company_name" property="companyName"/> </resultMap> <!-- <select id="selectById" resultMap="brandResultMap"> select * from tb_brand where id = #{id}; </select> -->
-
-
-
-