Mybatis常用知识点简介

入门

利用maven构建项目,需要引入相应的mybatis依赖。

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

Mybatis主要是一个持久层框架,持久层的主要工作就是对数据进行增删改查等操作。对数据库的任何操作之前都需要拿到一个与数据库的会话。Mybatis应用总主要是利用sqlSessionFactory这个类为核心,为每次操作创建需要的sqlSession会话。在Mybatis的官方文档中有说明:

  SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
  从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

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>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

其中的<configuration>标签在Mybatis框架中有一个对应的类,该类中还有environment属性(就是上面<environment>标签对应的类),environment标签中还有配置数据源的标签<dataSource>和配置事务管理的标签<transactionManager>,就是框架的数据库数据源。mappers 元素则包含了一组映射器(mapper),这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。

XML映射文件BlogMapper.xml如下:

<?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="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Board">
    select * from Blog where id = #{id}
  </select>
</mapper>

在准备一下实体类与实体对应的表和字段就可以运行了,代码如下:

import com.mybatis.po.Board;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class mybatis01 {

    public static void main(String[] args) throws IOException {

        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Board board = (Board) sqlSession.selectOne("org.mybatis.example.BlogMapper.selectBlog", 7);
        System.out.println(board);

    }
}

映射器

  映射器包括映射器接口和映射文件,一般情况下接口的全路径就是映射文件的namespace属性值,接口中定义的方法,方法名与映射文件中<insert>、<select>、<delete>、<update>等元素的id属性值相同。
  在核心配置文件中的<mapper>标签是配置映射器的,也就是找到相应的SQL映射语句,这些映射语句就是我们要mybatis框架执行的SQL语句。我们一般会将对某个表进行操作的sql语句(select,delete,update和insert等)都放同一个映射文件中。如何找到映射文件,mybatis提供了一下四种方式:

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

参数

mysql中写参数有两种方式:

  • #{param}:这种参数会采用预编译的方式,先用占位符替换替换参数(可防止sql注入),在实际执行时再将解析后的参数替换掉占位符。这种参数的书写方式只能写在SQL语句中的WHERE关键字后面。
  • ${param}:这种参数方式是直接赋值的,不会预编译用占位符替换(可能出现sql注入的情况)。这种参数方式不一定要放在SQL语句中的WHERE关键字后面才能执行。这种方式可以用来查询不同条件下查询不同表的数据。如:SELECT * FROM ${tableName}。根据上次调用传入参数不同查询不同的数据表。

动态SQL标签

  • <if test = "boardName != null and boardName != ’ ’ ">:判断传入属性的是否满足条件,为真则执行|标签对内的语句。
  • <choose>, <when test = "boardName != null and boardName != ’ ’ ">,<otherwise>标签,用于多判断分支的情况。逻辑类似Java中的switch(case和default)关键字的语法。
<choose>
    <when test = "boardName != null and boardName != ''">
        select id,name from table where boardName = #{boardName}
    </when>
    <when test = "boardNo != null and boardNo != 0">
        select id,name from table where boardId = #{boardId}
    </when>
    <otherwise>
        select id,name from table
    </otherwise>
</choose>
  • <where>标签:可以自动的将第一个满足条件的语句前面的逻辑运算符(or ,and)去掉。
select deptno,dname,loc from dept
<where>
    <if test = "deptNo != null and deptNo != 0">
        or deptNo = #{deptNo}
    </if>
    <if test = "dname != null and dname != ''">
        and dname like '%' #{dname} '%'
    </if>    
