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>

5.JNDI(了解)

posted @ 2020-02-10 21:13  sweetbetter  阅读(274)  评论(0)    收藏  举报