MyBatis三

MyBatis三

Mybatis 的连接池技术

我们在前面的 WEB 课程中也学习过类似的连接池技术,而在 Mybatis 中也有连接池技术,但是它采用的是自己的连接池技术。在 Mybatis 的SqlMapConfig.xml 配置文件中,通过<dataSource type=”pooled”>来实现Mybatis中连接池的配置。

1. Mybatis 连接池的分类

Mybatis 将它自己的数据源分为三类:

  1. UNPOOLED 不使用连接池的数据源
  2. POOLED 使用连接池的数据源
  3. JNDI 使用 JNDI 实现的数据源

2. PooledDataSource 工作原理

tTfPf0.png

Mybatis 的事务控制

1. Mybatis 自动提交事务的设置

连接池中取出的连接,都会将调用connection.setAutoCommit(false)方法,这样我们就必须使用sqlSession.commit()方法,相当于使用了 JDBC中的connection.commit()方法实现事务提交。

因此可以这样取出连接session = factory.openSession(true);


Mybatis 的动态 SQL 语句

1. 动态 SQL 之< if>标签

例如:

<select id="findByUser" resultType="user" parameterType="user">
    select * from user where 1=1
    <if test="username!=null and username != '' ">
    and username like #{username}
    </if> 
    <if test="address != null">
    and address like #{address}
    </if>
</select>

2. 动态 SQL 之< where>标签

例如:

<select id="findByUser" resultType="user" parameterType="user">
    <include refid="defaultSql"></include> 
    <where> 
        <if test="username!=null and username != '' ">
        and username like #{username}
        </if> 
        <if test="address != null">
        and address like #{address}
        </if>
    </where>
</select>

3. 动态标签之< foreach>标签

QueryVo 中有一个 List 集合用于封装参数

配置文件例如:

<!-- 查询所有用户在 id 的集合之中 --> 
<select id="findInIds" resultType="user" parameterType="queryvo">
    <!-- select * from user where id in (1,2,3,4,5); --> 
    <include refid="defaultSql"></include> 
    <where> 
        <if test="ids != null and ids.size() > 0"> <foreach collection="ids" open="id in ( " close=")" item="uid" separator=",">
            #{uid}
        </foreach>
        </if>
    </where>
</select>
  • <foreach>标签用于遍历集合,它的属性:
  1. collection:代表要遍历的集合元素,注意编写时不要写#{}
  2. open:代表语句的开始部分
  3. close:代表结束部分
  4. item:代表遍历集合的每个元素,生成的变量名
  5. sperator:代表分隔符

Mybatis 多表查询之一对一(多对一)

方式一:

  • 定义一个实体类继承其中一方的实体类,然后属性增加另一实体类中的是属性作为属性。

  • 如:Account和User,定义一个AccountUser类继承Account类,然后将想要的User中的属性加入AccountUser中,比如添加username和address两个属性,从而可以完成一对一的查询,一个AccountUser中包含了一个Account对应的一个User。

  • 小结:定义专门的 po 类作为输出类型,其中定义了 sql 查询结果集所有的字段。此方法较为简单,企业中使用普遍。

方式二:

使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。
通过面向对象的(has a)关系可以得知,我们可以在 Account 类中加入一个 User 类的对象来代表这个账户是哪个用户的。

  • 在Account中增加一个User属性,用于表示这个Account属于哪个User。

  • 同时还要修改对应的映射配置文件,如下修改

    <!-- 建立对应关系 --> 
    <resultMap type="account" id="accountMap"> 
        <id column="aid" property="id"/>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!-- 它是用于指定从表方的引用实体属性的 --> 
        <association property="user" javaType="user"> 
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>

一对多查询

  • 需求:

    • 查询所有用户信息及用户关联的账户信息。
  • 分析:
    用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,我们想到了左外连接查询比较合适。

  • 可以在User类中增加一个Account是Set集合。

  • 映射文件配置:

    <resultMap type="user" id="userMap"> <id column="id" property="id">
        </id> <result column="username" property="username"/>
        <result column="address" property="address"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <!-- collection 是用于建立一对多中集合属性的对应关系
        ofType 用于指定集合元素的数据类型 --> 
    
        /* property="accList":关联查询的结果集存储在 User 对象的上哪个属性。
        ofType="account":指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名 */
    
        <collection property="accounts" ofType="account">
            <id column="aid" property="id"/>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
        </collection>
    </resultMap>
  • SQL语句:SELECT u.*, acc.id id, acc.uid, acc.money FROM user u LEFT JOIN account acc ON u.id = acc.uid


Mybatis 多表查询之多对多

  • 多对多关系其实我们看成是双向的一对多关系。

  • 拿用户与角色举例,一个用户可以有多个角色,一个角色又可以有多个用户。
    tTb2E8.png

  • 需求:

    • 实现查询所有对象并且加载它所分配的用户信息。
  • 分析:

    • 查询角色我们需要用到Role表,但角色分配的用户的信息我们并不能直接找到用户信息,而是要通过中间表(USER_ROLE 表)才能关联到用户信息。
  • SQL语句:

    SELECT
    r.*,u.id uid,
    u.username username,
    u.birthday birthday,
    u.sex sex,
    u.address address
    FROM 
    ROLE r
    INNER JOIN 
    USER_ROLE ur
    ON ( r.id = ur.rid)
    INNER JOIN
    USER u
    ON (ur.uid = u.id);
  1. 实现角色到用户的一对多

    • 在角色实体类中加入一个用户的Set集合
    • 编写dao接口
    • 配置映射文件
  2. 实现用户到角色的一对多

    • 在用户实体类中加入一个角色的Set集合
    • 编写dao接口
    • 配置映射文件
  3. 最终完成多对多查询。

打赏
  • 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!

请我喝杯咖啡吧~

支付宝
微信