MyBatis 框架筆記

Copyright © 2019 Linyer. All Rights Reserved

框架介紹

框架技術

框架(Framework)

  • 是一個應用程序的半成品提供可重用的公共結構
  • 按一定規則組織的一組組件

分析優勢

  • 不用再考慮公共問題
  • 專心在業務實現
  • 結構統一,易於學習、維護
  • 新手也可寫出好程序

主流框架

Struts

  • MVC 設計模式的實現
  • 攔截器
  • 可變和可重用的標籤

HIBERNATE

  • ORM,簡化數據庫操作
  • DAO 層

Spring

  • 依賴注入容器 /AOP 實現
  • 聲明式事務
  • 簡化 JavaEE 應用黏合劑,將大家組裝到一起

Spring MVC

  • 結構最清晰的 MVC Model2 實現
  • 高度可配置,支持多種視圖技術
  • 定製化開發

MyBatis

  • 半自動化的 ORM 實現
  • DAO 層
  • 動態 SQL
  • 小巧靈活、簡單易學

持久化與ORM

  • 持久化:程序數據在瞬時狀態和持久狀態間轉換的過程
  • ORM(Object Relational Mapping):對象-關係映射
    • 👉編寫程序的時候,以面向對象的方式處理數據
    • 👉保存數據的時候,卻以關係型數據庫的方式存儲
  • ORM 解決方案包含下面四個部分
    • 👉在持久化對象上執行基本的增、刪、改、查操作對持久化對象提供一種查詢語言或者 API
    • 👉對象關係映射工具
    • 👉提供與事務對象交互、執行檢查、延遲加載以及其他優化功能

MyBatis

MyBatis 簡介

  • MyBatis 前身是 iBatis,本是 Apache 的一個開源的項目
  • 官方網站
  • ORM 框架
  • 實體類和 SQL 語句之間建立映射關係
  • 特點
    • 👉基於 SQL 語法,簡單易學
    • 👉能瞭解底層封裝過程
    • 👉SQL 語句封裝在配置文件中,便於統一管理與維護,降低程序的耦合度
    • 👉方便程序代碼調試

