Spring Boot 集成 MyBatis

Posted miantiao312

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot 集成 MyBatis相关的知识,希望对你有一定的参考价值。

Spring Boot 集成 MyBatis

    A、ORM框架是什么?
            对象关系映射(Object Relational Mapping,简称 ORM)模式是一种为了解决面向对象与关系数据库存在的
            互不匹配的现象技术。简单的说,ORM 是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自
            动持久化到关系数据库中。
    
    B、为什么需要ORM框架
            当开发一个应用程序的时候(不使用 O/R Mapping),可能会写不少数据访问层的代码,用来从数据库保存、
            删除、读取对象信息等。在 DAL 中写了很多的方法来读取对象数据、改变状态对象等任务,而这些代码写
            起来总是重复的。针对这些问题 ORM 提供了解决方案,简化了将程序中的对象持久化到关系数据库中的操作。
            
            ORM 框架的本质是简化编程中操作数据库的编码,一个是宣称可以不用写一句 SQL 的 Hibernate,
            一个是以动态 SQL 见长的 MyBatis,两者各有特点。在企业级系统开发中可以根据需求灵活使用,
            有趣的现象:传统企业大都喜欢使用 Hibernate,而互联网行业通常使用MyBatis。
    C、MyBatis 介绍
            MyBatis 支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的 JDBC 代
            码和参数的手工设置以及对结果集的检索封装。MaBatis 可以使用简单的 XML 或注解用于配置和原始映射。
            将接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
            
            优点:
                SQL 被统一提取出来,便于统一管理和优化
                SQL 和代码解耦,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试
                提供映射标签,支持对象与数据库的 ORM 字段关系映射
                提供对象关系映射标签,支持对象关系组件维护
                灵活书写动态 SQL,支持各种条件来动态生成不同的 SQL
            缺点:
                编写 SQL 语句时工作量很大,尤其是字段多、关联表多时,更是如此
                SQL 语句依赖于数据库,导致数据库移植性差

    E、MyBatis 重要的概念
            Mapper 配置: Mapper 配置可以使用基于 XML 的 Mapper 配置?文件来实现,也可以使用基于 Java 注解的
                          MyBatis 注解来实现,甚至可以直接使用 MyBatis 提供的 API 来实现。
            Mapper 接口: Mapper 接口是指自行定义的一个数据操做接口,类似于通常所说的 DAO 接?口。早期的Mapper
                          接口需要自定义去实现,现在 MyBatis 会自动为 Mapper 接口创建动态代理对象。Mapper 接
                          口的方法通常与 Mapper 配置?文件中的 select、insert、update、delete 等 XML 结点存在
                          一一对应关系。
            Executor: MyBatis 中所有的 Mapper 语句的执行都是通过 Executor 进行的,Executor 是 MyBatis 的一个
                       核?心接口。
            SqlSession: SqlSession 是 MyBatis 的关键对象,是执行持久化操作的独享,类似于 JDBC 中的Connection,
                         SqlSession 对象完全包含以数据库为背景的所有执行 SQL 操作的方法,它的底层封装了JDBC连
                         接,可以用 SqlSession 实例来直接执行被映射的 SQL 语句。
            SqlSessionFactory: SqlSessionFactory 是 MyBatis 的关键对象,它是单个数据库映射关系经过编译后的内
                                存镜像。SqlSessionFactory 对象的实例可以通过 SqlSessionFactoryBuilder 对象类获
                                得,而SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 
                                Configuration 的实例构建出。

    F、MyBatis 的工作流程如下:
            a、首先加载 Mapper 配置的 SQL 映射文件,或者是注解的相关 SQL 内容。
            b、创建会话工厂,MyBatis 通过读取配置文件的信息来构造出会话工厂(SqlSessionFactory)。
            c、创建会话。根据会话工厂,MyBatis 就可以通过它来创建会话对象(SqlSession)。会话对象是一个接
               口,该接口中包含了对数据库操作的增删改查?方法。
            d、创建执行器。因为会话对象本身不能直接操作数据库,所以它使用了一个叫做数据库执行器(Executor)
               的接口来帮它执行操作。
            e、封装 SQL 对象。在这一步,执行器将待处理的 SQL 信息封装到一个对象中(MappedStatement),该对
               象包括 SQL 语句、输?入参数映射信息(Java 简单类型、HashMap 或 POJO)和输出结果映射信息(Java 简单类型、HashMap 或 POJO)。
            f、操作数据库。拥有了执行器和 SQL 信息封装对象就使用它们访问数据库了,最后再返回操作结果,结束流程。
               在具体的使用过程中,按照上述的流程来执行。

技术分享图片

1、mybatis-spring-boot-starter 主要提供了两种解决方式,①XML配置,②使用注解。

A、XML版本

XML 版本保持映射文件的老传统,优化主要体现在不需要实现 Dao 的实现层,系统会自动根据方法名在映射文件中找到对应的 SQL。

POM.XML文件
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

    我还会引入另外一个组件,Apache 的 commons-lang 3 ,此包有非常多的工具类可以使用,
    比如常用的判断字符串是否为空,快速复写实体类的 toString() 方法等。

实体类文件:UserEntity
    public class UserEntity implements Serializable {

        private static final long serialVersionUID = 1L;
        private Long id;
        private String userName;
        private String passWord;
        private UserSexEnum userSex;
        private String nickName;
        //getter/setter省略
    }
枚举类:
    public enum UserSexEnum {
        MAN, WOMAN
    }

