参考资料《深入浅出Mybatis技术原理与实战》
第二章 Mybatis入门
2.2 Mybatis的基本构成
SqlSessionFactoryBuilder(构造器):它会根据配置信息或者代码来生成SqlSessionFactory(工厂接口);
SqlSessionFactory:依靠工厂来生成SqlSession(会话);
SqlSession:是一个既可以发送SQL去执行并返回结果,也可以获取Mapper的接口。
SQL Mapper:它是Mybatis新设计的组件,它是由一个Java接口和XML文件(或注解)构成,需要给出对应的SQL和映射规则。它负责发送SQL去执行,并返回结果。
2.2.2 创建SqlSession
构建SqlSessionFactory,然后生成MyBatis的门面接口SqlSession。SqlSession接口类似一个JDBC中的Connection接口对象,我们需要保证每次用完正常关闭它,所以正确的做法是把SqlSession接口写在finally语句中,保证每次都会关闭SqlSession,让连接资源归还数据库。
//定义SqlSession SqlSession sqlSession = null; try{ //打开SqlSession 会话 sqlSession = sqlSessionFactory.openSession(); //some code... sqlSession.commit(); } catch(Exception ex){ System.err.println(ex.getMessage()); sqlSession.rollback(); } finally { //在finally 语句中确保资源顺利关闭 if(sqlSession !=null){ sqlSession.close(); } }
SqlSession 的用途主要有两种。
(1)获取映射器,让映射器通过命名空间和方法名称找到对应的SQL,发送给数据库执行后返回结果。
(2)直接通过命名信息去执行SQL返回结果,这是iBatis版本留下的方式。在SqlSession层我们可以通过update、insert、select、delete等方法,带上SQL的id来操作XML中配置好的SQL,从而完成我们的工作;与此同时它也支持事务,通过commit、rollback方法提交或者回滚事务。
2.3 生命周期
SqlSessionFactoryBuilder:利用XML或Java编码获得资源来构建SqlSessionFactory的,通过它可以构建多个SessionFactory。它的作用就是一个构建器,一旦我们构建了,它的作用就完结。所以生命周期只存在于方法的局部。
SqlSessionFactory:职责唯一,就是创建SqlSession,使每一个数据库只对应一个SqlSessionFactory,管理好数据库资源分配,避免过多的Connection被消耗,果断采用单利模式。
SqlSession:是一个会话,相当于JDBC的一个Connection对象,生命周期应该是在请求数据库处理事务的过程中。线程不安全,操作数据库需要注意其隔离级别,数据库锁等高级特性。每次创建SqlSession都必须及时关闭它,它长期存在就会使数据库连接池的活动资源减少,对系统性能的影响很大。
Mapper:是接口,没有实现类,作用是发送SQL,然后返回结果,或者执行SQL从而修改数据库数据,因此它应该在一个SqlSession事务方法之内,是一个方法级别的东西。它如同JDBC中的一条SQL语句的执行,它最大的范围和Sql是相同的。尽管我们想一直保存着Mapper,但是它很难控制,所以尽量在一个SqlSession事务的方法中使用它,然后废弃掉。(当Sql销毁的时候,也会销毁它)
第三章:配置
MyBatis配置XML文件的层次结构。注意这些层次是不能颠倒顺序的,否则MyBatis在解析XML文件的时候就会出现异常。
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!--配置--> <properties/><!--属性--> <settings/><!--设置--> <typeAliases/><!--类型命名--> <typeHandlers/><!--类型处理器--> <objectFactory/><!--对象工厂--> <plugins/><!--插件--> <environments><!--配置环境--> <environment><!--环境变量--> <transactionManager/><!--事务管理器--> <dataSource/><!--数据源--> </environment> </environments> <databaseIdProvider/><!--数据库厂商标识--> <mappers/><!--映射器--> </configuration>
第四章 映射器
映射器是MyBatis最强大的工具,也是我们使用MyBatis时用得最多的工具。
4.2 select 元素
4.2.4 传递多个参数
使用@param注解传递多个参数,这种方式的使用受到参数个数(n)的影响。当n<=5时,它是最佳传参方式,它比JavaBean更好,因为它更加直观;当n>5时,,多个参数将给调用带来困难。
当参数个数多余5个时,建议使用JavaBean方式。
//MyBatis的参数注解@Param(org.apache.ibatis.annotation.Param)来实现想要的功能。 public List<Role> findRoleByAnnotation(@Param("roleName")) String rolenam,@Param("note") String note);
<select id="findRoleByAnnotation" resultMap="roleMap">
select id, role_name,note from t_role
where role_name like concat('%',#{roleName},'%')
and note like concat('%',#{note},'%')
</select>
参数过多的情况下,MyBatis允许组织一个JavaBean,通过简单的setter和getter方法设置参数,这样就可以提高我们的可读性。首先,定义一个RoleParams的JavaBean,如
pack com.learn.chapter4.params;
public class RoleParam{
private String roleName;
private String note;
public String getRoleName(){
return roleName;
}
public void setRoleName(String roleName){
this.roleName=roleName;
}
public string getNote(){
return note;
}
public void setNote (String note){
this.note=note;
}
<select id="findRoleByParams" parameterType="com.learn.chapter4.params.RoleParam",resultMap="roleMap">
select id,role_name,note from t_role
where role_name like concat('%',#{roleName},'%')
and note like concat('%',#{note},'%')
</select>
4.2.5 resultMap映射结果集
<resultMap id="roleResultMap" type="com.learn.pojo.Role"> <id property="id" column="id"/>
<result property="roleName" column="role_name"/>
<result property="note" column="note"/>
</resultMap>
<select parameterType="long" id="getRole" resultMap="roleResultMap" >
select id,role_name,note from t_role where id=#{id}
</select>
说明:
定义唯一标识符(id)为roleResultMap的resultMap,用type属性去定义它对应那个JavaBean,此事也可以使用别名
4.7 resultMap结果映射集
<resultMap> <constructor> <idArg/> <arg/> </constructor> <id/> <result/> <association/> <collection/> <discriminator> <cals/> </discriminator> </resultMap>
第五章 动态SQL
5.2 if元素
<select id="findRoles" parameterType="string" resultMap="resultRoleMap" > select role_no,role_name,note from t_role where 1=1 <if test="roleName!=null and roleName!=''"> and role_name like concat ('%',#{roleName},'%') </if> </select>
5.3 choose、when、otherwise
<select id="findRoles" parameterType="role" resultMap="resultRoleMap" > select role_no,role_name,note from t_role where 1=1 <choose> <when test="roleNo!=null and roleNo!=''"> AND role_no=#{roleNo} </when> <when test="roleNname!=null and roleName!=''"> AND role_name like concat('%',#{roleName},'%') </when> <otherwise> AND note is not null </otherwise> </choose> </select>
5.4 trim、where、set
<select id="findRoles" parameterType="string" resultMap="roleResultMap"> select role_no,role_name,note from t_role <where> <if test="roleName!=null and roleName!=''"> and role_name like concat('%',#{roleName},'%') </if> </where> </select>
<select id="findRoles" parameterType="string" resultMap="roleResultMap"> select role_no,role_name,note from t_role <trim prefix="where" prefixOverrides="and"> <if test="roleName!=null and roleName!=''"> and role_name lile concat('%',#{roleName},'%') </if> </trim> </select>
<update id="updateRole" parameter="role"> update t_role <set> <if test="roleName!=null and roleName!=''"> role_name=#{roleName}, </if> <if test="note!=null and note!=''"> note=#{note} </if> </set> where role_no=#{roleNo} </update>
set遇到逗号,会把对应的逗号去掉。
5.5 foreach元素
<select id="findUserBySex" resultType="user"> select * from t_user where sex in <foreach item="sex" index="index" collection="sexList" open="(" separator="," close=")"> #{sex} </foreach> </select>
注:
collection:配置的sexList是传递进来的参数名字,它可以是一个数值或者List、Set等集合
item:配置的是循环中当前的元素。
index:当前元素在集合中下表
open和close:以什么符号将集合中元素包裹起啦
separator:各元素的间隔符
第八章 MyBatis-Spring