乐趣区

关于mybatis:SSM基础篇三MyBatis

MyBatis

  • MyBatis 本是 apache 的一个开源我的项目 iBatis,2010 年这个我的项目由 apache software foundation 迁徙到了 google code,并且改名为 MyBatis。2013 年 11 月迁徙到 Github。
  • MyBatis 是一个优良的长久层框架,它对 jdbc 的操作数据库的过程进行封装,使开发者只须要关注 SQL 自身,而不须要破费精力去解决例如注册驱动、创立 connection、创立 statement、手动设置参数、后果集检索等 jdbc 繁冗的过程代码。
  • Mybatis 通过 xml 或注解的形式将要执行的各种 statement(statement、preparedStatemnt)配置起来,并通过 java 对象和 statement 中的 sql 进行映射生成最终执行的 sql 语句,最初由 mybatis 框架执行 sql 并将后果映射成 java 对象并返回。
  • 总之,Mybatis 对 JDBC 拜访数据库的过程进行了封装,简化了 JDBC 代码,解决 JDBC 将后果集封装为 Java 对象的麻烦。


(1)mybatis-config.xml 是 Mybatis 的外围配置文件,通过其中的配置能够生成 SqlSessionFactory, 也就是 SqlSession 工厂
(2) 基于 SqlSessionFactory 能够生成 SqlSession 对象
(3)SqlSession 是一个能够发送 SQL 去执行,并返回后果,相似于 JDBC 中的 Connection 对象,也是 Mybatis 中至关重要的一个对象。
(4)Executor 是 SqlSession 底层的对象,用于执行 SQL 语句
(5)MapperStatement 对象也是 SqlSession 底层的对象,用于接管输出映射(SQL 语句中的参数),以及做输入映射(行将 SQL 查问的后果映射成相应的后果)

MyBatis 劣势比照

1、应用传统形式 JDBC 拜访数据库:

  • 应用 JDBC 拜访数据库有大量反复代码(比方注册驱动、获取连贯、获取传输器、开释资源等);
  • JDBC 本身没有连接池,会频繁的创立连贯和敞开连贯,效率低;
  • SQL 是写死在程序中,一旦批改 SQL,须要对类从新编译;
  • 对查问 SQL 执行后返回的 ResultSet 对象,须要手动解决,有时会特地麻烦;

2、应用 mybatis 框架拜访数据库:

  • Mybatis 对 JDBC 对了封装,能够简化 JDBC 代码;
  • Mybatis 本身反对连接池(也能够配置其余的连接池),因而能够进步程序的效率;
  • Mybatis 是将 SQL 配置在 mapper 文件中,批改 SQL 只是批改配置文件,类不须要从新编译。
  • 对查问 SQL 执行后返回的 ResultSet 对象,Mybatis 会帮咱们解决,转换成 Java 对象。

mybatis-config.xml

MyBatis 的全局配置文件,配置连贯的数据库并导入 Mapper 配置文件

<?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">
<!-- MyBatis 的全局配置文件 -->
<configuration>
    <!-- 1. 配置环境,可配置多个环境(比方:develop 开发、test 测试)-->
    <environments default="develop">
        <environment id="develop">
            <!-- 1.1. 配置事务管理形式:JDBC/MANAGED JDBC:将事务交给 JDBC 治理(举荐)MANAGED:本人治理事务 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 1.2. 配置数据源,即连接池 JNDI/POOLED/UNPOOLED JNDI:已过期 POOLED:应用连接池(举荐)UNPOOLED:不应用连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    <!-- 2. 导入 Mapper 配置文件,如果 mapper 文件有多个,能够通过多个 mapper 标签导入 -->
    <mappers>
        <mapper resource="EmpMapper.xml" />
    </mappers>
</configuration>

映射关系

实体类 Emp

package com.tedu.pojo;

public class Emp {
    // 1. 申明实体类中的属性
    private Integer id;
    private String name;
    private String job;
    private Double salary;

    // 2. 提供对应的 getter 和 setter 办法
    public Integer getId() {return id;}

    public void setId(Integer id) {this.id = id;}

    public String getName() {return name;}

    public void setName(String name) {this.name = name;}

    public String getJob() {return job;}

    public void setJob(String job) {this.job = job;}

    public Double getSalary() {return salary;}

    public void setSalary(Double salary) {this.salary = salary;}

    // 3. 重写 toString 办法
    @Override
    public String toString() {return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
    }

}

接口 EmpMapper

package com.tedu.dao;

import com.tedu.pojo.Emp;
public interface EmpMapper {

    /**
    * 依据 id 查问员工信息
    * @param id
    * @return Emp
    */
    public Emp findById(Integer id);

}

映射文件 EmpMapper.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 值应该保障惟一 在程序中通过 [namespace + id] 定位到要执行哪一条 SQL 语句 -->
<mapper namespace="com.tedu.dao.EmpMapper">
    <!-- 通过 select、insert、update、delete 标签申明要执行的 SQL -->
    <!-- 1. 查问:查问 Emp 表中指定 id 的员工信息 -->
    <select id="findById" resultType="com.tedu.pojo.Emp">
        select * from emp where id=#{id}
    </select>
