Mybatis框架概述

目录

 简介

Mybatis环境搭建

1.创建一张表和表对应的实体类

2.导入MyBatis jar包,mysql 数据库驱动包

3.创建MyBatis全局配置文件 

4.创建sql映射文件

5. 定义接口

6.测试MyBatis

API接口说明

SqlSessionFactory 接口

SqlSession 接口

Mybatis-Dao 层 Mapper 接口化开发

Mapper接口开发条件

Mybatis 日志

参数传递

增删改查

增加

删除

修改

查询

嵌套查询  

 映射

对象映射

结果映射

多表关联处理结果集

Mybatis动态SQL

if

where

trim

Choose 元素

set元素

foreach元素

特殊符号处理

mybatis一级缓存二级缓存

为什么使用缓存?

一级缓存

二级缓存

 二级缓存配置


简介

        MyBatis 是一款优秀的持久层框架,免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

        Mybatis 将基本的JDBC常用接口封装,对外提供操作即可。中文官网:https://mybatis.org/mybatis-3/zh/getting-started.htmlicon-default.png?t=N7T8https://mybatis.org/mybatis-3/zh/getting-started.html

Mybatis环境搭建

1.创建一张表和表对应的实体类

2.导入MyBatis jar包,mysql 数据库驱动包

 <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.2</version>
 </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
   <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>8.0.16</version>
   </dependency>

3.创建MyBatis全局配置文件 

<?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">
<configuration>
  <properties resource="config.properties"></properties>
     <environments default="development">
         <environment id="development">
             <dataSource type="POOLED">
                 <property name="driver" value="" />
                 <property name="url" value="" />
                 <property name="username" value="" />
                 <property name="password" value=""/>
             </dataSource>
         </environment>
     </environments>
</configuration>

4.创建sql映射文件

<?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">

<mapper namespace="接口地址">

    定义sql语句

</mapper>

5. 定义接口

        在接口中定义方法

public interface AdminDao{

}

6.测试MyBatis

       (1) 读取配置文件

Reader reader = Resources.getResourceAsReader("mybatis-config.xml");

       (2)创建SqlSessionFactory

SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);

        (3)创建SqlSession

SqlSession sqlSession = sessionFactory.openSession();

        (4)获得接口代理对象

sqlSession.getMapper(接口.class);

sqlSession .close();关闭

API接口说明

SqlSessionFactory 接口

        使用SqlSessionFactory 来创建 SqlSession,一旦创建 SqlSessionFactory 就 会在整个应用过程中始终存在。

SqlSession 接口

        Sqlsession 意味着创建与数据库链接会话,该接口中封装了对数据库操作的方法,与数据库会话完成后关闭会话。

Mybatis-Dao 层 Mapper 接口化开发

        Mapper接口开发方式只需要我们编写Mapper接口,由Mybatis框架创建接口的动态代理对象,使用sqlsession.getMapper(接口.class),获得代理对象。

Mapper接口开发条件

(1)Mapper.xml文件中的namespace与mapper接口的类路径相同。

(2)Mapper接口方法名和Mapper.xml中定义的每个statement的id相同。

(3)Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的 parameterType 的类型相同。

(4)Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的 resultType 的类型相同。

Mybatis 日志

配置日志

<settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

参数传递

单个参数直接传递

Admin findAdminByid(int id);

<select id="findAdminByid" resultType="Admin" parameterType="int">
    select id,account,password,admin_gender from admin where id = #{id}
</select>

多个参数使用@Param(“id”)绑定

saveAdmin(@Param("acc") String account, @Param("pwd") String password);

