• spring boot -- 整合Mybatis


    前言

      在项目中,获取到数据库中的数据后,需要将其映射成class才能使用,一般的程序中都有上百个实体类,繁重且重复的赋值映射操作,是在让人不愉快。有没有一个东西可以自动帮我们处理实体类的映射操作,使我们的工作简化呢?

      现在市面上广泛使用两种解决方案

      1、Hibernate的 Spring Data Jpa

      2、Mybatis的:mybatis-spring-boot-starter

      它们的作用都是通过封装简化了开发人员对数据库的操作。本文主要讲的是Mybatis的使用,对Hibernate不做概述

    mybatis官网

      了解更多细节,可以前往mybatis官方文档

    使用mybatis与不使用mybatis的区别

      不使用mybatis

        我们对于executeQuery查询出来的数据,需要通过迭代ResultSet来读取,如果对象非常复杂,属性繁多,那么就需要定义一大堆的变量,重复使用一大堆方法(getInt、getString)

            Connection conn=  //...获取connection
            PreparedStatement ps = conn.prepareStatement("select * from user");
                ResultSet rs = ps.executeQuery();
                List<UserMap> list = new ArrayList<>();
                while (rs.next()) {
                    UserMap um = new UserMap();
                    um.id = rs.getInt("id");
                    um.account = rs.getString("account");
                    ...// 大量的赋值操作
                }

      使用mybatis

        只需要两步

          1、定义一个映射接口

    @Mapper 
    public interface Myb {
        
        @Select("SELECT * FROM user")
    List<UserMap> getAll();
      
    //实体类UserMap中的字段会自动被赋予,与sql语句查询结果相同列名的值,举例:UserMap中的存在属性字段id,那么会自动与sql执行结果中的id列的值进行绑定。当然也可以手动指定对应的列,详情请前往mybatis官方文档
    }

          2、使用

        @Autowired
        private Myb my; //无需手动实现Myb接口,Mybatis已经自动实现,所以自动装载后直接使用即可
    
        @RequestMapping("login")
        public Object index() {
            List<UserMap> listUser = my.getAll();//直接getAll方法,获取到通过sql select * from user查询到的数据映射结果
            return listUser;
        }

      总结

        不使用mybatis

          1、需要定义PreparedStatement 、Connection、ResultSet对象,并处理响应的异常

          2、需要迭代ResultSet对象,将executeQuery查询出来的数据手动转化车class对象,如果数据结构复杂,那么整个项目成百上千个Class映射,会产生大量重复劳动的工具量,以及大量重复代码

    如何使用mybatis

        mybatis的使用有两种方式,注解方式和xml方式

    =============注解方式====================

      1、下载依赖

         //mybatis没有集成jdbc,所以对不同数据库的链接,还是需要对应的库
         <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.26</version> </dependency>

        //mybatis     <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency>

      2、配置application.yml

    spring:
      datasource:
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/test?allowMultiQueries=true&autoReconnect=true&characterEncoding=utf-8
        username: root
        password: root

      3、定义Mapper

    @Mapper //表明此接口是一个mapper,加上此注解会自动被spring boot扫描到
    public interface Myb {
        //在接口中定义一个返回UserMap类型数据方法,会根据定义的数据类型,去映射数据
        @Select("SELECT * FROM user")
        List<UserMap> getAll();//定义执行sql,会将sql执行的结果映射到getAll()的return中
    }

         (1)也可以不使用@Mapper注解,在启动类上使用@MapperScan("com.example.mybitesstudy02.service"),指定扫描的包

    //@Mapper //去掉@Mapper
    public interface Myb {

      @Select("SELECT * FROM user") List<UserMap> getAll(); }
    @MapperScan("com.example.mybitesstudy02.service") //在启动类中指定扫描包
    @SpringBootApplication
    public class MybitesStudy02Application {
    
        public static void main(String[] args) {
            SpringApplication.run(MybitesStudy02Application.class, args);
        }
    
    }

      4、调用

    @RestController
    public class Index {
    
        @Autowiredprivate Myb my; //无需手动实现Myb接口,Mybatis已经自动实现,所以自动装载后直接使用即可
    
        @RequestMapping("login")
        public Object index() {
            List<UserMap> listUser = my.getAll();//直接getAll方法,获取到通过sql select * from user查询到的数据映射结果
            return listUser;
        }
    }

      (1)如果是使用@MapperScan指定扫描路劲的话,那么Autowired需要设置required=false

    @RestController
    public class Index {
    
        @Autowired(required = false) //使用@MapperScan无法在编译时注入my
        private Myb my; 
    
        @RequestMapping("login")
        public Object index() {
            List<UserMap> listUser = my.getAll();
            return listUser;
        }
    }

     

    =============xml方式====================

      因为依赖已经下载过了,所以我们直接跳过

      1.修改application.yml

      ...//旧的配置
        
    #新增配置项
    mybatis:
      # config-location: classpath:mybatis/mybatis.config.xml #指定Mybatis配置文件放置目录,学习阶段可以先不管他,
      mapper-locations: classpath:mybatis/sql/*Map.xml #指定映射xml文件放置目录,以及匹配规则

      2.在classpath:mybatis/sql目录下编写映射xml文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!--这个是必须要的 对xml文档进行标注功能-->
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <!--mapper 的namespace 要与你的映射接口的完整包名一致 -->
    <mapper namespace="com.example.mybitesstudy02.service.Myb">
    
        <!--    定义一个接收的数据对象-->
        <!--    id 表明后续xml中使用的id-->
        <!--    type 为对应实体类的完整包名-->
        <resultMap id="UserMapXml" type="com.example.mybitesstudy02.service.UserMap">
            <id column="id" property="id"/>
            <result column="account" property="account"/>
        </resultMap>
    
        <!--    定义一个查询语句-->
        <!--    id 必须要与映射接口com.example.mybitesstudy02.service.Myb中的方法名一致,下例表示映射到com.example.mybitesstudy02.service.Myb 
        接口上的 getAll方法,返回一个id为UserMapXml的<resultMap>作为数据类型-->
        <select id="getAll" resultMap="UserMapXml">
            SELECT *
            FROM user
        </select>
    </mapper>

      3、改造com.example.mybitesstudy02.service.Myb接口

    package com.example.mybitesstudy02.service;
    import org.apache.ibatis.annotations.Mapper;
    import java.util.List;
    
    @Mapper //不使用@Mapper的话,可以在启动类使用@MapperScan指定扫描
    public interface Myb {
    //@Select("select * from user) 此注解可以不用了 List
    <UserMap> getAll(); }

      4、造就使用即可

    @RestController
    public class Index {
    
        @Autowired //自动装载
        private Myb my;
    
        @RequestMapping("login")
        public Object index() {
            List<UserMap> um = my.getAll();
            return um;
        }
    }

     一些问题

      BindingException 异常

        原因:

          1.mapper.xml文件的namespace与mapper接口完整包路径不一致

          解决方案:

            参照xml方式使用mybatis的第二步

          2.mapper.xml文件中的sql语句所在标签的id属性与mapper接口中的方法名称不一致

          解决方案:

            参照xml方式使用mybatis的第二步

          3.xml资源未被扫描到

          解决方案:

            修改pom.xml的build,使其能够扫描到Mybatis的映射xml放置的位置

     <build>
            <resources>
                <resource>
                    <directory>src/main/resources</directory>
                </resource>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.xml</include>
                    </includes>
                </resource>
            </resources>
    
        </build>
  • 相关阅读:
    一道C#基础题,看你能多长时间做出来?
    终于能在这里安家了
    你知道返回多少吗?(使用Math类)
    关于implicit和explicit关键词的用法
    关于基类与派生类的学习
    js控制输入框
    Oracle 动态SQL返回单条结果和结果集 转帖
    定时器:.NET Framework类库中的Timer类比较(转帖)
    UVA10020 Minimal coverage
    UVA1388 Graveyard
  • 原文地址:https://www.cnblogs.com/wrhbk/p/15242973.html
Copyright © 2020-2023  润新知