MyBatis 是一款優秀的持久層框架,它支援自定義 SQL、儲存過程以及高階對映。
在之前的文章中我們學習了MYSQL和JDBC,但是這些東西遠遠不足以支援我們書寫JavaWeb相關的內容
在學習MyBatis前,請先學習Java,Mysql,JDBC,Maven內容
首先我們先簡單介紹一下MyBatis:
我們再來介紹一下JavaEE概念:
最後我們瞭解一下框架:
我們在前面提到MyBatis的產生是為了簡化JDBC開發
那麼我們就先來介紹一下JDBC的缺點:
我們通過一段程式碼進行解析:
package com.itheima.jdbc;
import org.junit.Test;
import java.sql.*;
import java.util.Date;
@Test
public void testPreparedStatement2() throws Exception {
// 前置連結操作
String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收使用者輸入 使用者名稱和密碼
String name = "zhangsan";
String pwd = "' or '1' = '1";
// 定義sql
String sql = "select * from tb_user where username = ? and password = ?";
// 獲取pstmt物件
PreparedStatement pstmt = conn.prepareStatement(sql);
Thread.sleep(10000);
// 設定?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
ResultSet rs = null;
// 執行sql
rs = pstmt.executeQuery();
// 設定?的值
pstmt.setString(1,"aaa");
pstmt.setString(2,"bbb");
// 執行sql
rs = pstmt.executeQuery();
// 判斷登入是否成功
if(rs.next()){
System.out.println("登入成功~");
}else{
System.out.println("登入失敗~");
}
//7. 釋放資源
rs.close();
pstmt.close();
conn.close();
}
}
在上述程式碼中,我們可以注意到:
/*
寫死概念: 程式碼展現形式固定,如果有所更改需要手動修改程式碼
寫死動作:註冊驅動,獲得連結,SQL語句
*/
// 前置連結操作
String url = "jdbc:mysql:///db1?useSSL=false&useServerPrepStmts=true";
String username = "root";
String password = "1234";
Connection conn = DriverManager.getConnection(url, username, password);
// 接收使用者輸入 使用者名稱和密碼
String name = "zhangsan";
String pwd = "' or '1' = '1";
/*
操作繁瑣:大量程式碼堆疊
操作繁瑣動作:手動設定引數,手動封裝結果
*/
// 獲取pstmt物件
PreparedStatement pstmt = conn.prepareStatement(sql);
Thread.sleep(10000);
// 設定?的值
pstmt.setString(1,name);
pstmt.setString(2,pwd);
ResultSet rs = null;
// 執行sql
rs = pstmt.executeQuery();
// 設定?的值
pstmt.setString(1,"aaa");
pstmt.setString(2,"bbb");
// 執行sql
rs = pstmt.executeQuery();
因而為了解決JDBC的這些缺點,MyBatis應運而生!
MyBatis解決思想:
MyBatis免除了幾乎所有的JDBC程式碼以及設定引數和獲得結果集的工作
我們將以一個案例進行MyBatis的快速入門(資源來自B站黑馬程式設計師老陳的JavaWeb課程)
我們以步驟形式逐步進行:
<!--
我們使用mybatis,匯入mybatis座標
我們使用mysql,匯入mysql座標
我們需要進行單元測試,匯入junit座標
我們需要紀錄檔,檢視錯誤資訊,匯入紀錄檔座標(注意:需要匯入logback.xml包,可在網路查詢)
->
<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-config.xml,
寫入下列資訊(MyBatis官網可查詢)
<?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">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
然後我們需要對上述資訊進行修改,使其完成連線資料庫的問題
-->
<?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">
<transactionManager type="JDBC"/>
<!--注意:這裡dataSource表示資料庫連線--->
<dataSource type="POOLED">
<!--
我們需要修改下述資訊
driver:固定com.mysql.jdbc.Driver
url:jdbc:mysql:/// + 資料庫名稱 + ?useSSL=false
username:資料庫賬號
password:資料庫密碼
-->
<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>
<!--這裡mapper表示對映地址:我們所需要的Mapper.xml,在後續我們會在Mapper.xml中書寫SQL語句-->
<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"/>
</mappers>
</configuration>
<!--
同樣自己建立Mapper.xml檔案,這裡注意在前面加上字首,如果你是Usr使用者的資料庫操作,命名為UserMapper.xml便於區分
匯入下述程式碼(同樣,在Mybatis官網可以找到)
<?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="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
在建立完成後,不要忘記回到上一步,把mapper的resource地址改為該檔案所在地址
-->
<?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介面名稱一致保證互聯(這裡暫時設定為test)
id:查詢方法的唯一表示
resultType:返回型別
在<select></select>中間書寫語句即可
後續會繼續介紹
-->
<mapper namespace="test">
<select id="selectAll" resultType="User">
select * from Blog where id = #{id}
</select>
</mapper>
// 注意:資料為private,書寫get和set方法以及toString方法
package com.itheima.pojo;
// alt + 滑鼠左鍵 整列編輯
public class User {
private Integer id;
private String username;
private String password;
private String gender;
private String addr;
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 getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", gender='" + gender + '\'' +
", addr='" + addr + '\'' +
'}';
}
}
// 建立主程式碼
package com.itheima;
import com.itheima.pojo.User;
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;
import java.io.InputStream;
import java.util.List;
/**
* Mybatis 快速入門程式碼
*/
public class MyBatisDemo {
public static void main(String[] args) throws IOException {
//1. 載入mybatis的核心組態檔,獲取 SqlSessionFactory(官網下載)
/*
下述為官網下載,我們只需要修改第一行的mybatis-config.xml地址即可
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
*/
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件,用它來執行sql(sqlSessionFactory方法)
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 執行sql(這裡的test.selectList是我們的UserMapper.xml中所設定的名稱空間.id)
List<User> users = sqlSession.selectList("test.selectAll");
System.out.println(users);
//4. 釋放資源
sqlSession.close();
}
}
至此,我們已經瞭解了MyBatis的整體建立流程
在下面我們會以上述入門為標準,進行各種流程上的簡化開發
我們在Mapper.xml中書寫sql語句時,可能會出現sql表名顯示紅色(報錯)現象
產生原因:IDEA和資料庫沒有建立連線,不識別表資訊
解決方法:在IDEA中設定MYSQL資料庫連線
解決優點:程式碼不再報錯,顯示所有SQL語句以及表列的補全資訊
解決方法:
我們在入門程式碼中建立了Mapper.xml,並在其中書寫程式碼
我們在主專案的程式碼中包含有以下這段:
List<User> users = sqlSession.selectList("test.selectAll");
但test.selectAll屬於寫死階段,且書寫方式麻煩
因而產生了Mapper代理開發,同樣我們採用案例的形式逐步書寫:
<?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="com.itheima.mapper.UserMapper">
<!--statement-->
<select id="selectAll" resultType="user">
select *
from tb_user;
</select>
</mapper>
package com.itheima.mapper;
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
public interface UserMapper {
List<User> selectAll();
}
package com.itheima;
import com.itheima.mapper.UserMapper;
import com.itheima.pojo.User;
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;
import java.io.InputStream;
import java.util.List;
/**
* Mybatis 代理開發
*/
public class MyBatisDemo2 {
public static void main(String[] args) throws IOException {
//1. 載入mybatis的核心組態檔,獲取 SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件,用它來執行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.1 獲取UserMapper介面的代理物件
//(採用sqlSession方法獲得介面類產生物件,呼叫物件的方法[這裡方法來自xml],並根據Mapper介面設定的返回引數)
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> users = userMapper.selectAll();
System.out.println(users);
//4. 釋放資源
sqlSession.close();
}
}
在mybatis-config.xml檔案中我們設定過mapper內容:
<mappers>
<!--載入sql對映檔案-->
<mapper resource="com/itheima/mapper/UserMapper.xml">
</mappers>
但隨著sql對映檔案增多,單個書寫過於麻煩,所以開發出了package方法
<mappers>
<!--載入sql對映檔案-->
<!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>-->
<!--Mapper代理方式:通過包掃描的方法,將包中所對應的mapper.xml對映過來-->
<package name="com.itheima.mapper"/>
</mappers>
Mybatis核心組態檔就是我們之前寫入的mybatis-config.xml檔案
現在我們對MyBatis的相關內容進行分析:
下面給出程式碼展示:
<?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="com.itheima.pojo"/>
</typeAliases>
<!--
environments:設定資料庫連線環境資訊。可以設定多個environment,通過default屬性切換不同的environment
-->
<environments default="development">
<environment id="development">
<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>
<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="1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--載入sql對映檔案-->
<!-- <mapper resource="com/itheima/mapper/UserMapper.xml"/>-->
<!--Mapper代理方式-->
<package name="com.itheima.mapper"/>
</mappers>
</configuration>
在下述內容中,我們會通過一個案例進行MyBatis的增刪改查並且補充相應知識點
在開始前,我們同樣準備環境:
package com.itheima.pojo;
/**
* 品牌
*
* alt + 滑鼠左鍵:整列編輯
*
* 在實體類中,基本資料型別建議使用其對應的包裝型別
*/
public class Brand {
// id 主鍵
private Integer id;
// 品牌名稱
private String brandName;
// 企業名稱
private String companyName;
// 排序欄位
private Integer ordered;
// 描述資訊
private String description;
// 狀態:0:禁用 1:啟用
private Integer status;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getBrandName() {
return brandName;
}
public void setBrandName(String brandName) {
this.brandName = brandName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
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 +
", brandName='" + brandName + '\'' +
", companyName='" + companyName + '\'' +
", ordered=" + ordered +
", description='" + description + '\'' +
", status=" + status +
'}';
}
}
我們將會介紹三種資料查詢方法:
接下來我們逐一講解:
查詢所有資料步驟:
package com.itheima.mapper;
import com.itheima.pojo.Brand;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.ResultMap;
import org.apache.ibatis.annotations.Select;
import java.util.List;
import java.util.Map;
public interface BrandMapper {
/**
* 查詢所有
*/
List<Brand> selectAll();
}
<select id="selectAll" resultType="brand">
select *
from tb_brand;
</select>
@Test
public void testSelectAll() throws IOException {
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
List<Brand> brands = brandMapper.selectAll();
System.out.println(brands);
//5. 釋放資源
sqlSession.close();
}
但是這種方法中,我們會發現brandName和companyName並沒有顯示
主要原因:
解決方法有兩種:
<mapper namespace="com.itheima.mapper.BrandMapper">
<select id="selectAll" resultMap="brandResultMap">
select id, brand_name as brandName, company_name as companyName, ordered, description, status
from tb_brand;
</select>
</mapper>
<mapper namespace="com.itheima.mapper.BrandMapper">
<!--
資料庫表的欄位名稱 和 實體類的屬性名稱 不一樣,則不能自動封裝資料
* 起別名:對不一樣的列名起別名,讓別名和實體類的屬性名一樣
* 缺點:每次查詢都要定義一次別名
* sql片段
* 缺點:不靈活
* resultMap:
1. 定義<resultMap>標籤
2. 在<select>標籤中,使用resultMap屬性替換 resultType屬性
-->
<!--
id:唯一標識
type:對映的型別,支援別名
-->
<resultMap id="brandResultMap" type="brand">
<!--
id:完成主鍵欄位的對映
column:表的列名
property:實體類的屬性名
result:完成一般欄位的對映
column:表的列名
property:實體類的屬性名
-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select *
from tb_brand;
</select>
<select id="selectAll" resultMap="brand">
select *
from tb_brand;
</select>
</mapper>
單個查詢步驟:
Brand selectById(int id);
<select id="selectById" resultMap="brandResultMap">
select *
from tb_brand
where id = #{id};
</select>
@Test
public void testSelectById() throws IOException {
//接收引數
int id = 1;
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
Brand brand = brandMapper.selectById(id);
System.out.println(brand);
//5. 釋放資源
sqlSession.close();
}
知識點講解:
這裡我們介紹多條件查詢:
/**
* 條件查詢
* * 引數接收
* 1. 散裝引數:如果方法中有多個引數,需要使用@Param("SQL引數預留位置名稱")
* 2. 物件引數:物件的屬性名稱要和引數預留位置名稱一致
* 3. map集合引數
*
*/
List<Brand> selectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
List<Brand> selectByCondition(Brand brand);
List<Brand> selectByCondition(Map map);
<!--
條件查詢:
這裡#{}中的元素和Param所書寫的屬性相同;
如果是Brand,則與Brand的屬性相同;
如果是Map,則與Map集合的鍵相同即可
-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status = #{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
@Test
public void testSelectByCondition() throws IOException {
//接收引數
int status = 1;
String companyName = "華為";
String brandName = "華為";
// 處理引數
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//封裝物件
/* Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);*/
Map map = new HashMap();
// map.put("status" , status);
map.put("companyName", companyName);
// map.put("brandName" , brandName);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
//List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
// List<Brand> brands = brandMapper.selectByCondition(brand);
List<Brand> brands = brandMapper.selectByCondition(map);
System.out.println(brands);
//5. 釋放資源
sqlSession.close();
}
動態查詢概念:
動態SQL語句:
<!--
if標籤:整體框架
test:判斷條件
<if test="title != null">
sql語句內容
</if>
-->
<select id="findActiveBlogWithTitleLike"
resultType="Blog">
SELECT * FROM BLOG
WHERE state = ‘ACTIVE’
<if test="title != null">
AND title like #{title}
</if>
</select>
<!--
動態條件查詢
* if: 條件判斷
* test:邏輯表示式
* 問題:
* 恆等式
* <where> 替換 where 關鍵字
-->
<!--這裡的where會根據實際情況,自行新增and或者刪除and-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
/* where 1 = 1*/
<where>
<if test="status != null">
and status = #{status}
</if>
<if test="companyName != null and companyName != '' ">
and company_name like #{companyName}
</if>
<if test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</if>
</where>
<!--
<choose> <!--相當於switch-->
<when test="status != null"> <!--相當於case-->
-->
<select id="findActiveBlogLike"
resultType="Blog">
SELECT * FROM BLOG WHERE state = ‘ACTIVE’
<choose>
<when test="title != null">
AND title like #{title}
</when>
<when test="author != null and author.name != null">
AND author_name like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
</select>
我們根據兩個案例來解釋上述語法:
List<Brand> selectByCondition(Brand brand);
<!--
動態條件查詢
* if: 條件判斷
* test:邏輯表示式
* 問題:
* 恆等式
* <where> 替換 where 關鍵字
-->
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
/* where 1 = 1*/
<!--這裡使用where,防止無條件或者and位置錯誤-->
<where>
<if test="status != null">
and status = #{status}
</if>
<if test="companyName != null and companyName != '' ">
and company_name like #{companyName}
</if>
<if test="brandName != null and brandName != '' ">
and brand_name like #{brandName}
</if>
</where>
</select>
@Test
public void testSelectByCondition() throws IOException {
//接收引數
int status = 1;
String companyName = "華為";
String brandName = "華為";
// 處理引數
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//封裝物件
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
List<Brand> brands = brandMapper.selectByCondition(brand);
System.out.println(brands);
//5. 釋放資源
sqlSession.close();
}
List<Brand> selectByConditionSingle(Brand brand);
<select id="selectByConditionSingle" resultMap="brandResultMap">
select *
from tb_brand
<!--這裡使用where防止無條件出現導致錯誤-->
<where>
<choose><!--相當於switch-->
<when test="status != null"><!--相當於case-->
status = #{status}
</when>
<when test="companyName != null and companyName != '' "><!--相當於case-->
company_name like #{companyName}
</when>
<when test="brandName != null and brandName != ''"><!--相當於case-->
brand_name like #{brandName}
</when>
</choose>
</where>
</select>
@Test
public void testSelectByConditionSingle() throws IOException {
//接收引數
int status = 1;
String companyName = "華為";
String brandName = "華為";
// 處理引數
companyName = "%" + companyName + "%";
brandName = "%" + brandName + "%";
//封裝物件
Brand brand = new Brand();
//brand.setStatus(status);
brand.setCompanyName(companyName);
//brand.setBrandName(brandName);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
List<Brand> brands = brandMapper.selectByConditionSingle(brand);
System.out.println(brands);
//5. 釋放資源
sqlSession.close();
}
在這小節我們會講到新增功能並附帶返回主鍵:
新增功能步驟:
void add(Brand brand);
<!--
useGeneratedKeys:對於支援自動生成記錄主鍵的資料庫,如:MySQL,SQL Server,此時設定useGeneratedKeys引數值為true,在執行新增記錄之後可以獲取到資料庫自動生成的主鍵ID。
keyProperty:後面跟資料庫中自動增長的列名,這時該屬性值就會反饋在Java程式碼中
-->
<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>
@Test
public void testAdd() throws IOException {
//接收引數
int status = 1;
String companyName = "波導手機";
String brandName = "波導";
String description = "手機中的戰鬥機";
int ordered = 100;
//封裝物件
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
// 這裡openSession的引數未設定時為手動提交資訊,設定true後為自動提交事務
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法(這裡就可以對brand的id進行提取,並輸出)
brandMapper.add(brand);
Integer id = brand.getId();
System.out.println(id);
// 執行add後並未立刻執行,我們需要提交事務才能反饋到資料庫中
sqlSession.commit();
//5. 釋放資源
sqlSession.close();
}
該小節中我們會介紹兩種修改方法:
我們會在下述內容中一一講解:
int update(Brand brand);
<update id="update">
update tb_brand
set brand_name = #{brandName},
company_name = #{companyName},
ordered = #{ordered},
description = #{description},
status = #{status}
where id = #{id};
</update>
@Test
public void testUpdate() throws IOException {
//接收引數
int status = 0;
String companyName = "波導手機";
String brandName = "波導";
String description = "波導手機,手機中的戰鬥機";
int ordered = 200;
int id = 6;
//封裝物件
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
brand.setDescription(description);
brand.setOrdered(ordered);
brand.setId(id);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
int count = brandMapper.update(brand);
System.out.println(count);
//提交事務
sqlSession.commit();
//5. 釋放資源
sqlSession.close();
}
int update(Brand brand);
<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 status = 0;
String companyName = "波導手機";
String brandName = "波導";
String description = "波導手機,手機中的戰鬥機";
int ordered = 200;
int id = 6;
//封裝物件
Brand brand = new Brand();
brand.setStatus(status);
// brand.setCompanyName(companyName);
// brand.setBrandName(brandName);
// brand.setDescription(description);
// brand.setOrdered(ordered);
brand.setId(id);
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
int count = brandMapper.update(brand);
System.out.println(count);
//提交事務
sqlSession.commit();
//5. 釋放資源
sqlSession.close();
}
這節介紹刪除功能的兩種形式:
我們將會在下面一一講解:
void deleteById(int id);
<delete id="deleteById">
delete from tb_brand where id = #{id};
</delete>
@Test
public void testDeleteById() throws IOException {
//接收引數
int id = 6;
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
brandMapper.deleteById(id);
//提交事務
sqlSession.commit();
//5. 釋放資源
sqlSession.close();
}
void deleteByIds(int[] ids);
<!--
mybatis會將陣列引數,封裝為一個Map集合。
* 預設:array = 陣列
* 使用@Param註解改變map集合的預設key的名稱
-->
<!--
foreach:類似於for強化語句
collection:集合/陣列
item:陣列中的單個值
separator:分割符
open:開始處新增符號
close:結尾處新增符合
-->
<delete id="deleteByIds">
delete from tb_brand where id
in
<!--這部分整合出來類似於:(id1,id2,id3....)-->
<foreach collection="array" item="id" separator="," open="(" close=")">
#{id}
</foreach>
;
</delete>
@Test
public void testDeleteByIds() throws IOException {
//接收引數
int[] ids = {5,7,8};
//1. 獲取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2. 獲取SqlSession物件
SqlSession sqlSession = sqlSessionFactory.openSession();
//SqlSession sqlSession = sqlSessionFactory.openSession(true);
//3. 獲取Mapper介面的代理物件
BrandMapper brandMapper = sqlSession.getMapper(BrandMapper.class);
//4. 執行方法
brandMapper.deleteByIds(ids);
//提交事務
sqlSession.commit();
//5. 釋放資源
sqlSession.close();
}
MyBatis介面方法中可以接收各種各樣的引數,MyBatis底層對這些引數有著不同的封裝處理方法
我們在下面一一介紹:
在介面多引數傳遞中會把所有引數轉移為Map集合
會轉化為兩種Map集合:
arg集合,下標從0開始: arg[0]
Param集合,下標從1開始: Param[1]
我們在xml中也可以直接使用arg或param來直接表示(但不推薦,因為不能直觀得到資訊)
我們所推薦的做法是使用@Param註解:
在引數前加上註解@Param("")
注意:這裡使用Param註解實際上是對Param集合的鍵進行修改,也就是說你的Param集合將不再能夠使用
常見的單引數傳遞分為六種:
POJO型別: 直接使用, 屬性名 和 引數預留位置 名稱一致即可
Map集合: 直接使用,鍵名 和 引數預留位置 名稱一致即可
Collection: 封裝為Map集合
List: 封裝為Map集合
Array:封裝為Map
其他型別:直接使用
我們先來介紹註解開發的格式:
// 相當於節省了xml的一步,直接在介面中定義方法
@Select("select * from tb_user where id = #{id}")
List<Brand> selectAll();
當然,註解的方法也分為四種:
註解的優缺點:
使用註解來對映簡單語句會使程式碼顯得更加簡潔,但對於稍微複雜一點的語句,Java 註解不僅力不從心,還會讓你本就複雜的 SQL 語句更加混亂不堪。 因此,如果你需要做一些很複雜的操作,最好用 XML 來對映語句。
選擇何種方式來設定對映,以及認為是否應該要統一對映語句定義的形式,完全取決於你和你的團隊。 換句話說,永遠不要拘泥於一種方式,你可以很輕鬆的在基於註解和 XML 的語句對映方式間自由移植和切換。
好的,關於MyBatis的內容就介紹到這裡,希望能為你帶來幫助!
該文章屬於學習內容,具體參考B站黑馬程式設計師陳老師的JavaWeb課程
這裡附上連結:01-MyBatis簡介_嗶哩嗶哩_bilibili