JavaEE学习(七) MyBatis

本文是学习JavaEE开发的记录笔记

大纲

MyBatis

ORM(Object Relational Mapping,对象关系映射):是一种使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中,为了解决面向对象与关系数据库存在互不匹配现象的技术
JDBC(Java DataBase Connectivity,Java数据库连接):是一组使用Java语言编写的类和接口用于执行SQL语句为多种数据库提供统一访问
MyBatis:是由apache的开源项目iBatis迁移到google code改名形成,是一个实现ORM规则、对JDBC进行封装、基于Java的持久层框架

MyBatis入门示例

  1. 使用Maven构建项目
  2. 在pom.xml中添加MyBatis依赖:
  3. 创建数据库表:我这里使用以前项目的数据库,数据库名为mt,数据表为mt_product
    • 数据表结构如下
  4. 创建入门示例包:在src/main/java下创建dao包
  5. src/main/java/dao/下创建pojo包存储实体类:
    • POJO(Plain Ordinary Java Object,简单Java对象):是一种实体类,类中的属性与数据库表中的字段对应,类中的方法为每个属性的getter/setter方法,在MyBatis框架中通过关联的XML文件使实体类对象与数据库中的表对应,对象属性与表中字段相对应
    • dao/pojo/下创建对应数据表mt_product的实体类Product.java
  6. src/main/resources创建MyBatis配置文件[mybatis-config.xml]:
    • 配置文件格式可在MyBatis中文官网查看
    • 配置文件及相关标签解释如下
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      <?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>

      <!--定义pojo包路径 映射文件resultType中可直接指定实体类名-->
      <typeAliases>
      <package name="dao.pojo"/>
      </typeAliases>


      <!--定义数据源 development表示生产环境 可通过多个<environment>标签配置多个环境下的数据源-->
      <environments default="development">
      <environment id="development">
      <!--事务管理 JDBC自身事务管理-->
      <transactionManager type="JDBC"/>
      <!--连接池参数配置-->
      <dataSource type="POOLED">
      <property name="driver" value="com.mysql.jdbc.Driver"/>
      <property name="url" value="jdbc:mysql://localhost/mt?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=true"/>
      <property name="username" value="root"/>
      <property name="password" value=""/>
      </dataSource>
      </environment>
      </environments>

      <!--映射文件-->
      <mappers>
      <!--配置路径-->
      <mapper resource="mapper/ProductMapper.xml"/>
      </mappers>

      </configuration>
  7. src/main/resources下创建mapper包存储映射文件
    • 创建实体类Product与数据表mt_product的映射文件ProductMapper.xml
    • 映射文件格式同样可在MyBatis中文官网查看
    • 映射文件及相关解释如下
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <?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">
      <!--namespace对应实现映射的接口类名-->
      <mapper namespace="dao.mapper.ProductMapper">
      <!--SQL映射语句-->
      <!--参数id为实现这个SQL语句的接口的方法名-->
      <!--参数parameterType为传入参数#{}类型-->
      <!--参数resultType为返回类型一般为对应的pojo实体类 resultType一般为全名引用 若想直接使用需要在mybatis-config.xml下定义包-->
      <select id="selectProduct" parameterType="int" resultType="Product">
      select * from mt_product where id = #{id}
      </select>

      <!--其他SQL映射语句-->
      <!--<insert id=""></insert>-->
      <!--<delete id=""></delete>-->
      <!--<update id=""></update>-->
      </mapper>
  8. src/main/java/dao/下创建mapper包存储映射接口
    • dao/mapper/下创建调用映射的接口ProductMapper
    • 调用映射的接口包含对应SQL映射语句的方法,如上的映射语句对应如下的接口
  9. src/main/java/dao下创建util包存储工具类
    • dao/util/下创建工具类GetSqlSessionFactory.java用于得到SQLSession对象
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      package dao.util;

      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.Reader;

      public class GetSqlSessionFactory {
      //SQL会话工厂对象
      private static SqlSessionFactory sqlSessionFactory=null;
      //静态代码块 用于读取配置文件创建SQL会话工厂对象
      static{
      try
      {
      //rs存储MyBatis配置文件路径
      String rs="mybatis-config.xml";
      Reader reader=null;
      //读取配置文件存储在reader中
      reader = Resources.getResourceAsReader(rs);
      //根据reader创建SQL会话工厂对象
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
      } catch (IOException e)
      {
      e.printStackTrace();
      }
      }

      //通过SQL会话工厂对象打开一个SQL会话用于调用接口实现SQL语句
      public static SqlSession getSqlSession() {
      return sqlSessionFactory.openSession();
      }

      //私有构造方法 禁止外界创建SQL会话工厂对象
      private GetSqlSessionFactory(){}

      }
  10. src/test/java下创建dao.mapper包用于测试接口
    • 添加junit依赖
    • 在dao.mapper下创建测试类ProductMapperTest测试ProductMapper接口
    • 在测试类ProductMapperTest下创建testSelectProduct测试方法并添加@Test注解测试ProductMapper接口中的selectProduct方法
    • 执行结果如下

dao.mapper.ProductMapper

不使用接口执行SQL映射语句

在入门示例中我们使用接口ProductMapper绑定了映射文件ProductMapper.xml,在测试用例中我们通过工具类获取SQL会话,通过SQL会话的反射机制获得ProductMapper接口的对象,从而调用接口对象的方法执行SQL映射语句
然而还有一种不使用接口执行SQL映射语句,不需要编写接口直接使用映射文件ProductMapper.xml,通过其mapper标签的namespace属性指定xml映射文件,之后通过SQL会话的方法通过传入namespace.SQL映射语句id的方式执行SQL映射语句

  1. 指定ProductMapper.xml的mapper标签的namespace属性:如test
  2. 测试用例中使用namespace.SQL映射语句id形式执行SQL映射语句:
    • 执行结果如下

数据库列名和pojo属性名不一致

若数据库列名和pojo属性名不一致,会造成查询的数据存储不到pojo实体类对象中,造成某些属性值为null
解决方案有两种:

  1. 别名:
    • 将pojo中的sid属性名改为test属性名
    • 直接查询会出现pojo实体中test属性为null
    • 在SQL映射语句中的使用as语法将数据库列名转换为pojo属性名
    • 此时执行查询会将数据库列名sid的值存储在pojo属性名test中
  2. ResultMap:
    • ProductMapper.xml定义ResultMap标签:
    • 在SQL映射语句中的resultMap属性指定ResultMap使用的标签:
    • 测试用例中使用新的SQL映射语句
    • 执行结果如下

模糊查询(SQL映射语句#/$传参)

  1. 使用#{}占位符传参形式,则使用?为占位符替换#{},无法在SQL语句中添加%

  2. 使用${}字符串拼接传参形式,则可以在SQL语句中直接添加%,用$传参需要注意
    • 若参数为字符串类型,需要在SQL语句中添加单引号’’包围${}
    • 参数为一个且为简单类型必须使用value
    • 参数为表名或者列名必须使用$传参

多参数传递

  1. 接口中使用注解@Param(value=””)
    • SQL映射语句中的#{}值与接口中@Param的value值相对应
    • XML
    • 接口
  2. 测试类中使用Map传递参数
    • SQL映射语句中的#{}值与Map中的KEY相对应
    • XML
    • 接口
    • 测试类

SQL插入语句

  • SQL映射语句XML
  • 接口:返回值为影响行数
  • 测试类:注意需要提交事务才能插入生效
  • 获取自增ID
    • 在SQL映射语句中配置useGeneratedKeys和keyProperty属性,MyBatis会在插入操作后将自增id放入被插入的实体类中

整合MyBatis和Spring