Mybatis 基础知识
Mybatis 的执行过程
-
- 加载 mybatis 配置文件,得到一个输入流
-
- 通过 SqlSessionFactoryBuilder().build() 加载输入流, 从而获得 SqlSessionFactory, SqlSessionFactory 是单例的;相当于数据库连接池
-
- 通过 SqlSessionFactory.openSession(), 获取 SqlSession
-
- SqlSession 执行 xxMapper.xml
-
- sqlSession.close();
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("com.foo.bean.BlogMapper.queryAllBlogInfo");
// 提交事务
sqlSession.commit();
// 关闭连接
sqlSession.close();
configuration 配置文件中的几个重要属性
typeAliases
bean 的别名;
有两种方式:
1.
</select>
<select id="selById2" resultType="user" >
select * from people where id = #{id}
</select>
在 configuration.xml 中
<typeAliases>
<typeAlias type="com.xx.User" alias="user"/>
</typeAliases>
或者
<typeAliases>
<!--使用包扫描的方式-->
<package name="com.xx"/>
</typeAliases>
2.
@Alias("user")
public class User{...}
properties
使用方式有三种:
1:
在properties 属性中增加 property 属性,用来设置一些属性的name, value
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
2:
引入外部配置类
<properties resource="db.properties" />
3:
Java 代码中使用,获取配置文件中的属性
String resource = "mybatis-config.xml";
InputStream is = Resources.getResourceAsStream("db.properties");
Properties properties = new Properties();
properties.load(is);
String userName = properties.getProperty("db.username");
String pwd = properties.getProperty("db.pwd");
properties.setProperty("db.username", CyperTool.decodeByBase64(userName));
settings
<settings>
<setting name="cacheEnabled" value="true" />
<setting name="useGeneratedKeys" value="true" />
<setting name="defaultExecutorType" value="REUSE" />
<setting name="logImpl" value="STDOUT_LOGGING" /> //
</settings>
- cacheEnabled // 全局开启或者关闭缓存, true/false
- lazyLoadingEnabled // 全局懒加载开关
- logimpl // 指定 mybatis 日志的具体实现,未指定时将自动查找
xxMapper.xml 重要的属性
ResultMap 结果集映射
设置数据库字段和bean 属性映射
<resultMap id="BaseResultMap" type="com.xx.User">
<id column="ID" jdbcType="BIGINT" property="id" />
<result column="SKU_NAME" jdbcType="VARCHAR" property="skuName" />
<result column="CATEGORY_ID" jdbcType="BIGINT" property="categoryId" />
</resultMap>
<select id="getUserList" resultMap="BaseResultMap" parameterType="User">
Mybatis 分页
1. limit
2. 利用 RowBounds
注解
1. 绑定接口
public interface UserMapper {
@Select("select * from user")
List<User> findAll();
}
多个参数 @Param
只能在元素参数上使用
Public User selectUser(@param(“userName”)String name,@param(“userArea”)String area);
<select id=" selectUser" resultMap="BaseResultMap">
select * from user_user_t where user_name = #{userName,jdbcType=VARCHAR} and user_area=#{userArea,jdbcType=VARCHAR}
</select>
${} 和 #{} 区别
#{} 是预编译的,防止SQL注入
association 、collection
<resultMap type="Student" id="studentResultMap">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="gender" property="gender" />
<result column="major" property="major" />
<result column="grade" property="grade"/>
// 集合 - 一对多
<collection property="emps" ofType="com.mybatis.bean.Employee">
<id column="eid" property="id"/>
<result column="last_name" property="lastName"/>
<result column="email" property="email"/>
<result column="gender" property="gender"/>
</collection>
// 对象 - 多对一
<association property="supervisor" javaType="Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
<result property="gender" column="t_gender"/>
<result property="researchArea" column="research_area"/>
</association>
</resultMap>
#
ofType : 用来指定映射到 List
JavaType : 指定实体类中属性的类型
动态 SQL
根据不同的条件生成不同的 SQL, Mybatis 的动态SQL 基于 OGNL 表达式
if
<select id="dynamicIfTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<if test="title != null">
and title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</select>
choose
<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>
trim
<select id="dynamicTrimTest" parameterType="Blog" resultType="Blog">
select * from t_blog
<trim prefix="where" prefixOverrides="and |or">
<if test="title != null">
title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
or owner = #{owner}
</if>
</trim>
</select>
where
<select id="dynamicWhereTest" parameterType="Blog" resultType="Blog">
select * from t_blog
<where>
<if test="title != null">
title = #{title}
</if>
<if test="content != null">
and content = #{content}
</if>
<if test="owner != null">
and owner = #{owner}
</if>
</where>
</select>
set
<update id="dynamicSetTest" parameterType="Blog">
update t_blog
<set>
<if test="title != null">
title = #{title},
</if>
<if test="content != null">
content = #{content},
</if>
<if test="owner != null">
owner = #{owner}
</if>
</set>
where id = #{id}
</update>
foreach
对集合进行遍历
<select id="dynamicForeachTest" resultType="Blog">
select * from t_blog where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>
动态SQL include
引用SQL片段
<include refid = "" />
MyBatis 缓存
经常查询的数据存在内存中的临时数据,为了减少与数据库的交互 两级缓存。默认只开启一级缓存(sqlsession 级别的,也成为本地缓存), 二级缓存需要手动开启,它是基于nameSpace 级别的缓存, Mybatis 提供了 Cache 接口,可以通过它来自定义二级缓存
一级缓存
也叫本地缓存,与数据库同一次查询期间(SqlSession 开启到关闭期间)缓存到本地缓存,下次查询相同数据,直接获取
缓存失效的情况
- 查询不同的东西
- 增删改
- 关闭清楚缓存, sqlSession.clearCache()
二级缓存
<!--开启二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
其次在 UserMapper.xml 文件中开启缓存
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
Mybatis 的缓存机制原理
第一次查询先看二级缓存,再看一级缓存,都没有走数据库,放入一级缓存;
使用自定义缓存
TODO.....
常用版本
3.x
Spring 整合 Mybatis
步骤:
-
- 导入相关 jar 包
- junit
- mybatis
- mysql 数据库
- Spring 相关
- aop 织入
- mybatis-spring
- 导入相关 jar 包
-
- 编写配置文件
xxMapper.xml
1. namespace - 命名空间,绑定一个对应的 Mapper 接口,名字一致
2. <select id ="xx" ....> - id 对应 Mapper 接口的方法名
3. <select id ="xx" resultType = "com.xx..."> - resultType 返回值
4. parameType - 参数类型
5. #{id} - 占位符获取参数
6. <insert parameType = "com.xx"
面试题
SqlSession 和 Mapper 是如何执行的?
通过mapeer.xml 的 namespace 来唯一定位
Mybatis 默认连接是什么?
JDBC , 默认连接池方式