application.properties文件
    mybatis.config-location=classpath:mybatis/mybatis-config.xml
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    mybatis.type-aliases-package=com.kid.entity
    
    spring.datasource.driverClassName = com.mysql.jdbc.Driver
    spring.datasource.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
    spring.datasource.username = root
    spring.datasource.password = root

    # mybatis.config-locations :配置 mybatis-config.xml 路径,mybatis-config.xml 中配置MyBatis 基础属性。
    # mybatis.mapper-locations :配置 Mapper 对应的 XML 文件路径
    # mybatis.type-aliases-package :配置项目中实体类包路径
    # spring.datasource.* :数据源配置
    
    # Spring Boot 启动时数据源会自动注入到 SqlSessionFactory 中,使用 SqlSessionFactory 构建
    # SqlSessionFactory,再自动注入到 Mapper 中,最后我们直接使用 Mapper 即可

启动类:在启动类中添加对 Mapper 包扫描 @MapperScan ,Spring Boot 启动的时候会自动加载包路径下的Mapper。
    @SpringBootApplication
    @MapperScan("com.kid.mapper")
    public class SpringbootMybatisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootMybatisApplication.class, args);
        }
    }
    
开发SQL:
    MyBatis公共属性
        <!--配置别名-->
        <typeAliases>
            <typeAlias alias="Integer" type="java.lang.Integer" />
            <typeAlias alias="Long" type="java.lang.Long" />
            <typeAlias alias="HashMap" type="java.util.HashMap" />
            <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
            <typeAlias alias="ArrayList" type="java.util.ArrayList" />
            <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        </typeAliases>
        mybatis-config.xml ,主要配置常用的 typeAliases,设置类型别名为 Java 类型设置一个短的名字。只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。

UserMapper接口
    public interface UserMapper {       
        List<UserEntity> getAll();      
        UserEntity getOne(Long id);     
        void insert(UserEntity user);       
        void update(UserEntity user);       
        int delete(Long id);        
        List<UserEntity> getList(UserParam userParam);      
        Long getCount(UserParam userParam);
    }
    注意:这里的方法名需要和 XML 配置中的 id 属性一致,不然会找不到方法去对应执行的 SQL。
    
添加UserMapper映射文件
    <!--指明对应文件的 Mapper 类地址-->
    <mapper namespace="com.kid.mapper.UserMapper" >
    
        <!--
            配置表结构和类的对应关系:
                这里故意将类的两个字段和数据库字段设置为不一致,并且有一个使用枚举。
                使?用枚举有一个非常?大的优点,插?入此属性的数据会自动进?行校验,
                如果不是枚举的内容会报错。
        -->
        <resultMap id="BaseResultMap" type="com.kid.entity.UserEntity" >
            <id column="id" property="id" jdbcType="BIGINT" />
            <result column="userName" property="userName" jdbcType="VARCHAR" />
            <result column="passWord" property="passWord" jdbcType="VARCHAR" />
            <result column="user_sex" property="userSex" javaType="com.kid.enums.UserSexEnum"/>
            <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
        </resultMap>
        
        <sql id="Base_Column_List" >
            id, userName, passWord, user_sex, nick_name
        </sql>
    
        <sql id="Base_Where_List">
            <if test="userName != null  and userName != ‘‘">
                and userName = #{userName}
            </if>
            <if test="userSex != null and userSex != ‘‘">
                and user_sex = #{userSex}
            </if>
        </sql>
    
        <select id="getAll" resultMap="BaseResultMap"  >
           SELECT 
           <include refid="Base_Column_List" />
           FROM users
        </select>
    
        <select id="getList" resultMap="BaseResultMap" parameterType="com.kid.param.UserParam">
            select
            <include refid="Base_Column_List" />
            from users
            where 1=1
            <include refid="Base_Where_List" />
            order by id desc
            limit #{beginLine} , #{pageSize}
        </select>
    
        <select id="getCount" resultType="Integer" parameterType="com.kid.param.UserParam">
            select
            count(1)
            from users
            where 1=1
            <include refid="Base_Where_List" />
        </select>
    
        <select id="getOne" parameterType="Long" resultMap="BaseResultMap" >
            SELECT 
           <include refid="Base_Column_List" />
           FROM users
           WHERE id = #{id}
        </select>
    
        <insert id="insert" parameterType="com.kid.entity.UserEntity" >
           INSERT INTO 
                users
                (userName,passWord,user_sex) 
            VALUES
                (#{userName}, #{passWord}, #{userSex})
        </insert>
        
        <update id="update" parameterType="com.kid.entity.UserEntity" >
           UPDATE 
                users 
           SET 
            <if test="userName != null">userName = #{userName},</if>
            <if test="passWord != null">passWord = #{passWord},</if>
            nick_name = #{nickName}
           WHERE 
                id = #{id}
        </update>
        
        <delete id="delete" parameterType="Long" >
           DELETE FROM
                 users 
           WHERE 
                 id =#{id}
        </delete>
    </mapper>

以上是关于Spring Boot 集成 MyBatis的主要内容,如果未能解决你的问题,请参考以下文章

spring-boot学习之集成mybatis

Spring Boot集成 MyBatis 操作 MySQL 8

spring boot集成mybatis官方生成器

264.Spring Boot MyBatis集成MyBatis-Plus

263.Spring Boot MyBatis集成TkMybatis

Spring Boot集成Mybatis及通用Mapper