乐趣区

关于java:Java-持久层框架-MyBatis

MyBatis 简介

MyBatis 是一个基于 Java 的长久层框架,它外部封装了 JDBC,使开发者只需关注 SQL 语句自身,而不必再破费精力去解决诸如注册驱动、创立 Connection、配置 Statement 等繁冗过程。

Mybatis 通过 xml 或注解的形式将要执行的各种 StatementPreparedStatement 等配置起来,并通过 Java 对象和 StatementSQL 的动静参数进行映射生成最终执行的 SQL 语句,最初由 MyBatis 框架执行 SQL 并将后果映射成 Java 对象并返回。

MyBatis 与 Hibernate

Hibernate 框架是提供了全面的数据库封装机制的 全自动 ORM,即实现了 POJO 和数据库表之间的映射,以及 SQL 的主动生成和执行。

绝对于此,MyBatis 只能算作是 半自动 ORM。其着力点,是在 POJO 类与 SQL 语句之间的映射关系。也就是说,MyBatis 并不会为程序员主动生成 SQL 语句。具体的 SQL 须要程序员本人编写,而后通过 SQL 语句映射文件,将 SQL 所需的参数,以及返回的后果字段映射到指定 POJO。

MyBatis 特点

  • XML 文件中配置 SQL 语句,实现了 SQL 语句与代码的拆散,给程序的保护带来了很大便当。
  • 能够联合数据库本身的特点灵便管制 SQL 语句,因而可能实现比 Hibernate 等全自动 ORM 框架更高的查问效率,可能实现简单查问。

Spring 整合 Mybatis

引入依赖

pom.xml 引入 Mybatis 相干依赖。

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.8</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.3.17.RELEASE</version>
</dependency>

创立 Mybatis 配置文件

resource 目录下创立 mybatis-config 配置文件。

<?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>
    <!-- 全局参数 -->
    <settings>
        <!-- 打印 SQL 语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    
        <!-- 使全局的映射器启用或禁用缓存。-->
        <setting name="cacheEnabled" value="false"/>

        <!-- 全局启用或禁用提早加载。当禁用时,所有关联对象都会即时加载。-->
        <setting name="lazyLoadingEnabled" value="true"/>

        <!-- 当启用时,有提早加载属性的对象在被调用时将会齐全加载任意属性。否则,每种属性将会按须要加载。-->
        <setting name="aggressiveLazyLoading" value="true"/>

        <!-- 是否容许单条 SQL 返回多个数据集 (取决于驱动的兼容性) default:true -->
        <setting name="multipleResultSetsEnabled" value="true"/>

        <!-- 是否能够应用列的别名 (取决于驱动的兼容性) default:true -->
        <setting name="useColumnLabel" value="true"/>

        <!-- 容许 JDBC 生成主键。须要驱动器反对。如果设为了 true,这个设置将强制应用被生成的主键,有一些驱动器不兼容不过依然能够执行。default:false  -->
        <setting name="useGeneratedKeys" value="false"/>

        <!-- 指定 MyBatis 如何主动映射 数据基表的列 NONE:不映射 PARTIAL:局部 FULL: 全副  -->
        <setting name="autoMappingBehavior" value="PARTIAL"/>

        <!-- 这是默认的执行类型(SIMPLE: 简略;REUSE: 执行器可能重复使用 prepared statements 语句;BATCH: 执行器能够反复执行语句和批量更新)-->
        <setting name="defaultExecutorType" value="SIMPLE"/>

        <!-- 应用驼峰命名法转换字段。-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>

        <!-- 设置本地缓存范畴 session: 就会有数据的共享 statement: 语句范畴 (这样就不会有数据的共享) defalut:session -->
        <setting name="localCacheScope" value="SESSION"/>

        <!-- 设置 JDBC 类型为空时, 某些驱动程序 要指定值, default:OTHER,插入空值时不须要指定类型 -->
        <setting name="jdbcTypeForNull" value="NULL"/>
    </settings>
</configuration>

创立集成配置文件

resource 目录下创立一个 spring-context-mybatis.xml 的集成配置文件。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 配置 SqlSession -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- 用于配置对应实体类所在的包,多个 package 之间能够用 ',' 号宰割 -->
        <property name="typeAliasesPackage" value="com.antoniopeng.ssm.domain"/>
        <!-- 用于配置对象关系映射 -->
        <property name="mapperLocations" value="classpath:/mapper/**/*.xml"/>
                <!-- - 用于配置文件所在目录 ->
        <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
    </bean>

    <!-- 扫描 Mapper -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.antoniopeng.ssm.dao" />
    </bean>
</beans>

CRUD 案例

新增

<insert id="insert">
    INSERT INTO tb_user (
      id,
      username,
      password,
      phone,
      email,
      created,
      updated
    )
    VALUES
      (#{id},
        #{username},
        #{password},
        #{phone},
        #{email},
        #{created},
        #{update}
      )
</insert>

删除

<delete id="delete">
    DELETE FROM tb_user WHERE id = #{id}
</delete>

查问

<select id="getById" resultType="TbUser">
    SELECT
      a.id,
      a.username,
      a.password,
      a.phone,
      a.email,
      a.created,
      a.updated AS "update"
    FROM
      tb_user AS a
    WHERE
      a.id = #{id}
</select>

更新

<update id="update">
    UPDATE
      tb_user
    SET
      username = #{username},
      password = #{password},
      phone = #{phone},
      email = #{email},
      created = #{created},
      updated = #{update}
    WHERE id = #{id}
</update>

