飞道的博客

MyBatis学习05-初识MyBatis

328人阅读  评论(0)

1 前言

目前比较流程的 ORM 框架有 Hibernate、Spring Data JPA、Mybatis(半 ORM 框架)。

对于 Spring Data JPA 框架,Spring 基于 JPA 规范进行实现,对 JDBC 进行了高度的封装,不怎么需要开发人员进行 SQL 语句的编写,可以说使用 Spring Data JPA 进行数据库相关的开发工作效率是最高的。

对于 Hibernate 笔者没有过多的接触,只是听到各种传言说 Hibernate 这个框架比较重,内含的一级缓存、二级缓存、HQL 知识点过多,及项目上没有直接使用过 Hibernate 进行实现,所以没有作过多的研究学习。

Mybatis 是一个轻量级的半 ORM 框架,之所以这样说是因为 Mybatis 只进行了部分封装,所有的 SQL 语句都需要研发人员进行编写。

2 MyBatis

2.1 官网地址

https://mybatis.org/mybatis-3/zh/index.html

2.2 简介

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

2.3 示例

运行环境:Win10 + Jdk1.8 + Maven3 + Intellij IDEA 2020 + mysql5.7 + Mybatis3

1、示例代码地址

https://gitee.com/lif/study-mybatis/tree/master

2、目录结构如下


3、pom.xml 文件引入依赖包

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ddpyjqtd</groupId>
    <artifactId>simple-mybatis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <name>simple-mybatis</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.10</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.4</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.20</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j-impl</artifactId>
            <version>2.13.3</version>
            <scope>test</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.13.3</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.13.3</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

4、增加 model 类: Demo.java

package com.ddpyjqtd.demo.model;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.Date;

/***
 * 测试表对应的demo类
 *
 * @author ddpyjqtd
 * @date 2020/5/22 16:30
 */
@Getter
@Setter
@ToString
public class Demo {
    /**
     * int 类型字段
     */
    private int demoInt;
    /**
     * String 类型字段
     */
    private String demoVarchar;
    /**
     * text 类型字段
     */
    private String demoText;
    /**
     * datetime 类型字段
     */
    private Date demoDateTime;

}

5、增加数据库配置文件:db.properties,内容如下:

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username=root
password=root

6、增加日志配置文件 log4j2.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--官方文档:https://logging.apache.org/log4j/2.x/manual/appenders.html-->
<configuration status="OFF">
    <Properties>
        <!-- 只需要输入日志文件路径与当前项目名称 -->
        <property name="file_path">d://logs</property>
        <property name="project_name">simple-mybatis</property>

        <property name="file_name">${file_path}/${project_name}.log</property>
        <property name="file_sql_name">${file_path}/${project_name}-sql.log</property>
        <property name="file_error">${file_path}/${project_name}-error.log</property>
        <property name="log_pattern">%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p %c{36} %L %M - %m%n</property>
    </Properties>
    <appenders>
        <!-- 控制台输出 -->
        <Console name="Console" target="SYSTEM_OUT">
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}"/>
        </Console>
        <!-- 业务输出 -->
        <File name="default_log" fileName="${file_name}" append="false">
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
            <PatternLayout pattern="${log_pattern}"/>
        </File>
        <!-- error 级别日志输出 -->
        <File name="error_log" fileName="${file_error}" append="false">
            <PatternLayout pattern="${log_pattern}"/>
            <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
        <!-- mybatis 执行sql 输出 -->
        <File name="mybatis_sql_log" fileName="${file_sql_name}" append="false">
            <PatternLayout pattern="${log_pattern}"/>
            <ThresholdFilter level="debug" onMatch="ACCEPT" onMismatch="DENY"/>
        </File>
    </appenders>
    <loggers>
        <Logger name="org" level="info" additivity="true"/>
        <Logger name="com" level="info" additivity="true"/>
        <Logger name="com.ddpyjqtd" level="debug" additivity="true">
            <appender-ref ref="mybatis_sql_log" level="debug"/>
        </Logger>

        <!--生产环境需要注释掉控制台配置-->
        <Root level="debug" includeLocation="true">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="default_log"/>
            <AppenderRef ref="error_log"/>
        </Root>
    </loggers>
</configuration>

7、增加 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>
    <properties resource="db.properties" />
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.ddpyjqtd.demo.model"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <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>
    <mappers>
        <mapper resource="mapper/demo/DemoMapper.xml"/>
    </mappers>
</configuration>

8、增加数据库配置文件读取工具类:DbUtils.java,内容如下:

package com.ddpyjqtd.demo.utils;

import lombok.extern.slf4j.Slf4j;
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;

/**
 * @description: 处理数据库连接相关事项
 * @author: ddpyjqtd
 * @date: 2020/5/22 18:13
 */
@Slf4j
public class DbUtils {

    private DbUtils() {
    }

    private static SqlSessionFactory factory;

    static {
        try {
            factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsReader("mybatis-config.xml"));
        } catch (IOException e) {
            log.error("SqlSessionFactory create Error : ", e);
        }
    }


    /**
     * 获取 SqlSession 实例对象
     *
     * @return org.apache.ibatis.session.SqlSession
     * @author ddpyjqtd
     * @date 2020/5/22 18:28
     */
    public static SqlSession getSqlSession() {
        return factory.openSession();
    }

    /**
     * 关闭SqlSession
     *
     * @param sqlSession 会话对象
     * @author ddpyjqtd
     * @date 2020/5/24 21:51
     */
    public static void closeSqlSession(SqlSession sqlSession) {
        if (sqlSession == null) {
            return;
        }
        sqlSession.close();
    }
}