</mapper>

映射文件标签阐明

  • 后面是 xml 的文档申明,用于申明 xml 的版本和编码,引入了 xml 束缚文档,以后 xml 文档将会依照 mybatis-3-mapper.dtd 文件所要求的规定进行书写。
  • Mapper 标签:根标签,其中 namespace(名称空间,也叫命名空间),要求不能反复。在程序中通过【namespace + id】定位到要执行哪一条 SQL 语句
  • select 标签:用于指定未来要执行的各种 SQL 语句。标签上能够申明属性,上面介绍罕用的属性:id、resultType、resultMap

id 属性:要求值不能反复。未来在执行 SQL 时,能够通过【namespace +id】找到指定 SQL 并执行。
resultType 属性:从这条 SQL 语句中返回所冀望类型的类的齐全限定名称(包名 + 类名)。留神如果是汇合情景,那应该是汇合能够蕴含的类型,而不能是汇合自身。简而言之,resultType 管制查问 SQL 执行后返回值的类型或汇合中的泛型,
例如查问 emp 表中的单条记录,返回值是一个 Emp 对象,因而,resultType=”com.tedu.pojo.Emp”;
如果查问 emp 表中的多条记录,返回值是一个 List,此时 resultType 的值应该汇合中的泛型,因而 resultType=”com.tedu.pojo.Emp”;
resultMap 属性:简单对象构造(例如多表关联查问等)。应用 resultType 或 resultMap,但不能同时应用。

MyBatis 增删改查

编辑 EmpMapper.xml 文件, 增加新增员工对应的 sql.
<insert id="insert" >
    insert into emp value(null, '赵云', '保安', 6000)
</insert>
编辑 EmpMapper.xml 文件, 增加批改员工对应的 sql。
<update id="update">
    update emp set job='保镖', salary=20000 where name='赵云'
</update>
编辑 EmpMapper.xml 文件, 增加删除员工对应的 sql。
<delete id="delete">
    delete from emp where name='赵云'
</delete>
编辑 EmpMapper.xml 文件, 增加查问员工对应的 sql。
<select id="select">
    select * from emp 
</select>

mybatis 中的占位符

在下面的增删改查操作中,SQL 语句中的值是写死在 SQL 语句中的,而在理论开发中,此处的值往往是用户提交过去的值,因而这里咱们须要将 SQL 中写死的值替换为占位符。
在 mybatis 中占位符有两个,别离是 #{} 占位符 和 ${} 占位符:

#{}占位符

相当于 JDBC 中的问号(?)占位符,是为 SQL 语句中的参数值进行占
位,大部分状况下都是应用 #{}占位符;并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行本义解决(在字符串或日期类型的值的两边加上单引号);

在 mapper 文件中:select * from emp where name=#{name}
在程序执行时:select * from emp where name=?
参数:王海涛,将参数传入,替换占位符
select * from emp where name= 王海涛; -- 谬误
select * from emp where name='王海涛'; -- 正确

${}占位符

是为 SQL 片段(字符串)进行占位,将传过来的 SQL 片段间接拼接在
${} 占位符所在的地位,不会进行任何的本义解决。(因为是间接将参数拼接在 SQL 语句中,因而可能会引发 SQL 注入攻打问题)

动静 SQL 标签

if、where 标签

  • <if> 标签:是依据 test 属性 中的布尔表达式的值,从而决定是否执行蕴含在其中的 SQL 片段。如果判断后果为 true,则执行其中的 SQL 片段;如果后果为 false,则不执行其中的 SQL 片段
  • <where> 标签:用于对蕴含在其中的 SQL 片段进行检索,在须要时能够生成 where 关键字,并且在须要时会剔除多余的连接词(比方 and 或者 or)
<!--
* 如果没有参数, 则不执行 where 子句, 默认查问所有员工:* select * from emp
*
如果参数中只有 minSal(即 minSal 不为 null), 则:* ... where salary > minSal
*
如果参数中只有 maxSal(即 maxSal 不为 null), 则:* ... where salary < maxSal
* 如果参数有
minSal、maxSal(即 minSal、maxSal 不为 null), 则:* ... where salary > minSal and
salary < maxSal 
-->
<select id="findAllBySal2" resultType="com.tedu.pojo.Emp">
    select * from emp
    <where>
        <if test="minSal != null">
            and salary>#{minSal}
        </if>
        <if test="maxSal != null">
            and salary <![CDATA[ <]]>
            #{maxSal}
        </if>
    </where>
</select>

foreach 标签

  • foreach 标签:能够对传过来的参数数组或汇合进行遍历,以下是 foreach 标签上的各个属性介绍:
<!-- 练习: 依据员工的 id 批量更新员工信息 将 id 为 2、4、6、8 的员工的薪资在原有根底上减少 1000 update emp set 
    salary=salary + 1000 where id in(2,4,6,8); -->
<update id="updateByIds">
    update emp set salary=salary + #{sal}
    where id in
    <foreach collection="arrIds" open="(" item="id" separator=","
        close=")">
        #{id}
    </foreach>
</update>
退出移动版