MyBatis基础

MyBatis

简介

  • ORM : 对象关系映射(Object RelationShip Mapping)
  • MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
  • iBatis一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBaties提供的持久层框架包括SQL Maps和Data Access Objects(sDAO)

官网

概述

  • MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • MyBatis主要就完成2件事情
    1. 封装JDBC操作
    2. 利用反射打通Java类与SQL语句之间的相互转换
  • MyBatis的主要设计目的就是让我们对执行SQL语句时对输入输出的数据管理更加方便,所以方便地写出SQL和方便地获取SQL的执行结果才是MyBatis的核心竞争力。

特点

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的ORM字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql

体系结构

MyBatis

  • mybatis配置文件,包括Mybatis全局配置文件Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。
  • mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
  • 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
  • SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
  • Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。

MyBatis入门

创建Maven项目

添加依赖信息

  <dependencies>
  	<dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <version>x.x.xx</version>
     </dependency>
     <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
     <dependency>
         <groupId>org.mybatis</groupId>
         <artifactId>mybatis</artifactId>
         <version>x.x.x</version>
     </dependency>
  <!-- https://mvnrepository.com/artifact/log4j/log4j -->
     <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
         <version>x.x.xx</version>
     </dependency>
  </dependencies>

加入配置文件

  • 在resources目录中添加Mybatis的核心配置mybatis-config.xmllog4j日志文件log4j.properties
  • 也可去官方文档中找到这些配置文件中的内容,日志文件可去【日志框架】文章中找
  <?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>
  	<!-- 和spring整合后 environments配置将废除 -->
  	<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:3306/mybatis_01?characterEncoding=utf-8" />
  				<property name="username" value="root" />
  				<property name="password" value="root" />
  			</dataSource>
  		</environment>
  	</environments>
   <!-- 添加映射文件位置  -->
   <mappers>
      <mapper resource="xxx/xx/mapper/XxxMapper.xml"/>
   </mappers>
  </configuration>

创建POJO

  • domain、bean、entity、pojo
  • 在不同的场合使用的对象的分类:
    • po : Persistent Object (持久化对象)
    • vo:View Object (视图对象 ,PageBean)
    • dto: Data Transfer Object (数据传输对象 ,系统与系统之间传递数据)
    • bo : Business Object (业务对象)

什么是POJO:

  • POJO是Plain Old Java Objects的缩写,POJO实质上可以理解为简单的实体类,顾名思义POJO类的作用是方便程序员使用数据库中的数据表
  • 对于广大的程序员,可以很方便的将POJO类当做对象来进行使用,当然也是可以方便的调用其get、set方法。

加入sql映射文件

  • 创建XxxMapper.xml文件
  • 将XxxMapper.xml添加在mybatis-config.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">
  <!-- namespace:命名空间,用于隔离sql -->
  <mapper namespace="test">
      <!-- id:statement的id 或者叫做sql的id-->
      <!-- parameterType:声明输入参数的类型 -->
      <!-- resultType:声明输出结果的类型,应该填写pojo的全路径 -->
      <!-- #{}:输入参数的占位符,相当于jdbc的?
      如果是简单类型(基本类型、字符串类型)名称可以任意-->
      <!-- 如果传入的参数是简单数据类型,使用${}里面必须写value -->
      <select id="xxxx" parameterType="Integer" resultType="com.xxx.pojo.User">
          SELECT * FROM `user` WHERE id  = #{id}
      </select>
  </mapper>

连接程序

  • MyBatis框架中涉及到的几个API:
    • SqlSessionFactoryBuilder:
      • 该对象负责根据MyBatis配置文件mybatis-config.xml构建SqlSessionFactory实例
      • SqlSessionFactoryBuilder用于创建SqlSessionFactory,SqlSessionFactory一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。
      • 所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。
    • SqlSessionFactory:
      • 每一个MyBatis的应用程序都以一个SqlSessionFactory对象为核心。该对象负责创建SqlSession对象实例。
      • SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory
    • SqlSession:
      • 该对象包含了所有执行SQL操作的方法,用于执行已映射的SQL语句
      • SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。
      • 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。
      • 因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
      • 打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。
    • SqlSession的使用范围:
      • SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
      • SqlSession通过SqlSessionFactory创建。
      • SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
  • 代码:
  // 1. 创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  // 2. 加载SqlMapConfig.xml配置文件
  InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
  // 3. 创建SqlSessionFactory对象
  SqlSessionFactory factory = sqlSessionFactoryBuilder.build(inputStream);
  // 4.创建SqlSession
  SqlSession sqlSession = factory.openSession();
  // 5.执行,要和映射文件中填写一致
  User user = sqlSession.selectOne("test.xxxx", 1);
  // 6. 打印结果
  System.out.println(user);
  //sqlSession.commit();添加、删除,修改需要提交
  // 7. 释放资源
  sqlSession.close();

selectOne和selectList

  • 动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据XxxMapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

其他

