Mybatis

简介

  1. 概述:Mybatis是一个持久层框架,它封装了JDBC操作的细节,使用了ORM思想实现了结果集的封装
  2. ORM:Object Relational Mappging(对象关系映射)
    • 就是把数据库表和实体类及实体类属性对应起来,使得我们操作实体类时就可以操作数据库表

三层架构

  1. API接口层
    • 提供给调用的接口API,开发人员通过本地API来操纵数据库。接口层接收到调用请求,会调用数据处理层来完成具体的数据处理
  2. 数据处理层
    • 负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作
  3. 基础支撑层
    • 负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑

使用

  1. **Mybatis**,下载导入jar包

  2. **MySql Connector**,导如MySql的JDBC的jar包

  3. 创建mybatis-config.xml文件,配置头

    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
  4. 创建数据库实体类和映射文件,配置头

    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. 通过SqlSessionFactoryBuilder创建Factory

    1
    2
    3
    4
    5
    6
    7
    8
    public class Demo1{
    public static void main(String[] args) {
    '加载mybatis的配置文件(映射)'
    InputStream in = Demo1.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
    '构建sqlSession的工厂'
    SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(in);
    }
    }

mybatis-config配置

  1. configuration标签,主标签,所有的配置信息都要写在configuration中

  2. properties标签:引入外部链接信息配置资源文件

    1
    <properties resource="jdbc.properties"></properties>
  3. settings标签:全局配置的属性

    1
    2
    3
    <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  4. typeAliases标签:为实体类起别名,避免写过长的名字

    1
    2
    3
    4
    5
    6
    7
    <typeAliases>
    '为io.jtxyh.entity.Sysuser这个类起个名字叫 sysuser'
    <typeAlias type="io.jtxyh.entity.Sysuser" alias="sysuser"/>

    '遍历io.jtxyh.entity下所有的实体类,起别名,别名为小写字母开头的类名'
    <package name="io.jtxyh.entity"/>
    </typeAliases>
  5. 环境配置,依次顺序

    • environments标签
    • environment标签
    • transactionManager标签
    • dataSource标签:元素使用基本的JDBC数据源接口来配置JDBC连接对象的资源,有三种内建的数据源类型
      1. UNPOOLED 每次创建新的连接
      2. POOLED 创建连接池,用完归还
      3. JNDI 获取JNDI连接池
    • property标签
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    'default后的名字和environment的id保持一致'
    <environments default="dev"> <!--默认运行环境ID-->
    <environment id="dev"> <!--运行环境ID,可以配置多个-->
    '设置事务管理机制为JDBC'
    <transactionManager type="JDBC"></transactionManager>
    '设置数据源:POOLED'
    * 使用mybatis内置的数据库连接池
    <dataSource type="POOLED">
    '配置数据库连接'
    <property name="driver" value="com.mysql.jdbc.Driver" />
    <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis" />
    <property name="username" value="root" />
    <property name="password" value="root" />
    </dataSource>
    </environment>

    <environment id="dev2">
    ....
    </environment>

    </environments>
  6. mappers标签:sql映射语句一般定义在各持久类的Mapper.xml文件中,需要在配置中引用这些映射文件

    1
    2
    3
    <mappers>
    <mapper resource="io/jtxyh/dao/user-mapper.xml"/>
    </mappers>

mybatis-mapper配置

mapper元素:后面的sql操作标签都必须配置在mapper标签中

  1. select标签
    • id属性,类似dao中的方法名
    • parameterType属性,类似dao中的形参类型
    • resultType属性,类似dao中的返回值类型
  2. insert标签,update标签,delete标签
    • id属性,类似dao中的方法名
    • 无返回值
    • 没有returnType属性
    • insert标签对于自增id,可以useGeneratedKeys=”true” keyProperty=”类的属性名”来获取新增记录id
  3. sql标签:公共代码块,一般用来写数据库字段。在select中通过include标签引用sql标签id
  4. resultMap标签:结果集映射,用来对实体类的属性与数据库的字段名做一一映射
    • type属性:写返回的结果集
    • id属性:定义一个id名字用于在select标签resultMap属性中调用
  5. 写在resultMap标签内的标签:有通用属性property和column,property写属性名,column写数据库字段名
    • id标签:用来确定数据库中的主键列
    • result标签:用来确定数据库中其他字段
    • association标签:**持有关系查询(多对1,1对1)**时使用
      1. 在标签上写column=字段名 property=属性名 javaType=属性的类型 select=二次查询的位置
      2. 在标签上写column=字段名 property=属性名 javaType=属性的类型,在标签中写id属性和result属性,通过sql语句进行多表查询
    • collection标签:**聚合关系查询(多对多,1对多)**时使用
      1. 在标签上写column=字段名,property=属性名,ofType=集合的泛型类型,select=二次查询的位置
      2. 在标签上写column=字段名,property=属性名,ofType=集合的泛型类型,在标签中写id属性和result属性,通过sql语句进行多表查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<mapper namespace="io.jtxyh.dao.UserInfoDao">

