MyBatis相关知识总结

1 什么是MyBatis

  MyBatis(前身是iBatis)是一个支持普通SQL查询、存储过程以及高级映射的持久层框架。iBatis一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架。iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。
  MyBatis框架是ORM(Object/Relation Mapping)框架。是为了解决面向对象与关系型数据库中数据类型不匹配的技术。通过描述Java对象与数据库表之间的映射关系,自动将Java应用程序中的对象持久化到关系型数据库的表中。

2 MyBatis的下载和使用

  下载地址:https://github.com/mybatis/mybatis -3/releases。使用时,若是普通项目,需要将mybatis-x.x.x.jar文件置于类路径(classpath)中。如果使用的是Maven管理项目则将如下依赖代码添加到配置文件中。

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.4</version>
</dependency>

3 MyBatis工作原理图

  1. 读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,配置了 MyBatis 的运行环境等信息,例如数据库连接信息。
  2. 加载映射文件。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。
  3. 构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。
  4. 创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
  5. Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。
  6. MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。
  7. 输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。
  8. 输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

单元测试实例示范:

	@Test
	public void findById() throws Exception {
		//定义配置文件
		String resource = "mybatis-config.xml";
		//以流的方式来加载
		InputStream is = Resources.getResourceAsStream(resource );
		//构造会话工厂
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
		//构造会话对象
		SqlSession session = sessionFactory.openSession();
		//执行器,实现查询
		Customer cust = session.selectOne("cn.edu.ujn.ch6.dao.CustomerMapper.selectByPrimaryKey", 1);
		//控制台输出
		System.out.println(cust);
		//关闭session
		session.close();
	}

4 模糊查询

  1. CustomerMapper.java接口中定义方法:
	// 依据客户名实现模糊查询
	List<Customer> findCustomerByName(String name);
  1. CustomerMapper.xml中加入查询语句:
<select id="findCustomerByName" parameterType="String"
		resultMap="BaseResultMap">
		select * from customer where username like '%${value}%'
</select>
  1. 单元测试实例:
//	模糊查询
	@Test
	public void findCustomerByName() throws Exception {
		// 定义配置文件
		String resource = "mybatis-config.xml";
		// 加载
		InputStream is = Resources.getResourceAsStream(resource);
		// 构造会话工厂
		SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
		// 构造会话对象
		SqlSession session = sqlSessionFactory.openSession();
		// 执行查询
		List<Customer> list = session.selectList("cn.edu.ujn.ch6.dao.CustomerMapper.findCustomerByName", "c");
		// 遍历输出
		for (Customer cc : list) {
			System.out.println(cc);
		}
		// 关闭session
		session.close();
	}

4.1 #与$

  • #{}:将传入的值当作字符串
  • ${}$是将传入的数据直接显示生成sql语句(一般传表名)

举例说明:

select * from customer where id = #{id};
//等同于:select * from customer where id = "1"
select * from customer where id = ${id};
//等同于:select * from customer where id = 1

#{}方式能够很大程度防止SQL注入,${}方式无法防止SQL注入。建议使用#{}方式

5 核心对象

5.1 SqlSessionFactory

  SqlSessionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。SqlSessionFactory对象的实列可以通过SqlSessionFactoryBulider对象来构建,而SqlSessionFactoryBulider则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例。

5.1.1 构建SqlSessionFactory

  • 通过XML配置文件构建代码如下:
InputStream inputStream = Resources.getResourceAsStream("配置文件位置");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream );
  • SQLSessionFactory对象是线程安全的,一旦被创建,在整个应用执行期间都会存在。
  • 如果我们多次的创建同一个数据库的SqlSessionFactory,那么此数据库的资源将很容易被耗尽。
  • 通常每一个数据库都只会对应一个SqlSessionFactory,所以在构建SQLSessionFactory实例时,建议使用单例模式

5.2 SqlSession

  SqlSession是Mybatis框架中很重要的对象,是应用程序与持久层之间执行交互操作的一个单线程对象。只要作用是执行持久化操作。
  每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例是线程不安全的。因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Server的HttpSession)中使用
  在我们使用完SqlSession对象之后,一定要及时关闭,通常可以将其放在finally中关闭。

