MyBatis笔记
Mybatis:将java对象映射成SQL语句,再将结果转化为java对象,解决了java对象和sql拼接、结果集的问题,又可以自己写sql语句
总体结构:
根据JDBC规范建立与数据库的连接
通过反射打通java对象与sql参数的交互
交互式框架:
1、准备好交互环境
2、构建一个交互环境,在交互环境还划分为会话,每次会话都有一个环境
3、交换数据
Mybatis
1、Mybatis配置文件 conf.xml
2、根据数据库表编写对应实体类
3、定义操作表的sql映射文件
4、在Mybatis配置文件注册实体映射文件
测试:
1、getClassLoader加载配置文件
2、利用SqlSessionFactory创建session
3、session通过实体映射文件操作数据,返回resultType
Hibernate:
1、创建实体类
2、创建实体映射文件
3、Hibernate配置文件
4、利用Configuration读取配置文件
5、sessionFactory创建session
6、操作数据 save deleter update
7、提交事务
1、多表查询
实体类:Class类中含有Teacher实体类,通过association标签将查询的结果传给Teacher,这样结果就返回到Class实体类中
public class Teacher{
private String id;
private String name;
}
public class Class{
private String id;
private String name;
private Teacher teacher
}
1.1、嵌套查询: select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=1
<select id="getClass" parameterType="int" resultMap="ClassResultMap">
select * from class c, teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
</select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="me.gacl.domain.Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap>
1.2、嵌套查询:通过执行另外一个SQL映射语句来返回预期的复杂类型
SELECT * FROM class WHERE c_id=1;
SELECT * FROM teacher WHERE t_id=1
<select id="getClass2" parameterType="int" resultMap="ClassResultMap2">
select * from class where c_id=#{id}
</select>
<!-- 使用resultMap映射实体类和字段之间的一一对应关系 -->
<resultMap type="me.gacl.domain.Classes" id="ClassResultMap2">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" column="teacher_id" select="getTeacher"/>
</resultMap>
<select id="getTeacher" parameterType="int" resultType="me.gacl.domain.Teacher">
SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
</select>
2、sql片段与动态sql
动态sql,内部判断传入的参数是否符合,会动态的舍弃一些参数
<select id="findUserList" parameterType="cn.bj.mybatis.model.UserQueryVO"
resultType="cn.bj.mybatis.model.UserCustom">
select * from t_user
<!-- where可以自动去掉第一个条件的and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and t_user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and t_user.username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
sql片段、将sql语句拿出来,在引入
<select id="findUserList" parameterType="cn.bj.mybatis.model.UserQueryVO"
resultType="cn.bj.mybatis.model.UserCustom">
select * from t_user
<!-- where可以自动去掉第一个条件的and -->
<where>
<!-- sql片段引入 -->
<include refid="query_user_where"></include>
</where>
</select>
<!-- sql片段 -->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and t_user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and t_user.username like '%${userCustom.username}%'
</if>
</if>
</sql>
3、MyBatis调用缓存
一级缓存:默认开启,如果session没有关闭,再次按照上次查询的条件查询时不会发出SQL语句,会从缓存中去数据
//session.clearCache(); 主动清理缓存
//session.close();session关闭则缓存不再有
SqlSession session = MyBatisUtil.getSqlSession();
String statement = "me.gacl.mapping.userMapper.getUser";
User user = session.selectOne(statement, 1);
System.out.println(user);
/*
* 一级缓存默认就会被使用
*/
user = session.selectOne(statement, 1);
System.out.println(user);
session.close();
二级缓存:<mapper namespace="me.gacl.mapping.userMapper">
<!-- 开启二级缓存 -->
<cache/>
原理:在使用不同的Sqlsession执行相同条件查询时不会发出SQL语句,而是直接从缓存中取
//开启两个不同的SqlSession
SqlSession session1 = factory.openSession();
SqlSession session2 = factory.openSession();
//使用二级缓存时,User类必须实现一个Serializable接口===> User implements Serializable
User user = session1.selectOne(statement, 1);
session1.commit();//不懂为啥,这个地方一定要提交事务之后二级缓存才会起作用
System.out.println("user="+user);
//由于使用的是两个不同的SqlSession对象,所以即使查询条件相同,一级缓存也不会开启使用
user = session2.selectOne(statement, 1);
//session2.commit();
System.out.println("user2="+user);
补充说明:
1. 映射语句文件中的所有select语句将会被缓存。
2. 映射语句文件中的所有insert,update和delete语句会刷新缓存。
3. 缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
4. 缓存会根据指定的时间间隔来刷新。
5. 缓存会存储1024个对象
4、属性配置说明
属性 描述
property 需要映射到JavaBean 的属性名称。
column 数据表的列名或者标签别名。
javaType 一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。
jdbcType 数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。
typeHandler 使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。