<resultMap type="Uinfo" id="selectUinfoAndCinfo">
<id property="uid" column="uid" />
<result property="uname" column="uname" />
<result property="cid" column="cid" />
<association property="cIf" column="cid" javaType="Cinfo"
select="io.jtxyh.dao.CinfoDao.selectCinfoByCid">
</association>

<association property="cIf" column="cid" javaType="Cinfo">
<id property="pid" column="pid" />
<result property="pname" column="pname" />
</association>

--------------------------------------------------------------

<collection property="minfoList" column="mid" ofType="Minfo" select="io.jtxyh.dao.MinfoDao.selectMinfoByMid">
</collection>

<collection property="minfoList" column="mid" ofType="Minfo">
<id property="pid" column="pid" />
<result property="pname" column="pname" />
</collection>
</resultMap>

<sql id="mySql">cmid,cid,mid</sql>

<!-- 第一个需要的参数使用的是mybatis已经设置好的别名 -->
<!-- 第二个结果集对象写的是别名,因为在mybatis-config中配置了typeAliases标签,里面配置了别名
全名应该是io.jtxyh.entity.UserInfo
-->
<!-- 实现模糊查询,使用百分号的时候必须加上双引号 -->
<select id="getLikeUserInfo" parameterType="string" resultType="userInfo">
select * from userinfo where upass like "%"#{upass}"%"
</select>

<insert id="addUserInfo">
insert into uinfo values(#{uid},#{uname},#{cid})
</insert>

<delete id="deleteUserInfo">
delete from uinfo where uid=#{uid}
</delete>

<update id="updateUserById" parameterType="Sysuser">
update uinfo set uname=#{uname} where uid=#{uid}
</update>

</mapper>

动态SQL

  1. 使用where,if实现条件查询:自动判断添加where和and

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <select id="selectCondition" resultMap="selectCon">
    select cid,cname from cinfo
    <where>
    <!-- test中写条件 -->
    <if test="cid != null">
    and cid=#{cid}
    </if>
    <if test="cname != null">
    and cname=#{cname}
    </if>
    </where>
    </select>
  2. 使用choose,when,otherwise实现判断选择单条件查询

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
       <select id="selectOneCondition" resultMap="selectCon">
    select cid,cname from cinfo
    <where>
    只要一个when匹配上就不判断后面的when,
    全部没有匹配上就匹配otherwise里的
    <choose>
    test中写条件
    <when test="cid != null">
    cid=#{cid}
    </when>
    <when test="cname != null">
    cname=#{cname}
    </when>
    <!-- 上述条件都不满足执行otherwise -->
    <otherwise>
    1=1
    </otherwise>
    </choose>
    </where>
    </select>
  3. 使用set,if实现条件更新:动态删除最后一个逗号

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
       <update id="updateCondition">
    update cinfo
    <set>
    <if test="cname != null">
    cname=#{cname},
    </if>
    <if test="cpass != null">
    cpass=#{cpass},
    </if>
    </set>
    where cid=#{cid}
    </update>
  4. 使用foreach批量添加/删除数据

    • collection属性:填list/array/自定义的list/array属性的别名
    • item属性:填写自定义临时的循环变量的名字
    • separator属性:用什么来分割多个变量
    • open属性:以什么开始
    • close属性:以什么结束
    • index属性:遍历的索引
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
       批量添加数据
    <insert id="insertQuery">
    insert into cinfo (cid,cname) values
    <foreach collection="cin" item="c" separator=",">
    (#{c.cid},#{c.cname})
    </foreach>
    </insert>
    批量删除数据
    <delete id="deleteQuery">
    delete from cinfo where cid in
    <foreach collection="cidList" item="cid" open="(" close=")"
    separator=",">
    #{cid}
    </foreach>
    </delete>

延迟加载

  • 当数据量比较大的时候,预先仅加载一部分数据返回用户,加快操作响应速度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    在mybatis-config.xml中配置这些
    <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
    启用延迟加载
    <setting name="lazyLoadingEnabled" value="true"/>
    积极加载改为消极加载
    <setting name="aggressiveLazyLoading" value="false"/>
    调用toString,equals不触发延迟对象的加载
    <setting name="lazyLoadTriggerMethods" value=""/>
    </settings>

缓存

  • 一级缓存:一级缓存是默认开启的,缓存存在于session中,每次关闭session或者使用增删改时清理缓存

  • 二级缓存:使用查询时,查询结果会存入对应的namespace中,使用增删改时清理缓存

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    在mybatis-config.xml中配置
    <settings>
    启用二级缓存
    <setting name="cacheEnabled" value="true"/>
    </settings>

    在mybatis-mapper.xml中配置
    <mapper namespace="io.jtxyh.dao.CinfoDao">
    配置缓存策略
    eviction=FIFO代表缓存方式为先进先出
    flushInterval=60000代表60秒中刷新一次缓存,
    size=512代表缓存为512个字节
    readOnly=true代表缓存为只读
    <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"></cache>
    </mapper>

相关文章

数据库连接池

SpringIOC

Junit和Spring

SpringAOP

Tomcat

Servlet

Request,Response和ServletContext

Cookie和Session

JSP和EL和Jstl

Filter和Listener