SqlSession sqlSession = sqlSessionFactory.openSession();
try{
	//此处执行持久化操作
}finally{
	//关闭SqlSession对象
	sqlSession.close();
}

5.3 使用工具类

  为了开发方便,我们可以将创建SqlSession的操作提取出来,写一个工具类,使用起来就会很方便了。示例如下:

工具类代码:

package cn.edu.ujn.ch7.utils;

import java.io.IOException;
import java.io.Reader;

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 sqlSessionFactory;

//	静态代码段
	static {
		try {
			Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
			// 赋值给成员变量
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static SqlSession getSession() {
		return sqlSessionFactory.openSession();
	}
}

使用示例:

@Test
	public void selectCustomer() {
		// 使用时会很方便
		SqlSession session = MyBatisUtils.getSession();
		Customer customer = session.selectOne("cn.edu.ujn.ch7.dao.CustomerMapper.selectByPrimaryKey", 1);
		System.out.println(customer);
		session.close();
	}

6 线程安全

  百度百科解释:在拥有共享数据的多条线程并行执行的程序中,线程安全的代码会通过同步机制保证各个线程都可以正常且正确的执行,不会出现数据污染等意外情况。
  多个线程访问同一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要经行额外的同步,或者在调用方法进行任何其他操作,调用这个对象的行为都可以获得正确的结果,那么这个对象就是线程安全的。出现线程安全问题大多都是由全局变量及静态变量引起的。线程安全是通过线程同步控制来实现的,也就是synchronized关键字。

7 配置文件

7.1 主要元素

  Mybatis的配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<configuration>元素内配置。

7.1.1 properties元素

  <properties>是一个配置属性的元素,该元素通常用来将内部的配置外在化,即通过外部的配置来动态的替换内部定义的属性。例如,数据库的连接等属性,就可以通过典型的Java属性文件中的配置来替换,如下:

  • 编写db.properties文件:
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javaee4
jdbc.username=root
jdbc.password=
  • 配置<properties/>属性
<properties resource="db.properties"/>
  • 修改配置文件中数据库连接的信息
<dataSource type="POOLED">
	<property name="driver" value="${jdbc.dirver}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</dataSource>

7.1.2 settings元素

  <settings>元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。

<settings>
	<setting name="cacheEnabled" value="true" />
	<setting name="lazyLoadingEnabled" value="true" />
	<setting name="multipleResultSetsEnabled" value="true" />
	<setting name="useColumnLabel" value="true" />
	<setting name="useGeneratedKeys" value="false" />
	<setting name="autoMappingBehavior" value="PARTIAL" />
</settings>

7.1.3 typeAliases元素

  <typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用意义在于减少全限定类名的冗余。

  • 使用<>typeAliases>元素配置别名的方法如下:
<typeAliases>
	<typeAlias alias="user" type="cn.edu.ujn.ch7.po.User"/>
</typeAliases>
  • 通过自动扫描包的形式自定义别名,具体如下:
<typeAliases>
	<package name="cn.edu.ujn.ch7.po"/>
</typeAliases>

7.1.4 typeHandler元素

  typeHandler:将预处理语句中传入的参数从javaType(Java类型 )转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。
  <typeHandler>元素可以在配置文件中注册自定义的类型处理器,它的使用方式有两种:

  • 注册一个类的类型处理器
<typehandlers>
	<typehandler handler="cn.edu.ujn.ch7.type.CustomtypeHandler"/>
</typeHandlers>
  • 注册一个包中所有的类型处理器
<typeHandlers>
	<package name="cn.edu.ujn.ch7.type"/>
</typeHandlers>

7.1.5 objectFactory元素

  MyBatis中默认的ObjectFactory的作用是实例化目标类,它可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。通常使默认的ObjectFactory即可。

7.1.6 plugins元素

  MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。<plugins>元素的作用就是配置用户所开发的插件。

7.1.7 environments元素

  <environments>元素用于对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,可以通过<environment>元素配置多种数据源。即配置多种数据库。示例如下:

<environments default="mysql">
		<!--1.2.配置id为mysql的数据库环境 -->
		<environment id="mysql">
			<!-- 使用JDBC的事务管理 -->
			<transactionManager type="JDBC" />
			<!--数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
				<property name="username" value="root" />
				<property name="password" value="" />
			</dataSource>
		</environment>
	</environments>
7.1.7.1 UNPOOLED

  UNPOOLED:不使用连接池,配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。在使用时,需要配置5中属性。

7.1.7.2 POOLED

  POOLED:此数据源利用“池”的概念将JDBC连接对象组织起来,这种方式使得并发Web应用可以快速响应请求,是当前流行的处理方式。在使用时,可以配置更多的属性。

7.1.7.3 JNDI

  JNDI:可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在使用时需要配置:

7.1.8 mappers元素

  <mappers>元素用于指定MyBatis映射文件的位置,一般可以使用以下四种方式引入映射器文件:

  1. 使用类路径引入
<mappers>
   <mapper resource="cn/edu/ujn/ch7/mapper/UserMapper.xml"/>
</mappers>
  1. 使用本地文件路径引入(不建议使用)
<mappers>
   <mapper url="file:///D:/cn/edu/ujn/mapper/UserMapper.xml"/>
</mappers>
  1. 使用接口类引入
<mappers>
   <mapper class="cn.edu.ujn.ch.mapper.UserMapper.xml"/>
</mappers>
  1. 使用包名引入
<mappers>
   <mapper name="cn.edu.ujn.ch7.mapper"/>
</mappers>

7.1.9 databaseIdProvider元素

  这是为了使用多个厂商的数据库。举例如下:

  • 在mybatis-config.xml中配置:
<databaseIdProvider type="DB_VENDOR">
   <property name="MySQL" value="mysql"/>
   <property name="Oracle" value-"oracle"/>
</databaseIdProvider>
  • mapperXML文件中配置:
<select id="SelectTime" resultType="String" databaseId="mysql">
SELECT NOW() FROM dual
</select>


<select id="SelectTime" resultType="String" databaseId="oracle">
SELECT 'oracle'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual
</select>

8 映射文件

8.1 主要元素

  在映射文件中,<mapper>元素是映射文件的根元素。

8.1.1 select元素

  <select>元素用来映射查询语句,可以帮助我们从数据库中读取出数据,让后组装起来,再给开发人员 。使用如下:

<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultType="cn.edu.ujn.ch7.dao.Customer">
    select * from customer where id = #{id}
</select>

常用属性:

8.1.2 insert

  <insert>元素用于映射插入语句,在执行完元素中定义的SQL语句后,会返回一个表示插入记录数的整数。配置示例如下:

三个特有属性:

  插入执行成功后,如果需要获取插入记录的主键值,实现方式如下:

  1. 对于支持主键自助增长的数据库(如MySQL),可以通过如下配置:
<!--注意keyProperty和useGeneratedKeys-->
<insert id="insert" parameterType="cn.edu.ujn.ch7.dao.Customer" useGeneratedKeys="true" keyProperty="id">
   insert into customer (id, username, jobs,  phone)
   values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR},#{jobs,jdbcType=VARCHAR},  #{phone,jdbcType=VARCHAR})
 </insert>

直接获取到主键。

  1. 对于不是主键自助增加的数据库(如Oracle),可以通过如下配置:

8.1.3 update和delete

  <update><delete>元素配置基本相同,常用属性如下:

8.1.4 sql元素

  SQL复用
  在一个映射文件中,通常需要定义多条SQL语句,这些SQL语句的组成可能有一部分是相同的(如多条select语句中都查询相同的id username、 jobs字段) ,如果每一个SQL语句都重写遍相同的部分,势必会增加代码量,导致映射文件过于臃肿。将这些SQL语句中相同的组成部分抽取出来统一提供引用方式。如下:

实例1:

<sql id="Base_Column_List"> 
 	id, username, jobs, phone
</sql>
  
<select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
 	select <include refid="Base_Column_List" />
    from customer
    where id = #{id,jdbcType=INTEGER}
</select>

实例2:

8.1.5 resultMap元素

  <resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。主要作用就是定义映射规则、级联的更新以及定义类型转换器等。元素结构如图所示:


声明:
若本人发布的作品涉及版权或存在其他问题,请联系我删除。
谢谢浏览!
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值