Mybatis入门

Mybatis入门

Mybatis入门

1.上节回顾

2.常见面试题

  1. 什么是orm框架?
  2. 使用mybatis的操作步骤?
  3. 如何使用mybatis返回自动生成的主键值?
  4. Mapper接口或者Dao接口的工作原理

3.本章重点

  1. 理解MyBatis概念及其应用场景
  2. MyBatis使用,入门程序搭建步骤(掌握)
  3. 使用Mapper动态代理实现CRUD

4.内容详解

4.1 MyBatis入门

4.1.1 MyBatis介绍

​ MyBatis 是一款优秀的持久层框架,是一款简单的ORM框架(Object-Relational Mapping,简称ORM),它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通 Java 对象)为数据库中的记录。

​ 对象-关系映射(Object-Relational Mapping,简称ORM),对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

​ 目前主流持久层框架:Hiberanate,Jpa,SpringJDBC

​ J2EE 的三大框架:SSH(Struts2+Spring+Hibernate)

​ SSM(SpringMVC+Spring+Mybatis)

4.1.2 Mybatis整体架构

1568619373726

架构大致分为三层:

​ API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。

​ 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。

​ 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。

4.2 MyBatis使用

4.2.1 为什么使用MyBatis

硬代码(硬编码问题)

回忆使用JDBC进行数据库操作步骤:

​ 加载jdbc驱动-->获取数据库连接-->创建ps对象-->设置参数-->执行SQL语句,返回结果集-->对结果集进行遍历,生成JavaBean对象返回-->释放资源

传统JDBC开发模式存在的缺陷:

  • 数据库连接参数硬编码
  • Sql语句的硬编码
  • 数据库的频繁连接与断开
  • 查询结果集取数据时的硬编码
  • sql代码与Java代码混合使用,代码不规范且不利于维护

针对上述问题,有没有解决方案??有,使用MyBatis即可,因为MyBatisf可以解决以上问题

​ MyBatis使用XML配置文件形式创建自己的数据库连接池,避免了数据库连接参数硬编码问题,同时避免了对数据库的频繁连接与关闭问题;MyBatis将SQL语句配置在xml文件中,避免了SQL硬编码问题;通过MyBatis的输出映射机制,可以将结果集自动映射为Java对象,避免了对结果集的手工检索。

