MyBatis框架简介

什么是MyBatis?

MyBatis是一个优秀的持久层框架(就是将某些数据持久化到硬盘或其他存储器中的框架),它把jdbc对数据库的操作进行了封装,使用户只需关注sql本身,不需要去执行jdbc的那一套复杂的操作。
MyBatis通过配置xml文件或注解的方式,将statement或preparedstatement中的sql语句与java对象中的数据相互映射,最终生成可执行的sql语句,由MyBatis执行sql语句,并将返回结果封装成java对象。
简而言之,MyBatis封装了JDBC对数据库的复杂操作,并将返回结果封装成所需的java对象。
MyBatis流程图:
image
1.MyBatis-config.xml文件是MyBatis的核心配置文件,这个文件中配置了运行环境,事务管理方式,是否使用连接池等,MyBatis可以通过该配置文件创建SqlSessionFactory
2.SqlSessionFactory用来创建SqlSession
3.SqlSession是用来发送sql语句到数据库执行,并返回结果,类似于jdbc中的connection
4.executor是MyBatis的一个底层对象,用于执行sql语句
5.MapperStatement也是MyBatis的一个底层对象,用于将配置文件中的sql语句映射为可执行的sql语句。


JDBC与MyBatis的对比

JDBC:
1.使用jdbc有大量重复且复杂的代码
2.jdbc中的sql语句是写死在代码中,一旦修改sql还需重新编译代码
3.jdbc本身是不支持使用连接池的,会不断的创建连接,释放资源,影响效率
4.jdbc返回的ResultSet对象,需要我们手动处理,特别麻烦
MyBatis:
1.MyBatis对JDBC进行了封装,可以简化了代码
2.MyBatis的sql语句都是写在配置文件中的,如需修改sql,修改配置文件即可
3.MyBatis本身是支持连接池的,且MyBatis还可以兼容其他连接池
4.MyBatis会将返回的结果,封装为相应的java对象,极大的减少了我们的麻烦。

MyBatis的用法

1.首先导入MyBatis框架的所需依赖

    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.2.8</version>
    </dependency>

2.配置MyBatis的核心配置文件,MyBatis-config.xml
1)配置头文件

<?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">
    
<!-- MyBatis的全局配置文件 -->
<configuration >
	
</configuration>

第一行是xml文档的声明,及使用的编码
第2,3,4行用来引入xml文件的约束文档,该文档受mybatis-3-config.dtd的约束
mybatis的环境配置都是在configuration中进行配置的。
2)配置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">
    
<!-- MyBatis的全局配置文件 -->
<configuration >
	<environments default="develop">
		<environment id="develop">
			<!--配置事务管理方式,MANAGED/JDBC
			MANAGED:自己管理
			JDBC:由JDBC进行管理(推荐)
			-->
			<transactionManager type="JDBC"></transactionManager>
			<!--配置数据库连接方式,POOLED/UNPOOLED/JNDI
			JNDI:已过时
			UNPOOLED:不使用连接池
			POOLED:使用连接池
			-->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
				<property name="username" value="root"/>
				<property name="password" value="root"/>
			</dataSource> 
		</environment>
	</environments>
	<mappers>
		<mapper>
		 <mapper resource="EmpMapper.xml"/>
		</mapper>
	</mappers>
</configuration>

environments,mybatis中可以同时部署多套环境,都是配置在environments,通过environments标签中的default属性来切换环境。
environment,mybatis中的环境配置,每个environment都有一个id,environments通过这个id来切换环境
transactionManager,数据库事务管理方式,由MANAGED/JDBC两种,MANAGED,自己手动管理事务,JDBC,由jdbc来管理事务
datasource,数据源,这里配置数据库连接是否使用连接池,JNDI/POOLED/UNPOOLED
mappers,可以在该标签下配置多个mapper
mapper,每个mapper对应一个mapper.xml配置文件


3.创建对应表的mapper.xml文件,并将该映射文件配置到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>

mapper,根标签,其中namespace(命名空间,要求不能重复),通过namespace+id来定位一条sql语句
select,映射文件中配置的sql类型标签
id,一条sql语句的标识
resultType,sql执行返回的结果类型,如果返回的是一个集合,那么这里包含的应该是集合的泛型,例如上述sql返回结果为list
则这里resultType就是泛型emp的全限定类名
resultMap,复杂对象结构,常用与多表查询,resultType与resultMap不能同时使用


4.通过Java代码查询数据库中数据

public class TestMyBatis(){
	public void main(String args[]){
		//1.读取MyBatis-config.xml核心配置文件
		InputStream in=Resources.getResourceAsStream("mybatis-config.xml");
		//2.创建SqlSessionFactory对象
		SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in);
		//3.创建Sqlsession对象
		SqlSession sqlSession=sqlSessionFactory.openSession();
		//4.执行sql语句
		List<emp> empList = sqlSession.selectList("emp.findAll");
		//5.对返回结果进行操作
		for (emp item:empList) {
      		 System.out.println(item.toString());
        }
	}
}

MyBatis中的占位符#{}和${}

${}和#{}的区别:
‘#{}’相当与jdbc中的?,并会将传进来的字符进行转义处理,在字符的两边加上单引号。

‘${}’是直接将传进来的字符拼接到sql中的,因此有可能出现sql注入,所以每个${}传进来的值,都需进行封装,即使只有一个值。


动态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>

根据if标签中的test属性,来判断是否拼接if标签中的sql
注意sql中的 'where 1==1',这是为了防止第一个if中的and


标签''

<!-- 
* 如果没有参数, 则不执行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="findAllBySal2" 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>

where标签会在需要的时候生成where语句,并且会剔除多余的and或or,例如本例中若第一个if成立就会生成where并剔除and
标签''
这个标签主要用于遍历集合

<!-- 
	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>

foreach标签中的属性
collection 集合(必需)
item 集合中的元素(必需)
open 以什么开始
close 以什么结束
separator 集合中元素的分割符


MyBatis的接口开发

上述,在Java代码中查询数据库时,是通过namepace+id定位sql的,mybatis还有一个更简单的方法来定位sql,通过接口中的方法直接定位到sql
要求:
1.创建一个接口,再创建mapper映射文件,映射文件中的namespace与接口的全限定类名一致
2.mapper映射文件中的每条sql,接口中都需要有一个对应的方法
3.接口中方法的入参类型要与sql中接收的参数类型一致
4.接口中方法的返回值类型要与sql中resultType中的一致(注意resutType中只是泛型)

posted @ 2021-08-30 19:41  杨远  阅读(1204)  评论(0编辑  收藏  举报