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 configurationPUBLIC "-//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 mapperPUBLIC "-//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 andsalary < 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>