<insert id="saveAdmin">
     insert into admin(account,password) values(#{acc},#{pwd})
</insert>

如果传入一个复杂的对象,就需要使用parameterType参数进行类型定义

void saveAdmin1(Admin admin);
<insert id="saveAdmin1" parameterType="Admin">
    insert into admin(account,password) values(#{account},#{password})
</insert>

增删改查

增加

<insert id="唯一标识" parameterType="参数类型" useGeneratedKeys="取出数据库中生成的主键" keyColumn="指定主键列id" keyProperty="指定主键对应的属性id">
       insert into admin(account,password) values(#{account},#{password})
</insert>

删除

<delete id="唯一标识" parameterType="参数类型">
     delete from admin where id= #{id}
 </delete>

修改

<update id="唯一标识" parameterType=“参数类型">
     update adminsetaccount= #{account},password= #{password} where id= #{id}
</update>

查询

<select id="唯一标识" resultType="返回结果集类型">
     select * from admin where id= #{id}
</select>

嵌套查询 

        将一个多表关联查询拆分为多次查询,先查询主表数据,然后查询关联表数据。

<resultMap id="studentmap" type="Student">
        <id column="id" property="id"></id>
        <result column="num" property="num"></result>
        <result column="name" property="name"></result>
        <result column="gender" property="gender"></result>

        <association property="dorm" javaType="Dorm" select="findDormByid" column="dormid"></association>
        
    </resultMap>

 <select id="findDormByid" parameterType="int" resultType="Dorm">
        select num from Dorm where id=#{id}
 </select>

column="dormid":关联查询时将 num 列的值传入findDormByid, 并将findDormByid 查询的结果映射到Student的dorm属性中。collection 和 association 都需要配置 select 和 column 属性,两者配置方法相同。

 映射

对象映射

        如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装到POJO对象中。

如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开始全局设置实现自动转换。

private String adminGender;
<setting name="mapUnderscoreToCamelCase" value="true"/>
<select id="findAdminByid" resultType="Admin" parameterType="int">
        select id,account,password,admin_gender from admin where id = #{id}
</select>

结果映射

定义resultMap

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

(1)resutlMap 的 id 属性是resutlMap的唯一标识(2)resutlMap 的 id 属性是映射的POJO类(3)id 标签映射主键,result标签映射非主键(4)property 设置 POJO 的属性名称,column映射查询结果的列名称

然后在引用它的语句中设置 resultMap 属性就行了(注意去掉了 resultType 属性) 

使用resultMap

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>

多表关联处理结果集

(1)宿舍一方,配置多方集合   宿舍有很多个学生

public class Dorm {
    private int id;
    private int num;
    private List<Student> students;
}

组装查询结果

<resultMap id="dormMap" type="Dorm">
        <id column="id" property="id"></id>
        <result column="num" property="num"></result>
            <!--封装学生集合-->
        <collection property="students" javaType="list" ofType="Student">
            <result column="name" property="name"></result>
            <result column="xuehao" property="num"></result>
        </collection>
</resultMap>
        <!--查询宿舍列表-->
    <select id="findDorms" resultMap="dormMap">
        SELECT d.id,d.num,s.name,s.num xuehao FROM dorm d
	            LEFT JOIN student s ON s.dormid = d.id
    </select>

(2)学生多方,在多方配置一方  学生有一个宿舍

public class Student {
    private int id;
    private int num;
    private String name;
    private String gender;
    private Dorm dorm;
}
 <resultMap id="studentmap" type="Student">

        <id column="id" property="id"></id>
        <result column="num" property="num"></result>
        <result column="name" property="name"></result>
        <result column="gender" property="gender"></result>

        <!--把学生关联的宿舍封装到宿舍对象中去,属于嵌套映射-->
        <association property="dorm" javaType="Dorm">
                <result column="dnum" property="num"></result>
        </association>

 </resultMap>

<select id="findStudentByid" resultMap="studentmap" parameterType="int">
             SELECT s.id,s.name,s.gender,s.num,d.num dnum FROM student s
	        LEFT JOIN dorm d ON s.dormid = d.id
	        WHERE s.id = #{ID}
</select>

 Mybatis三种自动映射等级

  • NONE - 禁用自动映射。即使是单张表
  • PARTIAL - 如果没有嵌套映射,会自动映射结果。如果使用了嵌套映射,所有的都不映射了。是mybatis默认的
  • FULL - 自动映射所有属性,无论是否开启嵌套映射。

Mybatis动态SQL

        动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。

if

<select id="findStudents" resultType="Student" parameterType="Student">
            select id,num,name,gender from student
              where  state = "active" 
                <if test="num!=0">
                   and num=#{num}
                </if>
                <if test="name!=null">
                    and name=#{name}
                </if>
</select> 

如果上面没有 state="active",后面num存在,语句就成为  where  and  错误

对于查询条件不确定 可以使用where

where

<select id="findStudents" resultType="Student" parameterType="Student">
            select id,num,name,gender from student
            <where>
                <if test="num!=0">
                    num=#{num}
                </if>
                <if test="name!=null">
                    and name=#{name}
                </if>
                <if test="gender!=null">
                    or gender = #{gender}
                </if>
            </where>
</select>

<where>元素会进行判断,如果它包含的标签中有返回值的话,它就插入一个 ‘where’。 此外,如果标签返回的内容是以AND 或OR 开头,它会剔除掉AND或OR。

trim

where 标签,其实用trim 也可以表示,当WHERE后紧随AND或则OR的 时候,就去除AND或者OR。prefix前缀,prefixOverrides覆盖首部指定内容。

<select id="findStudents" resultType="Student" parameterType="Student">
            select id,num,name,gender from student
         
       <trim prefix="where" prefixOverrides="and">
            <if test="num!=0">
                num=#{num}
            </if>
            <if test="name!=null">
                and name=#{name}
            </if>
            <if test="gender!=null">
                or gender = #{gender}
            </if>
        </trim>
</select>

Choose 元素

它有点像 Java 中的 switch 语句。

比如 传入了 “num” 就按 “num” 查找,传入了 “name” 就按 “name” 查找。若两者都没有传入,就选择gender="女"进行查询。

<select id="findStudents" resultType="Student" parameterType="Student">
            select id,num,name,gender from student
        <trim prefix="where" prefixOverrides="and">
            <choose>
                <when test="num!=0">
                    num=#{num}
                </when>
                <when test="name!=null">
                    and name=#{name}
                </when>
                <otherwise>
                    and gender = '女'
                </otherwise>
            </choose>
        </trim>
 </select>

set元素

set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。

<update id="updateStudent" parameterType="Student">
        update student
        <set>
            <if test="num!=0">
                num=#{num},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="gender!=null">
               gender = #{gender}
            </if>
        </set>
        where id = #{id}
 </update>

也可以使用trim实现,suffixOverrides覆盖尾部内容

<update id="updateStudent" parameterType="Student">
        update student
        <trim prefix="set" suffixOverrides=",">
            <if test="num!=0">
                num=#{num},
            </if>
            <if test="name!=null">
                name=#{name},
            </if>
            <if test="gender!=null">
                gender = #{gender},
            </if>
        </trim>
        where id = #{id}
 </update>

foreach元素

主要用在构建in条件中,它可以在SQL语句中对集合进行遍历。在使用foreach的时候最关键的就是collection属性,该属性是必须指定的。

item 表示集合中每一个元素进行迭代时的别名,index指定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始, separator 表示在每次进行迭代之间以什么符号作为分隔符,close表示以什么符号结束。

<delete id="deleteStudent">
            delete from student where id in
            <!--<foreach collection="array" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>-->
        <foreach collection="list" item="item" open="(" separator="," close=")">
            #{item}
        </foreach>
</delete>

特殊符号处理

在mybatis中的xml文件中,存在一些特殊的符号,比如:<、>、"、&、<> 等,正常书写mybatis会报错,需要对这些符号进行转义。具体转义如下所示:

特殊字符  转义字符
   <       &lt;
   >       &gt;
   "       &quot;
   ’       &apos;
   &       &amp;

 还可以使用  <![CDATA[]]> 来包裹特殊字符。

<if test="id != null">
     AND <![CDATA[ id <> #{id} ]]>
</if>

mybatis一级缓存二级缓存

为什么使用缓存?

        缓存(cache)的作用是为了减去数据库的压力,提高查询性能。缓存实现的原理 是从数据库中查询出来的对象在使用完后不要销毁,而是存储在内存(缓存)中, 当再次需要获取该对象时,直接从内存(缓存)中直接获取,不再向数据库执行 select 语句,从而减少了对数据库的查询次数,因此提高了数据库的性能。

一级缓存

        Mybatis 对缓存提供支持,默认开启一级缓存,一级缓存只是相对于同一个SqlSession而言。我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL,第一次查询后会将结果封装到SqlSession中,如果没有声明需要刷新,并且缓存没有超时的情况下,第二次执行相同的Sql语句查询, SqlSession 都会取出当前缓存的数据,而不会再次发送SQL到数据库。

清除方式:(1)SqlSession.close(); 关闭SqlSession对象 (2)SqlSession.clearCache();清理数据,对象仍可用。

(3)SqlSession 中执行了任何一个update操作(update()、delete()、 insert()) ,都会清空缓存的数据,但是该对象可以继续使用。

二级缓存

每次查询会先从缓存区域查找,如果找不到则从数据库查询,并将查询到数据写入缓存。

当第一次查询到数据后,关闭SqlSession时将数据存入到二级缓存中。

 二级缓存配置

(1)启用二级缓存

        在SqlMapperConfig.xml 中启用二级缓存,代码所下,当 cacheEnabled 设置为true时启用二级缓存,设置为false时禁用二级缓存。

        <setting name="cacheEnabled" value="true"/>

(2)对象序列化

        将所有的POJO类实现序列化接口Java.io.Serializable

 (3)配置映射文件

        在Mapper映射文件中添加

<cache flushInterval="时间"></cache>

表示此mapper开启二级缓存。当SqlSeesion 关闭时,会将数据存入到二级缓存。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值