Mybatis-03 连接池&事务&多表查询
1.连接池
1.1 连接池
连接池就是用来存取连接的一个容器,容器其实就是一个集合对象,**该集合必需是线程安全的,防止两个线程拿到同一连接**。且集合实现队列特性,先进先出。
可以减少我们获取连接的时间。
1.2 mybatis中的连接池
1.2.1 数据源分类:


MyBatis内部分别定义了实现了java.sql.DataSource(标准的jdbc接口)接口的UnpooledDataSource,PooledDataSource类来表示 UNPOOLED、POOLED 类型的数据源。
在SqlMapConfig.xml主配置文件中配置,dataSource标签,type属性表示采用何种连接词方式。
type属性的取值:
POOLED 采用传统的javax.sql.DataSource规范中的连接池,mybatis中有针对规范的实现。MyBatis会创建PooledDataSource实例。
可以看一下PooledDataSource类源码。
UNPOOLED 采用传统的获取连接的方式,虽然也实现Javax.sql.DataSource接口,但是并没有使用池的思想。MyBatis会创建UnpooledDataSource实例。
低层实际就是和原来的jdbc类似。
JNDI 采用服务器提供的JNDI技术实现,来获取DataSource对象,不同的服务器所能拿到DataSource是不一样。MyBatis会从JNDI服务上查找DataSource实例,然后返回使用。
注意:如果不是web或者maven的war工程,是不能使用的。
如我们课程中使用的是tomcat服务器,采用连接池就是dbcp连接池。
1.2.2 Mybatis中DataSource存取(了解)
MyBatis是通过工厂模式来创建数据源DataSource对象的,定义了DataSourceFactory抽象工厂,在存放到Configuration对象内的Environment对象中。
以后看源码在分析...等待补充...
1.2.3 Mybatis获取连接过程分析
当我们需要创建SqlSession对象并需要执行SQL语句时,这时候MyBatis才会去调用dataSource对象来创建java.sql.Connection对象。
以后看源码在分析...等待补充...
2.事务控制
2.0 概念
什么是事务?
事务的四大特性ACID?
不考虑隔离性的问题?
隔离级别?
2.1 JDBC中的事务控制
JDBC中setAutoCommit()方法将事务设置为手动提交。
Mybatis归根结底也是通过这个方法来设置的。
2.2Mybatis中事务
session = factory.openSession(true);//表示不进行手动提交
session = factory.openSession();//表示进行手动提交 即要session.commit()
2. 动态sql语句
2.1 标签
<select id="findByUser" resultType="user" parameterType="user">
select * from user where 1=1
<if test="username!=null and username != '' ">
and username like #{username}
</if>
</selecy>
<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
2.2 标签
<select id="findUserByCondition" resultMap="userMap" parameterType="user">
select * from user
<where>
<if test="userName != null">
and username = #{userName}
</if>
<if test="userSex != null">
and sex = #{userSex}
</if>
</where>
</select>
与上面不同的是少了where 1=1
2.3 标签
传入多个id时:
SELECT * FROM USERS WHERE username LIKE '%张%' AND id IN (10,89,16)
此时,如何将一个集合的值添加进去?
<!-- 根据queryvo中的Id集合实现查询用户列表 -->
<select id="findUserInIds" resultMap="userMap" parameterType="queryvo">
select * from user
<where>
<if test="ids != null and ids.size()>0">
<foreach collection="ids" open="and id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
SQL语句:select 字段 from user where id in (?)
<foreach>标签用于遍历集合,它的属性
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符
3.简化Sql的标签
3.1 自定义代码片段
<sql id="selectUser">
select * from user
</sql>
3.2 引用代码片段
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
4.Mybatis多表查询
4.1 一对一
方式1:
定义专门的bean类作为输出类型,其中定义了sql查询结果集所有的字段。此方法较为简单,企业中使用普遍。
如:一个账号信息Account在一张表,用户信息User在另一张表,要查询每个账号及其对应的用户信息,就可以定义一个类,继承于账号,在定义用户信息的属性。
方式2:
使用ResultMap建立对应关系。
在Account类中加入User对象。
association标签。
<!-- 定义封装account和user的resultMap -->
<resultMap id="accountUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!-- 一对一的关系映射:配置封装user的内容-->
<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>
4.2 一对多
如:查询所有用户信息及用户关联的账户信息
此时User类加入一个List<Account>。
对应的封装:用到collection标签
表示关联查询结果集
property="accList" :关联查询的结果集存储在User对象的上哪个属性。
ofType="account" :指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
<!-- 定义User的resultMap-->
<resultMap id="userMap" 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 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型 -->
<collection property="roles" ofType="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
</collection>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="userMap">
select u.*,r.id as rid,r.role_name,r.role_desc from user u
left outer join user_role ur on u.id = ur.uid
left outer join role r on r.id = ur.rid
</select>

浙公网安备 33010602011771号