MyBatis 动静 SQL

动静 SQL 次要用于解决查问条件不确定的状况:在程序运行期间,依据用户提交的查问条件进行查问。提交的查问条件不同,执行的 SQL 语句不同。若将每种可能的状况均逐个列出,对所有条件进行排列组合,将会呈现大量的 SQL 语句。此时,可应用动静 SQL 来解决这样的问题。这里的条件判断应用的表达式为 OGNL 表达式。罕用的动静 SQL 标签有 <if><where><choose><foreach> 等。

留神:在 mapper 的动静 SQL 中若呈现 ><>=<= 等符号,最好将其转换为实体符号。否则,XML 可能会呈现解析出错问题,特地是 < 在 XML 中是相对不能呈现的。

if 标签

对于该标签的执行,当 test 的值为 true 时,会将其蕴含的 SQL 片断拼接到其所在的 SQL 语句中。
案例
为了解决两个条件均未做设定的状况,在 where 后增加了一个“1=1”的条件。这样就不至于两个条件均未设定而呈现只剩下一个 where,而没有任何可拼接的条件的不残缺 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="com.antoniopeng.ssm.dao.StudentDao">
    <!-- if -->
    <select id="selectByIf" resultType="com.antoniopeng.ssm.entity.Student">
        SELECT 
                    *
        FROM
            student
        WHERE 1 = 1
        <if test="name != null and name !=''">
            AND name LIKE concat('%', #{name}, '%')
        </if>
        <if test="age != null and age > 0">
            AND age > #{age}
        </if>
    </select>
</mapper>

where 标签

<if/> 标签的中存在一个比拟麻烦的中央:须要在 where 后手工增加 1=1 的子句。因为,若 where 后的所有 <if/> 条件均为 false,而 where 后若又没有 1=1 子句,则 SQL 中就会只剩下一个空的 where,SQL 出错。所以,在 where 后,须要增加永为真子句 1=1,以避免这种状况的产生。但当数据量很大时,会重大影响查问效率。
案例

<select id="selectByWhere" resultType="com.antoniopeng.ssm.entity.Student">
    SELECT
            *
    FROM
      student
    <where>
        <if test="name != null and name !=''">
            AND name LIKE concat('%', #{name}, '%')
        </if>
        <if test="age != null and age > 0">
            AND age > #{age}
        </if>
    </where>
</select>

choose 标签

该标签中只能够蕴含 <when/><otherwise/>,能够蕴含多个 <when/> 与一个 <otherwise/>。它们联结应用,实现 Java 中的开关语句 switch case 性能。
案例
本例要实现的需要是,若姓名不空,则依照姓名查问;若姓名为空,则依照年龄查问;若没有查问条件,则没有查问后果。

<!-- choose -->
<select id="selectByChoose" resultType="com.antoniopeng.ssm.entity.Student">
    SELECT
        *
    FROM
      student
    <where>
        <choose>
            <when test="name != null and name !=''">
                AND name LIKE concat('%', #{name}, '%')
            </when>
            <when test="age != null and age > 0">
                AND age > #{age}
            </when>
            <otherwise>
                AND 1 != 1
            </otherwise>
        </choose>
    </where>
</select>

foreach 标签

该标签用于实现对于数组与汇合的遍历。对其应用,须要留神:collection 示意要遍历的汇合类型,这里是数组,即 array。opencloseseparator 为对遍历内容的 SQL 拼接。
遍历数组案例

<!-- foreach -->
<select id="selectByForeach" resultType="com.antoniopeng.ssm.entity.Student">
    SELECT
        *
    FROM
      student
    <if test="array != null and array.length > 0">
        WHERE id IN
        <foreach collection="array" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </if>
</select>

遍历泛型为根本类型的汇合案例

/**
 * 应用 foreach 标签以 list 根本类型的模式查问
 * @param ids
 * @return
 */
public List<Student> selectByForeachWithListBase(List<Long> ids);
<!-- foreach -->
<select id="selectByForeachWithListBase" resultType="com.antoniopeng.ssm.entity.Student">
    SELECT
        *
    FROM
      student
    <if test="list != null and list.size > 0">
        WHERE id IN
        <foreach collection="list" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </if>
</select>

遍历泛型为自定义类型的汇合案例

/**
 * 应用 foreach 标签以 list 自定义类型的模式查问
 * @param students
 * @return
 */
public List<Student> selectByForeachWithListCustom(List<Student> students);
<!-- foreach -->
<select id="selectByForeachWithListCustom" resultType="com.antoniopeng.ssm.entity.Student">
    SELECT
            *
    FROM
      student
    <if test="list != null and list.size > 0">
        WHERE id IN
        <foreach collection="list" open="(" close=")" item="student" separator=",">
            #{student.id}
        </foreach>
    </if>
</select>

sql 标签

该标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签应用该 SQL 片断,须要应用 <include/> 子标签。该标签能够定义 SQL 语句中的任何局部,所以 <include/> 子标签能够放在动静 SQL 的任何地位。
案例

<sql id="select">
    SELECT
        id,
        name,
        age,
        score
    FROM
      student
</sql>

应用 sql 标签

<!-- foreach -->
<select id="selectByForeachWithListCustom" resultType="com.antoniopeng.ssm.entity.Student">
    <include refid="select" />
</select>
  • 文章作者:彭超
  • 原文链接:[]()
  • 版权申明:本博客所有文章除特地申明外,均采纳 CC BY-NC-SA 4.0 许可协定。转载请注明来自 彭超的博客!
退出移动版