MyBatis框架一些知识

MyBatis简介

什么是MyBatis

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦。

下图是MBatis架构图
在这里插入图片描述
(1)mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂

(2)基于SqlSessionFactory可以生成SqlSession对象

(3)SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的Connection对象,也是Mybatis中至关重要的一个对象。

(4)Executor是SqlSession底层的对象,用于执行SQL语句

(5)MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)

为什么要使用MyBatis

思考:在开始之前,思考下如何通过JDBC查询Emp表中的所有记录,并封装到一个List集合中返回。(演示:准备数据、导包、导入JDBC程序)

1、使用传统方式JDBC访问数据库:`

(1)使用JDBC访问数据库有大量重复代码(比如注册驱动、获取连接、获取传输器、释放资源等,执行一次SQL语句就需要连接一次数据库);

(2)JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低;

(3)SQL是写死在程序中,一旦修改SQL,需要对类重新编译;

(4)对查询SQL执行后返回的ResultSet对象,需要手动处理,有时会特别麻烦(未尝试过,不过会有这样的现象);

2、使用mybatis框架访问数据库:

(1)Mybatis对JDBC对了封装,可以简化JDBC代码;

(2)Mybatis自身支持连接池(也可以配置其他的连接池),因此可以提高程序的效率;

(3)Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译。
如果是简单语句可以通过注解加配置文件

(4)对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。
底层会根据相对应的POJO对象的getXxx()方法或者根据POJO对象的属性(数据库表的列名需与POJO对象的属性名一致)将返回的ResultSet对象封装到POJO对象中

总之,JDBC中所有的问题(代码繁琐、有太多重复代码、需要操作太多对象、释放资源、对结果的处理太麻烦等),在Mybatis框架中几乎都得到了解决!!

MyBatis快速入门

1.先准备一个数据库,数据库中的表中有数据

2.创建一个Maven工程

3.在pom.xml中导入相关依赖

<dependencies>
    <!-- junit单元测试 -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.9</version>
    </dependency>
    <!-- mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.32</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.8</version>
    </dependency>
    <!-- 整合log4j -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.6.4</version>
    </dependency>
</dependencies>

4.添加mybatis-config.xml文件

1、在src/main/resources目录下,创建mybatis-config.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">

<!-- 
	不同Mapper文件的namespace值应该保证唯一
	在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
 -->
<mapper namespace="EmpMapper">
	<!-- 通过select、insert、update、delete标签声明要执行的SQL -->
	<!-- 练习1: 查询emp表中的所有员工信息
		resultType指定查询的结果将会封装到什么类型中
		即使最终返回的结果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
 	-->
	<select id="findAll" resultType="com.tedu.pojo.Emp">
		select * from emp
	</select>

</mapper>

这个是通过配置xml文件来执行SQL语句的方式

MyBatis中的占位符

在增删改查操作中,SQL语句中的值是写死在SQL语句中的,而在实际开发中,此处的值往往是用户提交过来的值,因此这里我们需要将SQL中写死的值替换为占位符。

在mybatis中占位符有两个,分别是 #{} 占位符 和 ${} 占位符:

  • #{}:相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}占位符; 并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号)
    例如:查询指定name的员工信息,SQL语句为:
select * from emp where name=#{name}

其实就等价于JDBC中:

select * from emp where name=?,

如果传过来的参数值为:张三,那么最终执行的SQL语句为:

-- 在参数替换占位符的同时进行了转义处理(在值的两边加上了单引号)
select * from emp where name='张三' 
  • ${}:是为SQL片段进行占位,将传过来的SQL片段直接拼接在${}占位符所在的位置,不会进行任何的转义处理。(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)
    那么如果我们在传递的时候不是一个参数值,而是一个SQL片段呢?

例如:在查询时,我们想动态的传递查询的列:

select #{columns} from emp

此时传递过来的应该是一个SQL片段,不同于上面的参数值,如果此时还用#{},也会像上面一样被转译处理:

select 'id,name,job' from emp

这不是我们希望看到的!

如果不想让传过来的SQL片段被转译处理,而是直接拼接在SQL语句中,那么这里可以使用${},例如:

select ${columns} from emp

拼接之后:

select id,name,job from emp

使用哪种方式要看你实际SQL语句

动态SQL标签

if、where标签

  • <if>标签:是根据test属性中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段

  • <where>标签:用于对包含在其中的SQL片段进行检索,在需要时可以生成where关键字,并且在需要时会剔除多余的连接词(比如and或者or)

练习:根据薪资查询员工信息(if标签)

  • <if>标签:是根据test属性中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段

在mapper文件中编写SQL语句:

<!-- 练习: 根据薪资查询员工信息
* 如果没有参数, 则不执行where子句, 默认查询所有员工:
* 	select * from emp
* 如果参数中只有minSal(即minSal不为null), 则:
* 	... where salary > minSal
* 如果参数中只有maxSal(即maxSal不为null), 则:
* 	... where salary < maxSal
* 如果参数有 minSal、maxSal(即minSal、maxSal不为null), 则:
*		... where salary > minSal and salary < maxSal  -->
<select id="findAllBySal" resultType="com.tedu.pojo.Emp">
  select * from emp
  where 1=1
  <if test="minSal != null">
  	and salary>#{minSal}
  </if>
  <if test="maxSal != null">
  	and salary <![CDATA[ < ]]> #{maxSal}
  </if>
</select>

练习:根据薪资查询员工信息(where标签)

  • <where>标签:用于对包含在其中的SQL片段进行检索,在需要时可以生成where关键字,并且在需要时会剔除多余的连接词(比如and或者or)
<!-- 练习: 根据薪资查询员工信息
* 如果没有参数, 则不执行where子句, 默认查询所有员工:
* 	select * from emp
* 如果参数中只有minSal(即minSal不为null), 则:
* 	... where salary > minSal
* 如果参数中只有maxSal(即maxSal不为null), 则:
* 	... where salary < maxSal
* 如果参数有 minSal、maxSal(即minSal、maxSal不为null), 则:
*		... where salary > minSal and salary < maxSal  -->
<select id="findAllBySal" resultType="com.tedu.pojo.Emp">
  select * from emp
  <where>
    <if test="minSal != null">
    	and salary>#{minSal}
    </if>
    <if test="maxSal != null">
    	and salary <![CDATA[ < ]]> #{maxSal}
    </if>
  </where>
</select>

foreach元素

foreach标签:可以对传过来的参数数组或集合进行遍历,以下是foreach标签上的各个属性介绍:

属性属性描述
collection必需,值为遍历的集合类型,例如:如果参数只是一个数组或List集合,则collection的值为array或list;如果传的是多个参数,用map封装,collection则指定为map中的key。
item必需,若collection为数组或List集合时,item表示其中的元素,若collection为map中的key,item表示map中value(集合或数组)中的元素
open可选,表示遍历生成的SQL片段以什么开始,最常用的是左括号’(’
close可选,表示遍历生成的SQL片段以什么结束,最常用的是右括号’)’
separator可选,每次遍历后给生成的SQL片段后面指定间隔符

练习: 根据员工的id批量删除员工信息
在mapper文件中编写SQL语句:

<!-- 练习14: 根据员工的id批量删除员工信息
	delete from emp where id in (1,3,5,7)
	collection: 如果传的参数仅仅是一个数组或者List集合, collection可以指定为
		array或list; 如果传的是多个参数,用map封装,collection则指定为map中的key
	open: 指定生成的SQL片段以什么符号开始
	close: 指定生成的SQL片段以什么符号结束
	item: 指定变量接收数组或集合中的元素
	separator: 指定一个间隔符, 在将数组或集合中的每个元素拼接到SQL片段之后, 
		在后面拼接一个间隔符
 -->
<delete id="deleteByIds">
	delete from emp where id in
	<foreach collection="array" open="(" item="id" separator="," close=")">
		#{id}
	</foreach>
</delete>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值