MyBatis笔记从入门到精通
什么是框架
概念:
框架是可被应用开发者定制的应用骨架.
简单记,就是别人写好了一部分代码, 我们在此基础上进行开发. 别人写好的这个部分代码就称为框架.
为什么使用框架:
让开发更加便捷
项目的三层架构:
1.表现层
{springmvc/struts2}
2.业务逻辑层
3.数据持久层
mybaits/hibernate
框架架构讲解:
(1)加载配置:
配置来源于两个地方,一处是配置文件,一处是Java代码的注解,将SQL的配置信息加载成为一个
mybatis结构个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)SQL解析:
当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map、JavaBean或者基本数据类型),Mybatis会根据SQL的ID找到对应 的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行:
将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果。
(4)结果映射:
将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型,封装并将最终结果返回。
MyBatis的入门案例<超重点>
1.在pom.xml文件中引入相关的依赖
2.编写user实体类 User
3.编写持久层接口 以及方法 list
4.编写持久层接口的 映射文件
<mapper namespace="com.itheima.dao.IUserDao">
<select id="findAll" resultType="com.itheima.domain.User">
select * from user
select>
mapper>
注意: 位置 : 必须和持久层接口在相同的包下
命名: 必须以持久层接口命名文件名,扩展名是.xml
5.编写 SqlMapConfig.xml 配置文件
<configuration>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ee50"/>
<property name="username" value="root"/>
<property name="password" value="1234"/>
dataSource>
environment>
environments>
resultMap的值是我们定义的resultMap标签的id
#{}与${}的区别
#
{}表示一个占位符号 相当于 ?
${}表示拼接 sql 串
SqlMapConfig.xml配置文件
1properties(属性)
一般用于配置数据库的4大金刚
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy_mybatis"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="1234"/>
2 ty peAliases(类型别名)
<package name="com.itheima.domain"/>
3.mappers(映射器)
如:
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。
连接池
UNPOOLED 不适用连接池的数据源
POOLED 使用连接池的数据局源
JNDL 使用JNDI实现的数据源
注释:以后我们和spring整合后,可以使用其他第三方的连接池 如c3p0
事物
1.什么是事物:单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行
简单说: 一个逻辑操作中的所有sql语句 , 要么执行成功要么失败
2.不考虑事物的隔离性出现问题
脏读
不可重复读
幻读
3.自动提交事务
sqlSession = factory.openSession(true);
总结 多表查询之间的关系
一对一 实体类中 有一个user对象
一对多 实体类中 有一个user集合
一对多 实体类中 有一个user集合
多对一 实体类中 有一个user集合
这两个加在一起就是多对多的关系
配置文件(表单查询)
多表查询(主要是看后面的一 还是 多 )
多对一{一对一}
实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//从表实体应该包含一个主表实体的对象引用
private User user;
映射文件
<resultMap id="accountUserMap" type="account">
<result property="id" column="aid">result>
<result property="uid" column="uid">result>
<result property="money" column="money">result>
<association property="user"(属性) column="uid" javaType="user">(对应类型)
<id property="id" column="id">id>
<result column="username" property="username">result>
<result column="address" property="address">result>
<result column="sex" property="sex">result>
<result column="birthday" property="birthday">result>
association>
resultMap>
<resultMap id="userAccountMap" type="user">
<id property="id" column="id">id>
<result property="username" column="username">result>
<result property="address" column="address">result>
<result property="sex" column="sex">result>
<result property="birthday" column="birthday">result>
<collection property="accounts" (集合属性) ofType="account"> (对应类型)
<id column="aid" property="id">id>
<result column="uid" property="uid">result>
<result column="money" property="money">result>
collection>
resultMap>
```
<include refid="defaultSql">include>
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in ( " close=")" item="uid"
separator=",">
#{uid}
foreach>
if>
where>
select>
SQL 语句:
select 字段 from user where id in (?)
标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}(就是实体类中的 list 集合)
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名(随便起 item=”uid”,但是要和 后面取值的变量一致 #{uid} )
sperator:代表分隔符 * ( 一般用 , 号 )
====================================
sql片段
抽取代码块片段
"defaultSql">
select * from user
引 用代码块片段
<select id="findAll" resultType="user">
<include refid="defaultSql">include>
select>
<
!– 根据 id 查询 –>
<select id="findById" resultType="UsEr" parameterType="int">
"defaultSql">
where id = #{uid}
select>
MyBatis延迟加载
1 延迟加载和立即加载的概念
就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载.
总是在加载用户信息时就一定要加载他的账户信息。
2 mybatis一对一实现延迟加载
老规矩:1.sql语句,2.pojo类,3.mapper.xml和mapper.java接口
使用 association实现延迟加载 一对一
使用 Collection 实现延迟加载 一对多
pojo类
public class Orders {
private String number;
private Date createtime;
private String note;
//用户信息,新增了一个User属性,为了保存查询得到的关联的User表的信息(一对一)
private User user;
映射文件
resultMap type=”user” id=”userMap”>
id column=”id” property=”id”> !– collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称)
column 是用于指定使用哪个字段的值作为条件查询
迟加载的开关
在SqlMapConfig.xml中
- 开启二级缓存
setting >name=”cacheEnabled”value=”true”/>
执行上边mapper方法(findOrdersUserLazyLoading),内部去调用com.iot.mybatis.mapper.OrdersMapperCustom中的findOrdersUserLazyLoading只查询orders信息(单表)。
在程序中去遍历上一步骤查询出的List,当我们调用Orders中的getUser方法时,开始进行延迟加载。
延迟加载,去调用UserMapper.xml中findUserbyId这个方法获取用户信息。
3 mybatis一对多实现延迟加载(同上)
MyBatis缓存
1 缓存的概念
像大多数的持久化框架一样,Mybatis 也提供了缓存策略,通过缓存策略来减少数据库的查询次数,从而提 高性能。
2 Mybatis中的一级缓存
默认是存在并且是开启的
3 触发清空一级缓存的情况
一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存
4 mybatis的二级缓存
二级缓存是 mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。
二级缓存的开启与关闭
第一步:在 SqlMapConfig.xml 文件开启二级缓存