MyBatis总结

MyBatis温故而知新

目的:巩固基础知识,加深记忆



前言

例如:经济基础决定上层建筑,上层建筑反作用于经济基础。技术亦是同理。


一、Mybatis是什么?

是一款优秀的持久层框架。

1.持久化

即可以将数据永久保存在存储设备中(如:磁盘)。持久化主要应用是将内存对象存储在数据库中,或者磁盘文件,xml数据文件中等。
JDBC是持久化机制,文件IO也是持久化机制

2.为什么要持久化

因为内存一旦断电,就会丢失数据。
内存有容量限制,不可能一直呆在内存中,需要持久化缓存到外存。

3.持久层(dao)

完成持久化工作的代码块(dao层)。持久化的过程大多通过各种关系型数据库完成。

二、搭建环境

1.引入依赖

代码如下(示例):

<dependency>
	<groupId>org.mybatis</groupId>
	<artifactId>mybatis</artifactId>
	<version>3.5.2</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>5.1.47</version>
</dependency>

2.配置文件

mybatis-config.xml:

<configuration>
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
			<property name="driver" value="com.mysql.jdbc.Driver"/>
			<property name="url"
			value="jdbc:mysql://localhost:3306/mybatis?
			useSSL=true&amp;useUnicode=true&amp;	characterEncoding=utf8"/>
			<property name="username" value="root"/>
			<property name="password" value="123456"/>
		</dataSource>
	</environment>
</environments>
<mappers>
<mapper resource="com/kuang/dao/userMapper.xml"/>
</mappers>
</configuration>

该处使用的url网络请求的数据。


3.工具类

import java.io.InputStream;
public class MybatisUtils {
	private static SqlSessionFactory sqlSessionFactory;
	static {
	try {
		String resource = "mybatis-config.xml";
		InputStream inputStream =
		Resources.getResourceAsStream(resource);
		sqlSessionFactory = new
		SqlSessionFactoryBuilder().build(inputStream);
	} catch (IOException e) {
	e.printStackTrace();
	}
}
	//获取SqlSession连接
	public static SqlSession getSession(){
		return sqlSessionFactory.openSession();
	}
}

三.配置解析

核心配置文件:mybatis-config
配置属性如下:

configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)
	objectFactory(对象工厂)
	plugins(插件)
	environments(环境配置)
	environment(环境变量)
	transactionManager(事务管理器)
	dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)

注意以上元素节点的顺序!顺序不对会报错。一般会提示!

1. environments 元素

<environments default="development">
	<environment id="development">
	<transactionManager type="JDBC">
	<!-- transactionManager 事务管理器
		type=JDBC | MANAGED
-->
		<property name="..." value="..."/>
	</transactionManager>
	<dataSource type="POOLED">
	<!-- 
	datasource type分为三个type="[UNPOOLED|POOLED|JNDI]")
	UNPOOLED:这个数据源实现只是每次请求时打开和关闭连接。
	POOLED:数据源实现利用"池"的概念讲JDBC对象组织起来,这是一种使得并发web应用快速响应请求的处理方式
	JNDI:这种数据源为了配合Spring使用,容器可以集中在外部配置数据源
-->
		<property name="driver" value="${driver}"/>
		<property name="url" value="${url}"/>
		<property name="username" value="${username}"/>
		<property name="password" value="${password}"/>
	</dataSource>
	</environment>
</environments>

可以配置多套数据库,使用default指定默认,通过id

2.mappers 元素

定义映射的sql文件。
方式一:使用类路径的资源引用

<mappers>
	<mapper resource="com/dfh/userMapper.xml"/>
</mappers>

方式二:使用完全限定资源定位符

<mappers>
file后面至少两个// 可以达到访问根目录
	<mapper url="file///src/main/java/com/dfh/userMapper.xml"/>
</mappers>

方式三:使用映射器接口实现类的完全限定类名
需要配置文件名称和接口名称一致,并且位于同一目录下

<mappers>
	<mapper class="com.dfh.mapper.userMapper"/>
</mappers>

方式四:将包内的映射器接口实现全部注册为映射器
但是需要配置文件名称和接口名称一致,并且位于同一目录下

<mappers>
	<mapper package="com.dfh.mapper"/>
</mappers>

3、利用properties文件优化配置

1.建立db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
pwd=root

2.修改配置文件


<configuration>
<!--导入properties文件-->
	<properties resource="db.properties"/>
	<environments default="test">
		<environment id="test">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="${driver}"/>
				<property name="url" value="${url}"/>
				<property name="username" value="${username}"/>
				<property name="password" value="${pwd}"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="mapper/UserMapper.xml"/>
	</mappers>
</configuration>

4.typeAliases

类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

<!--配置别名,注意顺序-->
<typeAliases>
	<typeAlias type="com.kuang.pojo.User" alias="User"/>
</typeAliases>
<!--方式二 指定包名,如果类上没有用注解@Alias("user")规定,默认首字母小写作为别名 -->
<typeAliases>
	<package name="com.kuang.pojo"/>
</typeAliases>

5.日志

Mybatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具:
SLF4J
Apache Commons Logging
Log4j 2
Log4j
JDK logging
具体选择哪个日志实现工具由MyBatis的内置日志工厂确定。它会使用最先找到的(按上文列举的顺序
查找)。 如果一个都未找到,日志功能就会被禁用。

<settings>
	<setting name="logImpl" value="STDOUT_LOGGING"/> 
</settings>

使用LOG4J

//首先导包
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

log4j.properties 配置文件

log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

然后到数据库配置文件中修改setting值

<settings>
	<setting name="logImpl" value="LOG4J"/>
</settings>

最后就可以使用LOG4J输出
private static Logger logger=Logger.getLogger(test.Class);

