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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章