搭建 MyBatis 框架

  • 使用 MyBatis 的開發步驟
  • 下載 mybatis-3.2.2.jar 包並導入工程
  • 編寫 MyBatis 核心配置文件(configuration.xml
  • 創建實體類:POJO
  • DAO層SQL映射文件mapper.xml
  • 創建測試類
    • 👉讀取全局(核心)配置文件mybatis-config.xml
    • 👉創建SqlSessionFactory對象,讀取配置文件
    • 👉創建SqlSession對象
    • 👉調用mapper文件進行數據操作

編寫核心配置文件

  • 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>
	<!-- 引入database.properties文件 -->
	<properties resource="database.properties"/>
	<settings>
		<setting name="logImpl" value="LOG4J"/>
	</settings>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"></transactionManager>
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${user}"/>
				<property name="password" value="${password}"/>
			</dataSource>
		</environment>
	</environments>
	<!-- 將mapper文件加入到配置文件中 -->
	<mappers>
		<mapper resource="cn/linyer/dao/user/UserMapper.xml"/>
	</mappers>
</configuration>

編寫 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">
<mapper namespace="cn.linyer.dao.user.UserMapper">
	<!--查詢用戶表的記錄數-->
	<select id="count" resultType="int">
		select count(1) as count from users
	</select>
</mapper>

編寫 JUnit 測試類

package cn.linyer.dao.user;
import java.io.IOException;
import java.io.InputStream;
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 org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
public class UserMapperTest {
	private Logger logger = Logger.getLogger(UserMapperTest.class);
	@Before
	public void setUp() throws Exception {
	}
	@Test
	public void test() {
		String resource="MyBatis-config.xml";
		int count=0;
		SqlSession sqlSession=null;
		try {
			//1 獲取mybatis-config.xml的輸入流
			InputStream is = Resources.getResourceAsStream(resource);
			//2 創建Sq1SessionFactory
			SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
			//3 創建sqlSession
			sqlSession = factory.openSession();
			//4 調用mapper文件來對數據進行操作,必須將mapper文件引入到mybatis-config.xml中
			count = sqlSession.selectOne("cn.linyer.dao.user.UserMapper.count");
			logger.debug("UserMapperTest count---->"+count);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			sqlSession.close();
		}
	}
}

MyBatis 與 JDBC 對比

  • JDBC
Class.forName("com. mysql. jdbc. Driver");
Connection connection = DriverManager.getConnection(url, user, password);
String sql = "select count(*) as count from smbms_user";
Statement st = connection.createStatement();
Resultset rs = st.executeQuery(sql);
if(rs.next()){
	int count = rs.getInt("count");
}
  • MyBatis
<mapper namespace="cn.linyer.dao.user.UserMapper">
	<select id="count" resultType="int">
		select count(1) as count from smbms_user
	</select>
</mapper>
  • 優點
    • 👉與 JDBC 相比,減少了 50% 以上的代碼量
    • 👉最簡單的持久化框架、小巧並簡單易學
    • 👉SQL 代碼從程序代碼中徹底分離,可重用
    • 👉提供XML標籤,支持編寫動態 SQL
    • 👉提供映射標籤,支持對象與數據庫的 ORM 字段關係映射
  • 缺點
    • 👉SQL語句編寫工作量大,對開發人員有一定要求
    • 👉數據庫移植性差
  • MyBatis 專注於 SQL 本身,是一個足夠靈活的 DAO 層解決方案
  • 適用於性能要求較高或者需求多變互聯網項目

MyBatis 基本要素

  • MyBatis 的核心接口
    • 👉SqlSessionFactoryBuilder
    • 👉SqlSessionFactory
    • 👉SqlSession
  • mybatis-config.xml 系統核心配置文件
  • mapper.xml SQL映射文件

核心對象

build方法
openSession方法
SqlSessionFactoryBuilder
SqlSessionFactory
SqlSession
  • SqlSessionFactoryBuilder
    • 👉用過即丟,其生命週期只存在於方法體內
    • 👉可重用其來創建多個SqlSessionFactory 實例
    • 👉負責構建SqlSessionFactory,並提供多個build方法的重載
build(InputStream inputStream,String environment,Properties properties)
build(Reader reader,String environment,Properties properties)
build(Configuration config)
  • 配置信息以三種形式提供給 SqlSessionFactory 的 build 方法:
    • 👉InputStream(字節流)
    • 👉Reader(字符流)
    • 👉Configuration(類)
  • 讀取XML文件構造方式:
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
  • SqlSessionFactory
    • 👉SqlSessionFactory每個 MyBatis 應用的核心
    • 👉作用:創建SqlSession實例
      SqlSession session = sqlSessionFactory.openSession(boolean autoCommit);

      autoCommittrue:關閉事務控制(默認)false:開啓事務控制

    • 👉作用域:Application
    • 👉生命週期與應用的生命週期相同
    • 👉單例
      • 👍存在於整個應用運行時,並且同時只存在一個對象實例

工具類

  • 靜態代碼塊,以保證SqlSessionFactory只被創建一次
  • 創建MyBatisUtils.java
package cn.linyer.utils;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtils {
	private static SqlSessionFactory factory;	
	static {		
		try {
			InputStream is = Resources.getResourceAsStream("MyBatis-config.xml");
			factory = new SqlSessionFactoryBuilder().build(is);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}	
	public static SqlSession createSqlSession() {
		return factory.openSession(false);
	}	
	public static void closeSqlSession(SqlSession sqlSession) {
		if(null != sqlSession) {
			sqlSession.clearCache();
		}
	}
}
  • 測試類
package cn.linyer.dao.user;
import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.junit.Before;
import org.junit.Test;
import cn.linyer.utils.MyBatisUtils;
public class UserMapperTest {
	private Logger logger = Logger.getLogger(UserMapperTest.class);
	@Before
	public void setUp() throws Exception {
	}
	@Test
	public void test() {
		int count=0;
		SqlSession sqlSession=null;
		try {
			sqlSession = MyBatisUtils.createSqlSession();
			count = sqlSession.selectOne("cn.linyer.dao.user.UserMapper.count");
			logger.debug("UserMapperTest count---->"+count);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			MyBatisUtils.closeSqlSession(sqlSession);
		}
	}
}

SqlSession

  • 包含了執行 SQL 所需的所有方法
  • 對應一次數據庫會話,會話結束必須關閉
  • 線程級別,不能共享
  • 關閉SqlSession非常重要,必須要確保在finally代碼塊中正常關閉
  • SqlSession裏可以執行多次SQL語句,但一旦關閉了SqlSession就需要重新創建
  • SqlSession的獲取方式
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = factory.openSession();
  • SqlSession的兩種使用方式
    • 👉通過SqlSession實例直接運行映射的SQL語句
    • 👉基於Mapper接口方式操作數據

實踐

  • 非集成環境下的最佳實踐
    • 👉SqlSessionFactoryBuilder
      • 👍用過即丟,推薦作用域在方法體內
    • 👉SqlSessionFactory
      • 👍最佳作用域範圍:應用全局作用域
      • 👍生命週期應與應用的生命週期相同
    • 👉SqlSession
      • 👍線程級
      • 👍一個request請求期間

核心配置文件

configuration

  • configuration 配置 (注意元素節點順序)
    • 👉properties 可以配置在 Java 屬性配置文件中
    • 👉settings 修改 MyBatis 在運行時的行爲方式
    • 👉typeAliases 爲 Java 類型命名一個別名(簡稱)
    • 👉typeHandlers 類型處理器
    • 👉objectFactory 對象工廠
    • 👉plugins 插件
    • 👉environments 環境
    • 👉environment 環境變量
      • 👍transactionManager 事務管理器
      • 👍dataSource 數據源
    • 👉mappers 映射器

properties

  • 配置properties元素的兩種方式
    1. 👍通過外部指定的方式 database.properties,實現動態配置
    2. 👍直接配置爲 XML,實現動態配置
  • 通過外部指定的方式 database.properties,實現動態配置
    • 👉配置propertiesresource指定
<properties resource="database.properties"/>
......
<dataSource type="POOLED">
	<property name="driver" value="${driver}"/>
	<property name="url" value="${url}"/>
	<property name="username" value="${user}"/>
	<property name="password" value="${password}"/>
</dataSource>
  • 直接配置爲 XML,實現動態配置
    • 👉配置propertynamevalue
<properties>
	<property name="driver" value="com.mysql.jdbc.Driver"/>
	<property name="url" value="jdbc:mysql://127.0.0.1:3306/book"/>
	<property name="user" value="root"/>
	<property name="password" value="123456"/>
</properties>
......
<dataSource type="POOLED">
	<property name="driver" value="${driver}"/>
	<property name="url" value="${url}"/>
	<property name="username" value="${user}"/>
	<property name="password" value="${password}"/>
</dataSource>

settings

  • 用來修改 MyBatis 運行時的行爲方式
  • 主要是 MyBatis 的一些全局配置屬性的設置
<settings>
	<!--是否啓用延遲加載-->
	<setting name="lazyLoadingEnabled" value="false"/>
</settings>
設置項 描述 允許值 默認值
cacheEnabled 對在此配置文件下的所有cache進行全局性開/關設置 true / false true
lazyLoadingEnabled 全局性設置懶加載。如果設爲false,則所有相關聯的都會被初始化加載 true / false true
autoMappingBehavior MyBatis對於resultMap自動映射匹配級別 NONE / PARTIAL / FULL PARTIAL
…(9個)

typeAliases

  • 類型別名
  • 僅僅只關聯 XML 配置,簡寫冗長的 Java 類名
<typeAliases>
	<typeAlias alias="user" type="cn.smbms.pojo.User"/>
</typeAliases>
<typeAliases>
	<package name="cn.smbms.pojo"/>
</typeAliases>

environments

  • 表示配置 MyBatis 的多套運行環境,將 SQL 映射到多個不同的數據庫上
  • 子元素節點:environment,但是必須指定其中一個默認運行環境(通過default指定)

每個SqlSessionFactory實例只能選擇一個運行環境

<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="${user}"/>
			<property name="password" value="${password}"/>
		</dataSource>
	</environment>
	<environment id="test">
	...
	</environment>
</environments>
  • transactionManager:事務管理器
    • 👉JDBCMANAGED(託管)
<transactionManager type="[ JDBC | MANAGED]"/>
  • dataSource
    • 👉dataSource元素使用基本的JDBC數據源接口來配置JDBC連接對象的資源
    • 👉有三種內建的數據源類型
      • 👍POOLED使用的概念
<dataSource type="[ UNPOOLED | POOLED | JNDI ]">

mappers

  • 映射器,定義 SQL 映射語句
  • 須在配置中引用mapper映射文件
  • 方式一:使用類資源路徑獲取資源
<!--將mapper映射文件加入到系統核心配置文件中-->
<mappers>
	<mapper resource="cn/smbms/dao/user/UserMapper.xml"/>
</mappers>
  • 方式二:使用 URL 獲取資源
<mappers>
	<mapper url="file:///E:/sqlmappers/UserMapper.xml"/>
	<mapper url="file:///E:/sqlmappers/ProviderMapper.xml"/>
<mappers>

SQL映射文件

SQL 映射的 XML 文件

  • MyBatis 真正的強大在於映射語句,專注於SQL,功能強大,SQL映射的配置卻是相當簡單
  • SQL映射文件的幾個頂級元素(按照定義的順序)
語句 含義
mapper namespace命名空間
cache 配置給定命名空間的緩存
cache-ref 從其他命名空間引用緩存配置
resultMap 用來描述數據庫結果集和對象的對應關係
sql 可以重用的SQL塊,也可以被其他語句引用
insert 映射插入語句
update 映射更新語句
delete 映射刪除語句
select 映射查詢語句
  • DAO接口方法常見的返回類型
    • 👉Java對象MapList 等複雜數據類型
    • 👉int
      • 👍(增、刪、改)更新操作時,影響的數據行數
  • MyBatis 參數入參
    • 👉使用@Param註解進行參數的傳遞
    • 👉封裝成對象入參

mapper

  • namespace:命名空間
    • 👉namespace和子元素的id聯合保證唯一區別不同的mapper
    • 👉綁定 DAO 接口
      • 👍namespace的命名必須跟某個接口同名
      • 👍接口中的方法與映射文件中 SQL 語句id一一對應
<mapper namespace="cn.smbms.dao.user.UserMapper">
	<select id="getUserList" ...>
		......
	</select>
</mapper>

select

  • select是 MyBatis 中最常用的元素之一
  • select語句有很多屬性可以詳細配置每一條語句
    • 👉id
      • 👍命名空間中唯一的標識符
      • 👍接口中的方法與映射文件中的 SQL 語句id一一對應
    • 👉parameterType
      • 👍傳入 SQL 語句的參數類型完全限定名別名
      • 👍基礎數據類型
        • 🤜intStringDate
        • 🤜只能傳入一個,通過#{參數名}即可獲取傳入的值
      • 👍複雜數據類型
        • 🤜Java 實體類Map
        • 🤜通過#{屬性名}或者#{Map的key}即可獲取傳入值
    • 👉resultType
      • 👍SQL 語句返回值類型的完整類名別名
<select id="getUserListByUserName" parameterType="string" resultType="user">
	select * from users where userName
		like CONCAT ('%',#{userName},'%')
</select>
  1. ❗支持基礎數據類型複雜數據類型
  2. ❗大小寫敏感❗
  • 參數傳遞:#{參數名}

JDBC 代碼:

string sql = "select * from users where userName like CONCAT ('%',?,'%')";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1,userName);
  • 注意❗:數據庫字段名與 JavaBean 的屬性名一致❗

resultMap

  • 描述如何將結果集映射到 Java 對象
<resultMap type="User" id="userList">
	<result property="id" column="id"/>
	<result property="userCode" column="userCode"/>
	<result property="userName" column="userName"/>
	<result property="userRole" column="userRole"/>
	<result property="userRoleName" column="roleName"/>
</resultMap>

<select id="getUserList" resultMap="userList" parameterType="User">
	select u.*,r.roleName
		from smbms_user u,smbms_role r
		where u.userName like CONCAT('%',#{userName},'%')
		and u.userRole=#{userRole} and u.userRole=r.id
</select>
<select id="getUserList" 👉resultMap👈="userList" parameterType="User">
            ❗❗一個外部 resultMap 👆 的id,表示返回結果映射到哪一個resultMap❗❗
========================================================================             
<result property="userRoleName" column=👉"roleName"👈/>         
                  ❗❗ 從數據庫中查詢的列名或者別名 👆      ❗❗
  • resultMap 對比 resultType
    • 👉resultType直接表示返回類型
      • 👍基礎數據類型
      • 👍複雜數據類型
    • 👉resultMap:對外部resultMap引用
      • 👍應用場景
        • 🤜數據庫字段信息與對象屬性不一致
        • 🤜複雜的聯合查詢,自由控制映射結果
    • 👉二者不能同時存在,本質上都是Map數據結構🤙
  • resultMap自動映射匹配前提:字段名屬性名一致
  • resultMap的自動映射級別(autoMappingBehavior
    • 👉PARTIAL(默認):自動匹配所有屬性
<settings>
	<setting name="autoMappingBehavior" value="NONE"/>
</settings>

insert

  • id
  • parameterType

注意:insertupdatedelete元素均 沒有 resultType屬性

<insert id="add" parameterType="User">
	insert into smbms_user(userCode,userName,userPassword)
	values(#{userCode),#{userName),#{userPassword))
</insert>

update

  • id
  • parameterType

對象入參

<update id="modify" parameterType="User">
	update smbms_user
	set userCode=#{userCode},userName=#{userName},userPassword=#{userPassword)
	where id=#{id)
</update>

多參數入參

public interface UserMapper {
	public int updatePwd(@Param("id")int id,@Param("password")String password);
}
<update id="updatePwd">
	update users
	set password=#{password}
	where id=#{id}
</update>

delete

  • id
  • parameterType
<delete id="deleteUserByld" parameterType="int">
	delete from smbms_user
	where id=#{id}
</delete>

使用 resultMap 實現 高級 結果映射

  • resultMap屬性
    • 👉idresultMap的唯一標識
    • 👉typeJava 實體類
  • resultMap子元素
    • 👉id:一般對應數據庫中該行的主鍵 id,設置此項可提高 MyBatis 性能
    • 👉result:映射到 JavaBean 的某個 “簡單類型”屬性
    • 👉association:映射到 JavaBean 的某個 “複雜類型”屬性,比如 JavaBean類
    • 👉collection:映射到 JavaBean 的某個 “複雜類型”屬性,比如 集合

association

  • 複雜的類型關聯,一對一
  • 內部嵌套
    • 👉映射一個嵌套 JavaBean 屬性
  • 屬性
    • 👉property:映射數據庫列的實體對象的屬性
    • 👉javaType完整 Java 類名或者別名
    • 👉resultMap:引用外部 resultMap
  • 子元素
    • 👉id
    • 👉result
      • 👍property:映射數據庫列的實體對象的屬性
      • 👍column數據庫列名或者別名
<resultMap type="User" id="userRoleResult">
	<id property="id" column="id"/>
	<result property="userCode" column="userCode"/>
	<result property="userName" column="userName"/>
	<result property="userRole" column="userRole"/>
	<association property="role" javaType="Role">
		<id property="id" column="r_id"/>
		<result property="rolecode" column="rolecode"/>
		<result property="roleName" column="roleName"/>
	</association>
</resultMap>

<select id="getUserlistByRoleId" parameterType="Integer" resultMap="userRoleResult">
	select u.*,r.id as r_id,r.roleCode,r.roleName
	from smbms_user u,smbms_role r
	where u.userRole=#{userRole} and u.userRole=r.id
</select>

collection

  • 複雜類型集合,一對多
  • 內部嵌套
    • 👉映射一個嵌套結果集到一個列表
  • 屬性
    • 👉property:映射數據庫列的實體對象的屬性
    • 👉ofType完整 Java 類名或者別名(集合所包括的類型)
    • 👉resultMap:引用外部resultMap
  • 子元素
    • 👉id
    • 👉result
      • 👍property:映射數據庫列的實體對象的屬性
      • 👍column數據庫列名或者別名
<resultMap type="Address" id="addressResult">
	<id property="id" column="a_id"/>
	<result property="contact" column="contact"/>
	<result property="addressDesc" column="addressDesc"/>
	<result property="postcode" column="postcode"/>
	<result property="tel" column="tel"/>
</resultMap>

<resultMap type="User" id="userAddressResult">
	<id property="id" column="id"/>
	<result property="usercode" column="usercode"/>
	<result property="userName" column="userName"/>
	<collection property="addresslist" ofType="Address" resultMap="addressResult"/>
</resultMap>

<select id="getAddresslistByUserId" resultMap="userAddressResult" parameterType="Integer">
	select u.*,a.id as a_id,a.contact,a.addressDesc,a.tel,a.postcode
	from smbms_user u,smbms _address a
	where u.id=a.userId and u.id=#{id}
</select>
  • resultMap自動映射(autoMappingBehavior)的三個匹配級別
    • NONE:禁止自動匹配
    • PARTIAL默認):自動匹配所有屬性,內部嵌套除外
    • FULL:自動匹配所有

MyBatis 緩存

  • 一級緩存
  • 二級緩存的配置
    • MyBatis 的全局cache配置
  • 第一種:在 MyBatis XML 中配置
<settings>
	<setting name="cacheEnabled" value="true"/>
</settings>
  • 第二種:在 Mapper XML 文件中設置緩存,默認情況下:未開啓
<cache eviction="FIFO" flushlnterval="60000" size="512" readOnly="true"/>
  • 在 Mapper XML 文件配置支持cache後,若需要對個別查詢進行調整,可以單獨設置cache
<select id="selectAll" resultType="Emp" useCache="true">

動態 SQL

  • 基於 OGNL 表達式
  • 使用動態 SQL 完成多條件查詢等邏輯實現
  • 用於實現動態 SQL 的元素主要有
    • 👉if
    • 👉trim
    • 👉where
    • 👉set
    • 👉choosewhenotherwise
    • 👉foreach

if

<select id="getUserList" resultMap="userlist">
	select u.*,r.roleName from smbms_user u,smbms_role r
	where u.userRole=r.id
	<if test="userRole!=null">
		and userRole=#{userRole}
	</if>
	<if test="userName!=null and userName!=''">
		and userName like CONCAT('%',#{userName},'%')
	</if>
</select>

where

  • 簡化 SQL 語句中where條件判斷
  • 智能處理andor
<select id="getUserlist" resultType="User">
	select * from smbms_user
	<where>
		<if test="userName!=null and userName!=''">
			and userName like CONCAT('%',#{userName},'%')
		</if>
		<if test="userRole!=null">
			and userRole=#{userRole}
		</if>
	</where>
</select>

set

<update id="modify" parameterType="user">
	update smbms_user
	<set>
		<if test="usercode!=null">userCode=#{userCode},</if>
		<if test="userName!=nulL">userName=#{userName},</if>
		<if test="userPassword!=null">userPas sword=#{userPassword},</if>
		<if test="gender!=null">gender=#{gender},</if>
		<if test="birthday !=null">birthday=#{birthday},</if>
		<if test="phone!=nulL">phone=#{phone},</if>
		<if test="address!=null">address=#{address},</if>
		<if test="userRolel!=null">userRole=#{userRole},</if>
		<if test="userCode!=nulL">modifyBy=#{modifyBy},</if>
		<if test="userCode !=nulL">modifyDate=#{modifyDate},</if>
	</set>
	where id=#{id}
</update>

trim

  • 屬性
    • 👉prefix
    • 👉suffix
    • 👉prefixOverrides
    • 👉suffixOverrides
  • 更靈活的去除多餘關鍵字
  • 替代where
<select id="getUserlist" resultType="User">
	select * from smbms_user
	<trim prefix="where" prefixoverrides="and / or">
		<if test="userName!=null and userName!=''">
			and userName like CONCAT('%',#{userName},'%')
		</if>
		<if test="userRole!=null">
			and userRole=#{userRole}
		</if>
	</trim>
</select>
<update id="modify" parameterType="User">
	update smbms_user
	<trim prefix="set" suffixOverrides="," suffix="where id=#{id}">
		<if test="userCode!=null">userCode=#{userCode},</if>
		<if test="userName!=null">userCode=#{userName },</if>
		<if test="userPassword!=null">userPassword=#{userPassword },</if>
	</trim>
</update>

foreach

  • 迭代一個集合,通常用於in條件
  • 屬性
    • 👉item別名
    • 👉index位置
    • 👉collection:必須指定
      • 👍list
      • 👍array
      • 👍map-key
    • 👉open開始符號
    • 👉separator間隔符號
    • 👉close結束符號

單參數入參:

<resultMap type="User" id="userMapByRole">
	<id property="id" column="id"/>
	<result property="userCode" column="userCode"/>
	<result property="userName" column="userName"/>
</resultMap>

<select id="getUserByRoleId_foreach_array" resultMap="userMapByRole">
	select * from smbms_user where userRole in
	<foreach collection="array" item="roleIds" open="(" separator="," close=")">
		#{roleIds}
	</foreach>
</select>

多參數入參:

public List<User> getUserByConditionMap_foreach_map(Map<String,Object> conditionMap);
<select id="getUserByConditionMap_foreach_map" resultMap="userMapByRole">
	select * from smbms_user where
	gender=#{gender}
	and userRole in
	<foreach collection=" roleIds" item="roleMap" open="(" separator="," close=")">
		#{roleMap}
	</foreach>
</select>

choosewhenotherwise

  • 相當於Javaswitch語句
  • when有條件滿足的時候,就跳出choose
<choose>
	<when test="條件1">...</when>
	<when test="條件2">...</when>
	<when test="條件3">...</when>
	...
	<otherwise>...</otherwise>
</choose>

MyBatis 入參類型

  • 基本類型
    • key:變量名
    • value:變量值
  • 數組
    • key:“array”
    • value:該數組
  • 對象
    • key:對象的屬性名鍵值不變
    • value:對象的屬性值
  • List
    • key: “list”
    • value:該List
  • Map
    • 鍵值不變

❗❗ 無論 入參是何種類型,MyBatis 都會將其放入在一個 Map 中❗❗

MyBatis 實現分頁功能

  • 分頁—DAO層實現
    • limit(起始位置,頁面容量)
  • 查詢用戶列表的方法增加2個參數:
    • from
    • pageSize
public List<User> getuserList(@Param("userName")string userName,
							  @Param("userRole")Integer roleId,
							  @Param("from")Integer currentPageNo,
							  @Param("pagesize")Integer pagesize);
<select id="getUserlist" resultMap="userlist">
	select u.* from smbms user_u, smbms_role r
	where u.userRole=r.id
	<if test="userName!=null and userName!=''">
		and userName like CONCAT('%',#{userName},'%')
	</if>
	<if test="userRole!=null">
		and userRole=#{userRole}
	</if>
	order by creationDate DESC limit #{from},#{pageSize}
</select>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章