#{}和${}的区别

  • (1)#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它任意名称
  • (2)${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value

parameterType和resultType

  • parameterType:指定输入参数类型,MyBatis通过ognl从输入对象中获取参数值拼接在sql中。
  • resultType:指定输出结果类型,MyBatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

实现增删改

  • 映射文件配置<insert>标签,用于执行插入操作。
  • 在插入操作完成之前或之后,可以配置<selectKey>标签获得生成的主键的值,获得插入之前还是之后的值,可以通过配置order属性来指定。
  <insert id="addUser" parameterType="com.qf.po.User">
      <!-- selectKey 标签实现主键返回,查询主键,在标签内需要输入查询主键的sql -->
      <!-- keyProperty:主键对应的pojo中的哪一个属性 -->
      <!-- order:指定查询主键的sql和insert语句的执行顺序,设置在执行insert语句前执行查询id的sql,还是在执行insert语句之后执行查询id的sql -->
      <!-- resultType:设置返回的id的类型 -->
      <!-- LAST_INSERT_ID:该函数是mysql的函数,获取自增主键的ID,它必须配合insert语句一起使用
      注意:它是获取当前事务中,最近一次增加的主键值 -->
      <selectKey keyProperty="id" resultType="int" order="AFTER">
	        SELECT LAST_INSERT_ID() 
      </selectKey>

      INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
  </insert>

  • 在映射文件文件中使用<delete>标签配置删除的statement。
  <delete id="deleteUser" parameterType="int">
    	delete from user where id=#{id}
  </delete>

  • 在映射文件使用<update>标签配置修改的statement。
  <update id="updateUser" parameterType="com.qf.pojo.User">
      update user set username=#{username},sex=#{sex},birthday=#{birthday},address=#{address}  where id= #{id}
  </update>

MyBatis两种开发方式

  • 使用MyBatis开发Dao,通常有两种方式,即原始Dao开发方式Mapper接口动态代理开发方式。推荐使用第二种。
    • MyBatis配置文件
    • 封装MyBatisUtils工具类
    • 原生Dao方式,编写Dao层接口Dao层实现类(老方式)
    • 另一种方式,Mapper接口动态代理方式(重要的,推荐的)
    • 动态代理开发规范
      • Mapper接口开发方法只需要程序员编写XxxMapper接口(相当于Dao接口)
      • 由MyBatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同Dao层接口实现类方法。
      • Mapper接口开发需要遵循以下规范:
        1. Mapper.xml文件中的namespace与mapper接口的类路径相同。
        2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
        3. Mapper接口方法的输入参数类型和Mapper.xml中定义的每个sql 的parameterType的类型相同(注意:Mapper.xml中parameterType可不写,如果不写则由Mapper接口中的方法参数类型决定)
        4. Mapper接口方法的返回值类型和Mapper.xml中定义的每个sql的resultType(输出参数类型)的类型相同
  • XxxMapper.java接口(Xxx和实体类名相对应)
public interface XxxDao {
	Xxx queryXxxById(int id);
	List<Xxx> queryXxxByUsername(String username);
	void saveXxx(Xxx xxx);
}
  • XxxMapper.xml映射文件与XxxMapper.java接口相对应
<?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:命名空间,用于隔离sql -->
  <!-- 还有一个很重要的作用,使用动态代理开发DAO,
  1. namespace必须和Mapper接口类路径一致 -->
  <mapper namespace="com.xxx.mapper.XxxMapper">
	    <!-- 根据用户id查询用户 -->
	    <!-- 2. id必须和Mapper接口方法名一致 -->
	    <!-- 3. parameterType必须和接口方法参数类型一致 -->
	    <!-- 4. resultType必须和接口方法返回值类型一致 -->
	    <select id="queryXxxById" parameterType="int"
		    resultType="com.xxx.pojo.Xxx">
		    select * from xxx where id = #{id}
	    </select>

	    <!-- 根据用户名查询用户 -->
	    <select id="queryXxxByUsername" parameterType="string"
		    resultType="com.xxx.pojo.Xxx">
		    select * from xxx where username like '%${value}%'
	    </select>

	    <!-- 保存用户 -->
	    <insert id="saveXxx" parameterType="com.xxx.pojo.Xxx">
		    <selectKey keyProperty="id" keyColumn="id" order="AFTER"
			    resultType="int">
			    select last_insert_id()
		    </selectKey>
		    insert into xxx(username,birthday,sex,address) values
		    (#{username},#{birthday},#{sex},#{address});
	    </insert>
  </mapper>

把java目录中配置也编译程序中:

  • 需要在Maven项目的pom.xml文件中添加下面的代码,不然MaBatis配置文件找不到Mapper.xml文件路径。
  <!--把java目录中配置也包含在项目的类路径中-->
  <build>
      <resources>
          <resource>
              <directory>src/main/resources</directory>
          </resource>
          <resource>
              <directory>src/main/java</directory>
              <includes>
                  <include>**/*.properties</include>
                  <include>**/*.xml</include>
              </includes>
              <!-- 是否替换资源中的属性-->
              <filtering>false</filtering>
          </resource>
      </resources>
  </build>

转载请注明:Memory的博客 » 点击阅读原文

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