1、什么是Mybatis?
mybatis官网:MyBatis中文网
Mybatis是一款用于持久化层的、轻量级的半自动化ORM框架,封装了所有jdbc操作以及设置查询参数和获取结果集的操作,支持自定义sql、存储过程和高级映射
1.1 什么是持久层框架
就是和数据库进行交互的框架,用于数据存储等数据操作的框架
1.2 什么是轻量级框架
简单理解为:所用框架开发的程序启动时占用的资源较少,对业务代码的侵入性不强,比较容易配置,部署简单,不需要依赖于其他框架
1.3 什么是ORM框架
ORM(Object Relational Mapping)即对象关系映射,是用于将对象模型映射到关系数据库的框架,用于实现面向对象编程语言里不同类型系统的数据之间的转换。在使用 Java中的数据类和数据库之间的类型系统不同,因此需要对应的类型转换
1.4 为什么说mybatis是半自动ORM框架
MyBatis 是半自动 ORM 框架,因为它需要我们手动编写 SQL 语句,然后通过 MyBatis 的映射器将 SQL 语句映射到 Java 对象。
2、Mybatis的作用是什么?
用于开发持久层,用于处理Java程序和数据库之间的交互
3、Mybatis的加载过程
1、加载配置文件
2、创建工厂构建器
3、通过构建器对象加载配置文件并创建session工厂
4、通过工厂获取sqlsession对象
5、通过sqlsession来执行SQL
public class App {
public static void main(String[] args) throws IOException {
//mybatis的加载过程
//1、加载配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2、创建工厂构建器
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3、通过构建器对象加载配置文件并创建session工厂
SqlSessionFactory factory = builder.build(in);
//4、通过工厂获取session对象
SqlSession sqlSession = factory.openSession();
//5、通过session来执行SQL
//statement:SQL的标识 namespace.id
Person person = new Person();
person.setAge(18);
person.setName("张三");
person.setSex("男");
int rows = sqlSession.insert("org.example.mapper.PersonMapper.add", person);
System.out.println("rows=" + rows);
}
}
3.1 创建db.properties配置文件
作用:连接数据库的外部数据源文件
#数据库驱动提供了连接数据库的功能,能够建立应用程序与数据库之间的连接通道。
#通过数据库驱动,应用程序可以向数据库发送连接请求并接收返回的结果
#使得应用程序能够和数据库进行交互,执行数据库操作,并处理相关的错误和异常情况
datasource.driverClassName=com.mysql.cj.jdbc.Driver
datasource.username=root
datasource.password=123456
#数据库连接
datasource.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF8&useSSL=false&serverTimezone=UTC
3.2 Mybatis 的配置文件 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>
<!--引入属性文件-->
<properties resource="db.properties"></properties>
<!--全局设置-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" ></setting>
<!--控制本地缓存(一级缓存)
SESSION:默认值,同一个sqlSession执行的查询结果进行缓存
STATEMENT:等同于弃用一级缓存,底层的执行器(executor)仅用于执行sql语句-->
<!-- <setting name="localCacheScope" value="STATEMENT" ></setting>-->
</settings>
<!--环境(数据源、连接池、事务等相关配置-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${datasource.driverClassName}"/>
<property name="username" value="${datasource.username}"/>
<property name="password" value="${datasource.password}"/>
<property name="url" value="${datasource.url}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--使用映射文件-->
<mapper resource="org/example/mapper/PersonMapper.xml"></mapper>
<!--使用注解-->
<mapper class="org.example.mapper.PersonDao"></mapper>
</mappers>
</configuration>
4、动态SQL
静态sql:在编译阶段就可以确定数据库要做什么事情
动态sql:根据程序运行时的条件和需求动态的生成SQL语句
例如每一种数据库软件都有能够执行SQL语句的界面,那个界面接收的SQL就是动态SQL,因为数据库厂商在做这个界面时,并不知道用户会输入哪些SQL,只有在该界面执行后,接收了用户的实际输入,才知道SQL是什么。
动态sql的具体标签
-
if
-
choose(when,otherwise)
-
trim(where,set),update需要结合set使用
-
foreach
1、if
使用动态SQL最常见的请将是根据条件包含 where 子句的一部分
提供了可选的查找文本功能
//if
<select id="select" resultType="org.example.model.Person">
select * from person where
<if test="id!=null">
id=#{id}
</if>
<if test="name!=null">
and name=#{name}
</if>
</select>
2、choose、when、otherwise
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句
<select id="select3" resultType="org.example.model.Person">
select * from person
<where>
<choose>
<when test="id!=null">
id=#{id}
</when>
<when test="name!=null">
name=#{name}
</when>
<when test="age!=null">
age=#{age}
</when>
<otherwise>
1=1
</otherwise>
</choose>
</where>
</select>
3、trim、where、set
-
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
-
trim:去除前后空格,也可以自定义
<select id="select2" resultType="org.example.model.Person">
select * from person
<!--
prefix:以该标签属性的值开头,如果trim标签没内容,该属性值会被忽略掉
prefixOverrides:如果trim标签内的内容是以指定的内容开头,会被忽略掉
suffixOverrides:如果trim标签内的内容是以指定的内容结尾,会被忽略掉
-->
<trim prefix="WHERE" prefixOverrides="and |or" suffixOverrides="and |or" suffix=";">
<if test="id!=null">
id=#{id}
</if>
<if test="name!=null">
and name=#{name} or
</if>
</trim>
</select>
- set:用于动态更新语句的类似解决方案叫做 set。set元素可以用于动态包含需要更新的列,忽略其它不更新的列。并且会删除额外的逗号
<update id="update">
update person
<!--set可以去掉结尾的逗号-->
<set>
<if test="name!=null and name.trim().length() !=0">
name=#{name},
</if>
<if test="age!=null and age>=0">
age=#{age}
</if>
<if test="sex!=null">
sex=#{sex}
</if>
where id=#{id}
</set>
</update>
4、foreach
动态 SQL 的另一个常见使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)
<select id="select4" resultType="org.example.model.Person">
<!--
index=0;
content="(";
for(item:list){
if(last){
content +=item+ ")";
}else{
content+=item+",";
}
index++
}
-->
select * from person where id in
<foreach item="item" collection="list" index="index" open="(" separator="," close=")">
#{item}
</foreach>
</select>
5、Mybatis的缓存
一级缓存和二级缓存
- 一级缓存:session级别的缓存,多个session之间的缓存不能共享 ,一级缓存是默认的缓存设置 清理一级缓存 : 1、clearCache方法
2、commit
3、更新操作(insert,update,delete)
-
二级缓存:mapper级别的缓存,只要是使用用一个映射文件就可以共享代码,可以跨session使用
二级缓存中的数据是从一级缓存中获取的,只有提交事务才会将一级缓存中的事务提交到二级缓存对象需要实现序列化接口
清除二级缓存:
使用更新操作(insert,update,delete)
打开二级缓存
1、在mybatis的配置文件中加入
<setting name="cacheEnabled" value="true" ></setting>
2、在映射文件中加入标签
Mybatis的清除策略 (eviction)
-
LRU:最近最少使用
-
FIFO:先进先出,按照添加顺序,将先添加的清除
-
SOFT:软引用规则
-
WEAK:弱引用规则
优先级
二级缓存 > 一级缓存 > 数据库
6、什么是SQL注入问题
是一种常见的安全漏洞,发生在应用程序未能正确过滤用户输入的情况下。SQL注入攻击者通过用户输入中插入恶意的SQL代码,从而绕过应用程序的验证和控制,对数据库进行非法操作
7、Mybatis中的问题
1、mapper中如何传递多个参数
-
将多个参数封装到实体类或者map中,通过属性名或者key来获取参数值
-
在映射文件中,通过arg0,arg1...或者param1,param2...\
-
通过@param(名称),通过该注解为每个参数指定名称,在映射文件中通过名称来取值
List<Person> selectOrderBy(@Param("fileName") String age,@Param("name") String name);
2、#和$的区别
#{}:替换成?占位符,将来通过Preparedstatement对应为?赋值,一般用于数据
${}:直接用值原样替换SQL中对应位置的{},一般用于表名、库名、字段名