四、生命周期和作用域

1.Mybatis执行流程图

在这里插入图片描述理解:
SqlSessionFactoryBuilder 的作用在于创建 SqlSessionFactory,创建成功后,SqlSessionFactoryBuilder 就失去了作用,所以它只能存在于创建 SqlSessionFactory 的方法中,而不要让其长期存在。因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是
局部方法变量)。
SqlSessionFactory 可以被认为是一个数据库连接池,它的作用是创建 SqlSession 接口对象。因为MyBatis 的本质就是 Java 对数据库的操作,所以 SqlSessionFactory 的生命周期存在于整个MyBatis 的应用之中,所以一旦创建了 SqlSessionFactory,就要长期保存它,直至不再使用MyBatis 应用,所以可以认为 SqlSessionFactory 的生命周期就等同于 MyBatis 的应用周期。
由于 SqlSessionFactory 是一个对数据库的连接池,所以它占据着数据库的连接资源。如果创建多个 SqlSessionFactory,那么就存在多个数据库连接池,这样不利于对数据库资源的控制,也会导致数据库连接资源被消耗光,出现系统宕机等情况,所以尽量避免发生这样的情况。
因此在一般的应用中我们往往希望 SqlSessionFactory 作为一个单例,让它在应用中被共享。所以说 SqlSessionFactory 的最佳作用域是应用作用域。
如果说 SqlSessionFactory 相当于数据库连接池,那么 SqlSession 就相当于一个数据库连接(Connection 对象),你可以在一个事务里面执行多条 SQL,然后通过它的 commit、rollback等方法,提交或者回滚事务。所以它应该存活在一个业务请求中,处理完整个请求后,应该关闭这条连接,让它归还给 SqlSessionFactory,否则数据库资源就很快被耗费精光,系统就会瘫痪,所以用 try…catch…finally… 语句来保证其正确关闭。所以 SqlSession 的最佳的作用域是请求或方法作用域。

五、 #和$的区别

#{}的作用是替换预编译语句中的占位符
${}的作用是直接进行字符替换

简明的解释:

#{}是预编译处理,$ {}是字符串替换(当做占位符来用)。

mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的
set方法来赋值;
例子/:select * from user where id=#{id}
#{} 可以根据所需类型进行符值,如果是字符就是‘12’,如果是整型就是id=12
mybatis在处理 $ {} 时,就是把 ${} 替换成变量的值。

而¥{id}不进行数据类型匹配,直接替换掉。
所以如果id是字符类型,sql语句应该写成 select * from user where id='${id}'
使用 #{} 可以有效的防止SQL注入,提高系统安全性。

在某些特殊场合下只能用${},不能用#{}。例如:在使用排序时ORDER BY ${id},
如果使用#{id},则会被解析成ORDER BY “id”,这显然是一种错误的写法。

**到此结束即可**

六、ResultMap 的使用

1.多对一

设定学生和老师两个类,学生与老师的关系是多对一,多个学生对应一个老师。
建学生实体类和dao层接口

@Data
public class Student {
	private int id;
	private String name;
	//多个学生可以是同一个老师,即多对一
	private Teacher teachers;
}

接口方法  
public List<Student> getStudents();

然后建对应Mapper文件


<resultMap id="StudentTeacher" type="Student">
	<id property="id" column="sid"/>
	<result property="name" column="sname" />
	<association property="teachers" javaType="Teacher" >
		<result property="name" column="tname"/>
	</association>
</resultMap>

<select id="getStudents" resultMap="StudentTeacher">
	select s.id sid, s.name sname , t.name tname 
	from student s,teacher t where s.tid=t.id
</select>

2.一对多

一个老师拥有多个学生
编写类

@Data
public class Student {
	private int id;
	private String name;
	private int tid;
}
@Data
public class Teacher {
private int id;
private String name;
//一个老师多个学生
private List<Student> students;
}

然后写接口,建立对应Mapper文件,此处省略,主要是看mapper

<resultMap id="ST" type=teacher>
	<id property="id" column="tid"/>
	<result property="name" column="tname" />
	<collection property="students" ofType="Student">
		<result property="id" column="sid" />
		<result property="name" column="sname" />
		<result property="tid" column="tid" />
	</colection>
</resultMap>

<select id="getTeacher" resultMap="ST">
	select s.name sname ,t.name tname,t.id tid
	from student s,teacher t
	where s.tid=t.id and t.id=#{tid}
</select>

注意: JavaType和ofType都是用来指定对象类型的 JavaType是用来指定pojo中属性的类型 ofType指定的是映射到list集合属性中pojo的类型。

七 动态SQL

trim 属性
prefix:前缀覆盖并增加其内容
suffix:后缀覆盖并增加其内容
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件


<insert id="insertUser" parameterType="User">
	insert into user
	<trim prefix="(" suffix=")" suffixOverrides=",">
			<if test="name !=null and name!=''">name,</test>
			<if test="phone!=null ">phone,</test>
	</trim>
	<trim prefix="values (" suffix=")" suffixOverrides=",">
			<if test="name !=null and name!=''">#{name},</test>
			<if test="phone!=null ">#{phone},</test>
	</trim>
</insert>

<update id="updateUser" parameterType="User">
	update useri
	<trim prefix="set" suffixOverrides=",">
			<if test="name !=null and name!=''">name=#{name},</test>
			<if test="phone!=null ">phone=#{phone},</test>
	</trim>
	where id=#{id}
</update>

foreach 循环语句
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
select * from blog where 1=1 and (id=1 or id=2 or id=3)

<select id="selectByIdList" resultType="User">
	select * from user
	<where>
		<foreach collection="ids" item="id" open="(" close=")" separator="or">
		    id=#{id}
		</foreach>
	</where>
</select>
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值