</where>
  • <set>标签:在update语句中会使用这个标签。<set>标签会自动将最后一个满足更新条件的字段后面的逗号“,”去掉。若 dname属性满足条件,而loc属性条件不满足,则会被解析成:update dept dname = #{dname} where deptno = #{deptNo}
         update dept
          <set>
              <if test="dname!=null and dname!=''">
                    dname = #{dname},
              </if>
              <if test="loc!=null and loc!=''">
                    loc = #{loc}
              </if>
          </set>
          where  deptno = #{deptNo}
  • <trim>标签:自定义第一个满足条件前部的代替内容,还可以自定义最后一个满足条件后面的代替内容。
  • <foreach>标签:foreach标签用于对集合内容进行遍历,将得到内容作为SQL语句的一部分.在实际开发过程中主要用于in语句的构建和批量添加操作。
      foreach元素的属性主要有 item,index,collection,open,separator,close。
    collection:表示传进来的集合类型。可以是:List,Set,Map和Array等集合。一般我们在传入map集合时,collection会这样写: collection=“myMap.values” 取map集合的value值,collection=“myMap.keys” 取map集合的key值。myMap的变量名和dao层传入的map类型的变量名相同。
    item:表示集合中每个元素进行迭代的别名。
    index:集合迭代时的索引。
    open:可以指定集合遍历后得到的SQL语句是以什么字符开头的
    close:可以指定集合遍历后得到的SQL语句是以什么字符结尾的。
    separator:每个迭代过的元素之间的分隔符。最后一个元素后面不会加上分隔符。
<insert id = "insertDept">
    insert into dept(dname,loc)
    values
    <foreach collection="list" item="dept" separator=",">
        (#{dept.dname},#{dept.loc})
    </foreach>
</insert>

--------------------------------------------------
// 传入的list集合如下:
Dept dept = new Dept();
dept.setdName("研发部");
dept.setLoc("杭州");
Dept dept2 = new Dept();
dept2.setdName("算法部");
dept2.setLoc("杭州");
List<Dept> deptList = new ArrayList<>();
deptList.add(dept);
deptList.add(dept2);
deptDao.insertDept(deptList);

------------------------------------
// 那么foreach标签拼装后的sql如下
insert into dept(dname,loc) values (?,?), (?,?)


// 插入后的查询语句
<select id = "findDept">
    select dname,loc,deptno from dept
    where deptno in
    <foreach collection="array" item="deptno" open="(" separator="," close=")">
        #{deptno}
    </foreach>
</select>
-----------------------------------------------------
// 拼装后的sql如下,其中 "(" 是open属性指定的开始符号,")"是close属性指定的结束符号,占位符之间的逗号","就是separator属性指定的
select dname,loc,deptno from dept where deptno in (?,?)

Mybatis级联操作

  在实际开发中,我们操作的表往往不是一个独立个体.它们往往根据业务依赖关系,形成一对一,一对多,多对多关联关系.为了保证业务数据的完整性.我们在操作某一张表的时候也要对与这张表关联其它表进行操作.这样的操作就成为级联操作。

  • 一对多的查询
<resultMap id="deptMap" type="dept">
        <id column="dept_deptno" property="deptNo" />
        <result column="dname" property="dname" />
        <result column="loc" property="loc" />
        <!-- collection集合标签中的column属性应该填写select返回字段中来自于一方表的主键对应的字段名 -->
        <collection property="empList" ofType="employee" column="dept_deptno">
            <id column="empno" property="empNo"></id>
        </collection>
    </resultMap>
    
    <!-- 查询当前部门下所有职员信息及当前部门的基本信息 -->
    <select id="deptFindById" resultMap="deptMap">
        select d.deptno as dept_deptno, d.dname, d.loc,
               e.empno, e.ename, e.job, e.sal
          from dept d
          left join emp e
            on d.deptno = e.deptno
         where d.deptno = #{deptno}
    </select>

上述映射文件中对应的dept实体类如下(employee类省略):

public class Dept {
       private Integer deptNo;
       private String dname;
       private String loc;
       private List<Employee> empList;

       // setter和getter方法省略 
}

  • 多对一的查询
<resultMap id="empMap" type="employee">
        <id column="empno" property="empNo"></id>
        <result column="ename" property="ename" />
        <result column="job" property="job" />
        <result column="sal" property="sal" />
        <!-- association用来表示关联的实体 -->
        <association property="dept" javaType="Dept">
            <result column="dept_deptno" property="deptNo" />
            <result column="dname" property="dname" />
            <result column="loc" property="loc" />
        </association>
    </resultMap>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值