一、Mybatis简介
Mybatis是一款优秀的持久层框架,它支持定制化SQL、储存过程以及高级映射。Mybatis避免了几乎所有的JDBC的代码和手动设置参数以及获取结果集,Mybatis可以使用简单的XML或者注解来配置和映射原生类型、接口和JAVA的POJO(Plain Old Java Object,普通老式Java对象)为数据库中的记录。
二、体系结构
API接口层:
提供给外部使用的接口 API,开发人员通过这些本地API来操纵数据库。接口层一收到调用请求就会调用数处理层来完成具体的数据处理。
数据处理层:
负责具体的SQL查找、SQL解析、SQL执行和结果映射处理等。它主要的目是根据调用请求完成一次数库操作。
基础支撑层:
负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础组件,为上层的数据处理层提供最基础支撑。
三、Java项目中Mybatis基础使用
1.第一步:导入jar包:
导入mybatis、mysql的jar包(代码如下)
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
2、第二步:在resources文件夹下面创建config.xml
- 新建config.xml;
- 新建mapper文件夹;
- pom.xml文件中导入api包;
3.在mapper文件夹下面创建 XXXmapper接口、XXXmapper.xml; 在config.xml中引入所写的 XXXmapper.xml文件;
a)XXXmapper接口中书写方法;
b) XXXmapper.xml文件中
c)在config.xml中引入所写的 XXXmapper.xml文件
4、运行测试
四、MyBatis表之间的关系
1、多对一 (XML方式)
a)自动映射:resultType=“”
b)手动映射:colum(名不区大小写)的值给 property(名区大小写);代码如下:
<resultMap id="映射名字" type="对那个bean包的类进行映射">
<id property="表主键名" colum="主键列字段">
<result property="非主键列字段" colum="非主键列字段">
</resultMap>
//外键(多对一关系)
<association property = "‘多对一’中的EmpInfo类中的‘一’的名" javaType="类地址">
<id property="表主键名" colum="主键列字段">
<result property="非主键列字段" colum="非主键列字段">
</association>
2、多对一 (注解方式)
public interface EmpAnnotationMapper {
@Select("SQL语句")
@Results({
@Result(property = "列字段",column = "列字段",id = true), //主键列需要将Id写为true
@Result(property = "其他列字段",column = "其他列字段"),
//关系
@Result(property = "‘多对一’中的EmpInfo类中的‘一’的名",column = "连接的值",
one = @One(select = "获取另一张表信息的查询方法名"))
})
EmpInfo findEmpByEmpId(int empNo);
}
3、一对多(XML方式)
<resultMap id="映射名字" type="对那个bean包的类进行映射">
<id property="表主键名" colum="主键列字段">
<result property="非主键列字段" colum="非主键列字段">
</resultMap>
//外键(一对多关系)
<collection property = "‘一对多’中的多的泛型名" ofType="泛型的类型">
<id property="表主键名" colum="主键列字段">
<result property="非主键列字段" colum="非主键列字段">
</collection>
4、一对多 (注解方式)
public interface DeptAnnotationMapper {
@Select("SQL语句")
@Results({
@Result(property = "列字段",column = "列字段",id = true), //主键列需要将Id写为true
@Result(property = "其他列字段",column = "其他列字段"),
//关系
@Result(property = "‘一对多’中的多的集合名",column = "连接的值",
many = @many(select = "获取另一张表信息的查询方法名"))
})
DeptInfo findDeptByDeptNo(int deptNo);
}
五、MyBatis的缓存
a)一级缓存
基于perpetualCache的HashMap本地缓存,其储存作用域为Session,当Session flush或 close 之后,该 Session中的所有Cache就将清空。 一级缓存默认是长开启的。
1.一级缓存的生命周期:
a)Mybatis开启一个数据库会话时,会创建一个Sqlsession对象,当会话结束时,释放缓存;close()方法;
b)当调用clearCache()方法时,释放缓存;
c)当执行了任何一个 update操作 (改update()、删delete()、增insert())时清空缓存;
2.怎么判断两次查询是相同的?
归根结底一句话:只要两次查询的SQL语句一样,就认为是相同的两次查询。
b)二级缓存
二级缓存与一级缓存的机制是相同的,默认也是采用PerpetualCache,HashMap储存,不同点在于其储存的作用域为Mapper(Namespace),并且可自定义储存源,如Ehcache。
1.开启二级缓存:
①在config.xml中开启二级缓存:<setting name="cacheEnabled" value="true"/>
(xml和注解第一、三步相同,第二步不同)
②XML方式:mapper.xml中在<mapper>下面加入:<cache/>
注解方式:在XXXMapper接口类上面加入:@CacheNamespace(blocking = true)
③让bean包下的类序列化:实现接口 Serializeable
注:
* XML和注解方式下,session用完要关闭,否则会一直占用着资源。
* 一级缓存只能自己本地使用,二级缓存是全局的,大家都可以用。
六、SQl
1.实现:
①
<if test=“条件”>
SQL语句拼接语句
</if>
② 在XXXMapper中SQl语句:
<where>
<if test=“条件”>
and/or SQL语句拼接语句
</if>
<if test=“条件”>
and/or SQL语句拼接语句
</if>
</where>
* where 里面只要有一个条件成立,则会自动忽略if里面语句前面的 and或者or
③ 在XXXMapper中SQl语句:
<trim prefix=“前缀” prefixOverrides=“忽略前面第一次出现的内容”>
//同理suffix=“后缀”suffixOverrides=“忽略后面第一次出现的内容”
<if test=“条件”>
and/or SQL语句拼接语句
</if>
<if test=“条件”>
and/or SQL语句拼接语句
</if>
</trim>
④ 在XXXMapper中SQl语句:
<foreach collection="集合名" item="迭代名" separator="以什么隔开" open="以什么开始" close="以什么结束">
⑤ 在XXXMapper中SQl语句:
<select id="方法名" resultType="返回结果类型" parameterType="输入类型">
select * from emp
<where>
<choose>
<when test="条件1">
sql语句1
</when>
<when test="条件2">
sql语句2
</when>
<otherwise> //否则
sql语句3
</otherwise>
</choose>
</where>
</select>
2、给输入、输出数据类型起别名(写在config.xml中)
<!--起别名-->
<typeAliases>
<typeAlias type="输入、输出数据类型" alias="起的名字"/>
</typeAliases>