Mybatis入门

104 阅读3分钟

MyBatis认识

Mybatis是一款orm(对象关系映射)框架,自己写sql,效率高,性能好控制

jdbc特点:

  • 执行效率高,自己写sql
  • 开发效率低,很多重复代码

jpa特点:

  • 开发效率高,直接调用api即可完成对应crud
  • 执行效率低:因为sql语句是自动生成的,性能不太好控制

Mybatis特点

  • 开发效率比jdbc高,因为消除了许多重复代码
  • 执行效率比jpa高,因为是自己写sql

Mybatis的三大核心对象

SqlSessionFactoryBuilder(SqlSession工厂构建对象):该对象主要用于创建SqlSessionFactory对象 SqlSessionFactory(SqlSession工厂对象):它是一个重量级对象,在当前应用系统中应该只有一个 (线程安全的

为什么说是一个重量级对象?

  • 内部存储了mybatis核心配置xml的基本信息
  • 内部有二级缓存
  • 内部存储了连接池对象

所以我们不能轻易销毁该对象,它的生命周期应该随着tomcat的启动而创建,tomcat关闭而销毁

SqlSession:他是一个轻量级对象,线程不安全的

  • 内部存储有连接对象
  • 存储一级缓存
  • 一个线程获取一个SqlSession,线程不安全的

Mybatis细节

mybatis-config.xml文件的配置顺序

configuration的子元素必须按照由上到下的顺序配置,否则MyBatis在解析XML配置文件的时候会报错

configuration 配置
    ---   properties 属性
    ---   settings 设置
    ---   typeAliases 类型别名
    ---   typeHandlers 类型处理器
    ---   objectFactory 对象工厂
    ---   plugins 插件
    ---   environments 环境
            ---   environment 环境变量
                    ---   transactionManager 事务管理器
                    ---   dataSource 数据源
    ---   databaseIdProvider 数据库厂商标识
    ---   mappers 映射器

引入jdbc.properties 配置数据库连接

数据库连接使用配置文件方式

jdbc.properties文件

username=root
password=123456
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///mybatis

Mybatis核心配置文件:mybatis-config.xml

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

    <!--引入jdbc.properties文件-->
    <properties resource="jdbc.properties"/>

   <!-- 配置连接数据库的环境-->
    <environments default="mysql">
        <!--给环境取一个别名-->
        <environment id="mysql">
            <!--配置事务类型:JDBC-->
            <transactionManager type="JDBC"/>
            <!--使用连接池对象-->
            <dataSource type="POOLED">
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

配置类型别名

在mybatis-config.xml里配置类型别名,之后再mapper.xml中直接使用别名

mybatis-config.xml:

<!--配置全限定名对应的别名-->
<typeAliases>
    <!--给Product全限定名取了一个别名-->
    <typeAlias type="cn.itsource.mybatis._01hello.domain.Product" alias="Product"/>
</typeAliases>

mapper.xml:


获取映射器

在mybatis-config.xml中配置映射器,在mapper.xml中namespace(命名空间)名必须和mapper层(dao层)对应的接口全限定名

mybatis-config.xml:

<!--配置sql映射文件-->
<mappers>
    <mapper resource="cn/itsource/mybatis/_01hello/dao/impl/ProductDaoImpl.xml"/>
    <mapper resource="cn/itsource/mybatis/_02mapper/mapper/EmployeeMapper.xml"/>
</mappers>

mapper.xml:

通过SqlSession对象的getMapper方法获取映射器对象

@Test
public void save() throws Exception {
    //获取SqlSession
    SqlSession sqlSession = MybatisUtils.openSession();
    //获取映射器
    EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
        Employee employee = new Employee();
        employee.setName("李很弱231231");
        employee.setSex(false);
        employee.setAge(33);
        employeeMapper.save(employee);
    sqlSession.commit();
}

mapper.xml的sql细节

添加时拿到返回的主键

把keyColumn数据库id这列对应的值 封装到keyProperty对应的属性中

  • useGeneratedKeys="true":表示要返回主键id
  • keyColumn="id": 数据库id列
  • keyProperty="id":实体类id属性字段

自定义映射规则

当数据库的列名和domain中的属性名不能对应的时候,我们就必须定义自定义映射规则 mybatis默认的映射规则: 数据库的列名和domain中的属性名对应,就赋值,否则不能赋值

mapper.xml:

<!--
    配置自定义映射规则
    id=""自定义映射规则的别名
    type 最终转为指定的类型
-->
<resultMap id="productResultMap" type="Product">
    <!--主键映射使用id-->
    <id column="id" property="sid"/>
    <!--普通属性使用result来映射-->
    <result column="dir_id" property="dirId"/>
</resultMap>

<!--
    resultType:返回的结果值类型
    resultMap:自定义映射规则
-->
<select id="selectAll" resultMap="productResultMap">
    SELECT * FROM product
</select>

动态sql语句

动态where条件,where标签

where标签的作用: 它会把第一个and换成where。其他不变

<select id="selectByQuery" parameterType="EmployeeQuery" resultType="Employee">
    SELECT <include refid="columnSql"/> FROM t_employee
    <where>
        <if test="name!=null and name!=''">
            AND name LIKE CONCAT("%",#{name},"%")
        </if>
        <if test="sex!=null">
            AND sex=#{sex}
        </if>
    </where>
</select>

动态修改语句,set标签

set标签的作用:他会把第一个表达式前加set,并且去掉最后一个表达式的逗号

<update id="update">
    UPDATE t_student
    <set>
      <if test="name!=null and name!=''">
          name=#{name},
      </if>
      <if test="age!=null">
          age=#{age},
      </if>
      <if test="email!=null and email!=''">
          email=#{email},
      </if>
      <if test="sex!=null">
          sex=#{sex},
      </if>
    </set>
    WHERE id=#{id}
</update>

抽取公共sql

能抽sql语句哪些部分呢?

  • where条件
  • sql查询的列
<sql id="columnSql">
     id,name,age,sex
</sql>

<select id="selectAll" resultType="Employee">
    SELECT
     <include refid="columnSql"/>
     FROM t_employee
</select>

<sql id="whereSql">
    <where>
        <if test="name!=null and name!=''">
            AND name LIKE CONCAT("%",#{name},"%")
        </if>
        <if test="sex!=null">
            AND sex=#{sex}
        </if>
        <if test="minAge!=null">
            AND age>=#{minAge}
        </if>
        <if test="maxAge!=null">
            <![CDATA[AND age<=#{maxAge}]]>
        </if>
    </where>
</sql>

<select id="selectByQuery" parameterType="EmployeeQuery" resultType="Employee">
    SELECT <include refid="columnSql"/> FROM t_employee
    <include refid="whereSql"/>
</select>

sql语句处理特殊符号

<![CDATA[字符串表达式]]> :会将xml中的字符串保持原样

CONCAT("%",#{name},"%"):拼接字符串

<select id="selectByQuery" parameterType="EmployeeQuery" resultType="Employee">
    SELECT id,name,age,sex FROM t_employee
    <where>
        <if test="name!=null and name!=''">
            AND name LIKE CONCAT("%",#{name},"%")
        </if>
        <if test="maxAge!=null">
            <![CDATA[AND age<=#{maxAge}]]>
        </if>
    </where>
</select>

批量删除

在xml中实现以下批量删除sql

DELETE  FROM  t_employee WHERE id in (id1,id2,id3)

使用foreach标签:该标签支持遍历数组和list集合

<!--collection="array|list"-->
<!--array方式-->
<delete id="batchDelete" parameterType="long[]">
    DELETE  FROM  t_employee
    WHERE id in
    <!--
      open="" 开始位置
      item="x" 循环迭代给每个元素取的别名
      separator=","  循环每次以指定的字符进行分割
    -->
    <foreach collection="array" open="(" item="x" separator="," close=")">
        #{x}
    </foreach>
</delete>
<!--list方式-->
<delete id="batchDelete2" parameterType="list">
    DELETE  FROM  t_employee
    WHERE id in
    <foreach collection="list" open="(" item="x" separator="," close=")">
        #{x.id}
    </foreach>
</delete>

批量添加

在xml中实现以下批量添加sql

INSERT INTO  t_employee(name, age, sex) 
VALUES (name1,age1,sex1),(name2,age2,sex2)

mapper.xml

<insert id="batchSave" parameterType="list">
    INSERT INTO  t_employee(name, age, sex) VALUES
    <foreach collection="list" item="x" separator=",">
        (#{x.name},#{x.age},#{x.sex})
    </foreach>
</insert>