9、编写数据库操作接口:DemoMapper.java,内容如下:

package com.ddpyjqtd.demo.dao;

import com.ddpyjqtd.demo.model.Demo;

/**
 * 数据库映射接口
 *
 * @author ddpyjqtd
 * @date 2020/5/22 18:04
 */
public interface DemoMapper {


    /**
     * 通过ID查询Demo对象信息
     *
     * @param demoInt 主键ID
     * @return com.ddpyjqtd.demo.model.Demo
     * @author ddpyjqtd
     * @date 2020/5/24 22:22
     */
    Demo findDemoById(int demoInt);
}

10、 编写 Service 类:DemoService.java,内容如下:

package com.ddpyjqtd.demo.service;

import com.ddpyjqtd.demo.dao.DemoMapper;
import com.ddpyjqtd.demo.model.Demo;
import com.ddpyjqtd.demo.utils.DbUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSession;

/**
 * 示例类Service
 *
 * @author ddpyjqtd
 * @date 2020/5/22 18:26
 */
@Slf4j
public class DemoService {

    /**
     * 通过ID获取对应的示例对象
     *
     * @param demoInt 主键ID
     * @return com.ddpyjqtd.demo.model.Demo
     * @author ddpyjqtd
     * @date 2020/5/24 22:28
     */
    public Demo findDemoByKey(int demoInt) {
        SqlSession session = DbUtils.getSqlSession();
        DemoMapper demoMapper = session.getMapper(DemoMapper.class);
        Demo demo = demoMapper.findDemoById(demoInt);
        if (demo != null) {
            log.info("demo info is : {}", demo);
        }
        DbUtils.closeSqlSession(session);
        return demo;
    }
}

11、编写 Mybatis 映射器文件:DemoMapper.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">

<mapper namespace="com.ddpyjqtd.demo.dao.DemoMapper">

    <select id="findDemoById" resultType="Demo">
        select * from demo where demo_int = #{demoInt}
  </select>
</mapper>

12、执行 SQL

CREATE TABLE demo  (
  demo_int int(255) NOT NULL COMMENT 'int 类型字段',
  demo_varchar varchar(255)  NULL DEFAULT NULL COMMENT 'String 类型字段',
  demo_text text  NULL COMMENT 'text 类型字段',
  demo_date_time datetime(0) NULL DEFAULT NULL COMMENT 'datetime 类型字段',
  PRIMARY KEY (demo_int) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_bin COMMENT = '示例表,各个字段为数据库的各种类型' ROW_FORMAT = Dynamic;


insert into demo (demo_int, demo_varchar, demo_text, demo_date_time)
VALUES (1, 'this is demo_varchar', 'this is demo_text', now());

13、编写测试类:TestDemoService.java,内容如下:

package com.ddpyjqtd.demo;

import com.ddpyjqtd.demo.model.Demo;
import com.ddpyjqtd.demo.service.DemoService;
import org.junit.Assert;
import org.junit.Test;

import java.util.Date;

/**
 * 测试service
 *
 * @author ddpyjqtd
 * @date 2020/5/22 18:31
 */
public class TestDemoService {

    @Test
    public void findDemoByKey() {
        DemoService service = new DemoService();
        Demo demo = service.findDemoByKey(1);
        Assert.assertNotNull(demo);
    }

}

14、运行测试类,执行结果如下:

2020-06-14 21:19:40.346 DEBUG com.ddpyjqtd.demo.dao.DemoMapper.findDemoById 143 debug - ==>  Preparing: select * from demo where demo_int = ? 
2020-06-14 21:19:40.392 DEBUG com.ddpyjqtd.demo.dao.DemoMapper.findDemoById 143 debug - ==> Parameters: 1(Integer)
2020-06-14 21:19:40.427 DEBUG com.ddpyjqtd.demo.dao.DemoMapper.findDemoById 143 debug - <==      Total: 1
2020-06-14 21:19:40.431 INFO  com.ddpyjqtd.demo.service.DemoService 31 findDemoByKey - demo info is : Demo(demoInt=1, demoVarchar=this is demo_varchar, demoText=this is demo_text, demoDateTime=Sat Jun 06 06:37:37 CST 2020)

Process finished with exit code 0

2.4 优缺点

2.4.1 优点

  • 轻量级的半 ORM 框架,对 JDBC 进行了一定的封装,简单易学。
  • SQL 语句单独写在 XML 文件中,不存在这块的硬编码
  • 由于 SQL 文件的单独规划,对于系统的 SQL 的性能优化非常的方便。

2.4.2 缺点

  • 所有的 SQL 都需要研发人员进行编写,开发效率比其它的 ORM 框架要低很多。
  • 由于 SQL 全是研发人员进行编写的,对于数据库的兼容性比较差,如果一套系统需要同时兼容多款数据库,则需要研发人员同时编写多个不同的数据库对应的语句。
  • Mybatis 中的一级缓存与二级缓存,对于现在常规的系统设计(设计上都是使用 redis 等第三方缓存数据库,且缓存方式需要按系统业务规则进行设计,Mybatis 自带的缓存无法应用于各个不同的系统)中有占鸡肋。

转载:https://blog.csdn.net/wwww641788662/article/details/106752042
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场