4.2.2 MyBatis入门程序

  1. 新建一个数据库mybatis01,新建一张表blog(id,name,content)

    CREATE TABLE blog(
    id INT(3) PRIMARY KEY NOT NULL auto_increment,
    name VARCHAR(30),
    content VARCHAR(30)
    )
    
  2. 搭建Java项目,引入jar包(2个jar包)

    1570845131495

  3. 编写持久层类Blog

    包含三个字段,id(int),name,content

  4. 新建一个全局配置文件 mybatisConfig.xml

    dtd(Document type definition),是一种规范约束,用来检验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>
        <properties resource="dev-db.properties"></properties>
        <environments default="dev">
            <environment id="dev">
    <!--            事务管理配置-->
                <transactionManager type="JDBC"></transactionManager>
    <!--            数据源配置-->
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
          <!--sql映射文件-->
        <mappers>
            <mapper resource="com/aaa/mapper/BlogMapper.xml"></mapper>
        </mappers>
    </configuration>
    
  5. 包含SQL语句的mapper映射文件

    ​ 此配置文件和我们要执行的SQL语句有关,MyBatis几乎所有的SQL语句都配置在此文件中,在适当的时机,MyBatis会加载此文件,读取其中SQL信息以及输入输出参数信息

    ​ 所有配置都包裹在mapper标签对中,mapper标签有一个namespace属性,此属性作用是对SQL进行分类化管理(与Java的包名进行类似,但它是包名+类名),实现不同业务的SQL隔离。

    <?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="com.aaa.mapper.BlogMapper">
        <!--查询一条SQL配置-->
        <select id="queryBlog" parameterType="int" resultType="com.aaa.entity.Blog" >
            select * from blog where id=#{id}
        </select>
    </mapper>
    

    ​ id是命名空间唯一标识符,可以用来引用这条SQL语句

    ​ #{} 输入参数用占位符来标识对应的位置 是一种占位符 告诉MyBatis创建一个预处理参数。接收输入参数的类型可以是简单类型,普通JavaBean或者HashMap,如果接收的是JavaBean,会通过OGNL读取对象中的属性值

    ​ 编写完SQL映射文件后,为了能让MyBatis资源文件加载类解析Mapper文件,需要将Mapper文件的路径配置在全局配置文件中。具体配置在最下面的标签mappers标签中

  6. 编写测试类

    ​ 编写数据库交互类,上面提到资源文件加载类会读取全局配置文件,然后SqlSessionFactory类会获取数据库连接数据和Mapper映射规则,从而创建出能与数据库交互的SqlSession对象。因此需要先获取SqlSessionFactory

    package com.aaa.entity;
    
    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 org.junit.Before;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.SQLFeatureNotSupportedException;
    
    import static org.junit.Assert.*;
    
    /**
     * @Date: 2019/10/12 10:44
     * @Version: 1.0
     */
    public class BlogTest {
        private static SqlSessionFactory sqlSessionFactory;
    
        @Before
        public void before() throws IOException {
            String resource = "mybatisConfig.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        }
    
        @Test
        public void testSelect() {
            SqlSession sqlSession = sqlSessionFactory.openSession();
            Blog blog = (Blog) sqlSession.selectOne("com.aaa.mapper.BlogMapper.queryBlog", 1);
            System.out.println(blog);
        }
    }
    
  7. 添加log配置

    日志的重要性,生产故障以及分布式调试,bug的难重现

    1. 配置文件log4j.properties

      # Global logging configuration
      # All,DEBUG,INFO,WARN,ERROR,FATAL,OFF
      #1,log级别,输出stdout所指定的载体中
      log4j.rootLogger=DEBUG, stdout
      # MyBatis logging configuration...
      #log4j.logger.org.mybatis.example.BlogMapper=TRACE
      # Console output...
      #2,日志输出载体是哪种类型
      log4j.appender.stdout=org.apache.log4j.ConsoleAppender
      # 输出界面布局类型,
      log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
      # 具体格式
      log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
      
    2. 在全局配置文件中添加:

      setting的位置在properties下面

          <properties resource="dev-db.properties"></properties>
      <!--配置日志信息-->
          <settings>
              <setting name="logImpl" value="LOG4J"/>
          </settings>
      
    3. log需要的jar包放在MyBatis解压文件的lib目录下

到此入门程序搭建完毕,以下为项目目录截图

4.3 Mapper动态代理实现CRUD

​ 使用MyBatis开发Web项目时,通过Mapper动态代理机制,可以只编写数据交互的接口以及方法定义,和对应的Mapper映射文件,具体的交互方法实现由MyBatis来完成。大大节省了开发DAO层的时间

代理方法的实现需遵循以下规则:

  1. mapper的namespace指定了接口的路径
  2. 接口名称与对应的mapper.xml配置文件名相同
  3. 接口中方法的方法名和参数以及返回类型必须与mapper.xml配置文件中对应的

sql映射文件配置:

还是上述文件

接口代码:

package com.aaa.mapper;

import com.aaa.entity.Blog;

/**
 * @Date: 2019/10/12 11:26
 * @Version: 1.0
 */
public interface BlogMapper {
     /**
     *查询一个blog 记录
     * @param id
     * @return
     */
    Blog queryBlog(int id);
}

​ 接口的全限名,就是映射文件中的namespace的值;接口的方法名,就是映射文件中Mapper的Statement的id值;接口方法内的参数,就是传递给sql的参数。

测试类代码:

 @Test
    public void testSelect() {
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        Blog blog = (Blog) sqlSession.selectOne("com.aaa.mapper.BlogMapper.queryBlog", 1);
        BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
        Blog blog = mapper.queryBlog(1);
        System.out.println(blog);
    }

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://championmi.cn/archives/mybatis入门

Buy me a cup of coffee ☕.