三、SpringBoot整合MyBatis的两种方式

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/weixin_38323872/article/details/98752012

概述

目前行业内,常见的持久层框架有两种:Hibernate 和 MyBatis 。两者皆为持久层框架发展史中的佼佼者,且各有千秋。具体两者的对比,会在以后我的另一篇文章中介绍,敬请期待…

MyBatis的发育史

  • 前期:各种配置文件繁琐,开发流程不够简化。
  • 中期:配合generator 使用,可以自动生成entity 以及 Dao层接口及xml文件,但是配置依旧繁琐。
  • 后期:经过官方团队的优化,支持了基于注解的方式开发,同时也能自动化管理配置文件了(优秀!)
  • 大后期:这里就期待一下吧,大家可以自己发挥想象,也欢迎大家联系我一起探讨任何编程方面的问题。我相信它一定是朝着市场需求的方向奔的,官方放出新特性之时,就是这里增加新博文之日,哈哈哈…

整合Mybatis的两种方式

一、 基于注解方式

  1. 修改pom文件,增加MyBatis、MySQL驱动以及Druid连接池依赖包,具体pom文件如下:
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 集成MyBatis启动类 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.0.0</version>
        </dependency>

        <!-- 添加mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 添加mysql的连接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
  1. 修改yml/properties配置文件,配置数据源信息,具体配置如下:
spring:
  #数据路基本信息配置
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345678
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
  1. 建表,这里以UserInfo为例,建表语句如下:
    -- ----------------------------
    -- Table structure for user_info
    -- ----------------------------
    DROP TABLE IF EXISTS `user_info`;
    CREATE TABLE `user_info` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
      `address` varchar(255) DEFAULT NULL,
      `add_time` timestamp NULL DEFAULT NULL,
      PRIMARY KEY (`id`) USING BTREE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    SET FOREIGN_KEY_CHECKS = 1;
  1. 创建UserInfo实体类,代码如下:
/**
 * FileName: UserInfo
 * Author:   RollerRunning
 * Date:     2019/8/6 6:02 PM
 * Description:
 */
public class UserInfo implements Serializable {
    private Integer id;

    private String userName;

    private String address;

    private Date addTime;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
    ......
}
  1. 开发Dao层Mapper接口,具体代码如下:
package com.example.demo.helloworld.dao;

import com.example.demo.helloworld.entity.UserInfo;
import org.apache.ibatis.annotations.*;

/**
 * FileName: UserDao
 * Author:   RollerRunning
 * Date:     2019/8/6 6:05 PM
 * Description:
 */
@Mapper
public interface UserDao {
    /**
     * @param userInfo
     * @return int
     * @description 新增用户
     **/
    @Insert("insert into user_info values(#{id}, #{userName}, #{address}, #{addTime})")
    int addUserInfo(UserInfo userInfo);

    /**
     * @param userInfo
     * @return int
     * @description 修改用户
     **/
    @Update("update user_info set user_name = #{userName}, address = #{address}, add_time = #{addTime} where id = #{id}")
    int update(UserInfo userInfo);

    /**
     * @param id
     * @return int
     * @description 删除用户
     **/
    @Delete("delete from user_info where id = #{id}")
    int delete(int id);

    /**
     * @param
     * @return java.util.List<com.example.demo.helloworld.entity.UserInfo>
     * @description 查询用户
     **/
    @Select("select id, user_name userName, address, add_time addTime from user_info where id = #{id}")
    UserInfo selectUser(Integer id);
}

:在这里我只是介绍了最基本的CRUD操作,还有相关的动态SQL相关知识这里就不多介绍了,因为我个人不偏好基于注解的这种方式。在这里推荐一篇文章,大家可以作为参考
6. 开发Service接口及其实现类,代码如下:

package com.example.demo.helloworld.service;

import com.example.demo.helloworld.entity.UserInfo;

import java.util.Date;

/**
 * FileName: UserService
 * Author:   zhengwei
 * Date:     2019/8/6 6:45 PM
 * Description:
 */
public interface UserService {
    /**
     * @param userName, address, addTime
     * @return int
     * @description 新增用户
     **/
    void addUser(String userName, String address, Date addTime);
    /**
     * @param id, userName, address, addTime
     * @return int
     * @description 修改用户
     **/
    void updateUser(Integer id, String userName, String address, Date addTime);

    /**
     * @param id
     * @return int
     * @description 删除用户
     **/
    void deleteUser(Integer id);

    /**
     * @param id
     * @return UserInfo
     * @description 查询用户
     **/
    UserInfo selectUser(Integer id);
}

package com.example.demo.helloworld.service.impl;

import com.example.demo.helloworld.dao.UserDao;
import com.example.demo.helloworld.entity.UserInfo;
import com.example.demo.helloworld.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * FileName: UserService
 * Author:   zhengwei
 * Date:     2019/8/6 6:28 PM
 * Description:
 */
@Service("userService")
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    /**
     * @param userName, address, addTime
     * @return void
     * @description 新增用户信息
     **/
    @Override
    public void addUser(String userName, String address, Date addTime) {
        //接收到用户信息,调用mapper
        UserInfo userInfo = new UserInfo();
        userInfo.setUserName(userName);
        userInfo.setAddress(address);
        userInfo.setAddTime(addTime);
        int add = userDao.addUserInfo(userInfo);
        System.out.println("插入用户信息返回的结果:" + add);
    }

    /**
     * @param id, userName, address, addTime
     * @return int
     * @description 修改用户
     **/
    @Override
    public void updateUser(Integer id, String userName, String address, Date addTime) {
        //接收到用户信息,调用mapper
        UserInfo userInfo = new UserInfo();
        userInfo.setId(id);
        userInfo.setUserName(userName);
        userInfo.setAddress(address);
        userInfo.setAddTime(addTime);
        int update = userDao.update(userInfo);
        System.out.println("更新用户信息返回的结果:" + update);
    }

    /**
     * @param id
     * @return
     * @description 删除用户
     **/
    @Override
    public void deleteUser(Integer id) {
        int delete = userDao.delete(id);
        System.out.println("更新用户信息返回的结果:" + delete);
    }

    /**
     * @param id
     * @return int
     * @description 查询用户
     **/
    @Override
    public UserInfo selectUser(Integer id) {
        UserInfo userInfo = userDao.selectUser(id);
        System.out.println("更新用户信息返回的结果:" + userInfo);
        return userInfo;
    }
}

  1. 编写Controller类,代码如下:
package com.example.demo.helloworld.controller;

import com.example.demo.helloworld.entity.UserInfo;
import com.example.demo.helloworld.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * FileName: HelloWorldController
 * Author:   RollerRunning
 */
@RestController
public class HelloWorldController {
    @Autowired
    private UserService userService;

    /**
     * @param userName, address, addTime
     * @return void
     * @description 新增用户信息
     **/
    @RequestMapping("add")
    public String hello(String userName, String address) {
        System.out.println("接收到前端传递的参数信息,userName=" + userName + ", address=" + address);
        userService.addUser(userName, address, new Date());
        return "success";
    }

    /**
     * @param id, userName, address, addTime
     * @return int
     * @description 修改用户
     **/
    @RequestMapping("update")
    public String update(Integer id, String userName, String address) {
        System.out.println("接收到前端传递的参数信息,id=" + id + ", userName=" + userName + ", address=" + address);
        userService.updateUser(id, userName, address, new Date());
        return "success";
    }

    /**
     * @param id
     * @return int
     * @description 删除用户
     **/
    @RequestMapping("delete")
    public String delete(Integer id) {
        System.out.println("接收到前端传递的参数信息,id=" + id);
        userService.deleteUser(id);
        return "success";
    }

    /**
     * @param id
     * @return int
     * @description 查询用户
     **/
    @RequestMapping("select")
    public UserInfo select(Integer id) {
        System.out.println("接收到前端传递的参数信息,id=" + id);
        UserInfo userInfo = userService.selectUser(id);
        return userInfo;
    }

}

以上就是本次Demo的全部代码,大家可以通过PostMan或者浏览器测试接口的正确性,如果有问题欢迎来撕本猿。

二、 基于配置文件方式

  1. 修改POM文件,内容与注解方式相同,这里不再赘述。
  2. 创建xxxMapper.xml的文件路径,我这里是放在了resources/mapper/xxxMapper.xml的路径
    在这里插入图片描述
  3. 配置yml文件,代码如下:
#测试环境端口
server:
  port: 8082
spring:
  #数据路基本信息配置
  datasource:
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull
    username: root
    password: 12345678
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
#MyBatis相关配置
mybatis:
  #指定映射文件的路径,这里我是放在了resources/mapper/xxxMapper.xml,其中*Mapper.xml使用通配符,扫描加载所有的Mapper文件
  mapper-locations: classpath:mapper/*Mapper.xml
  configuration:
    #开启懒加载
    lazy-loading-enabled: true
    #设置单个SQLSession查询的超时时间
    default-statement-timeout: 3
    .......

:mybatis这里有很多配置,就不在demo中一一列举了,大家可以根据自己的需要,查阅官方文档来选择最适合自己项目优化目的的配置。大家也可以尝试把mybatis的配置项单独提出来一个文件,算是一个练习了。
4. 书写xxxxMapper.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.example.demo.helloworld.dao.UserMapper">

    <!--自定义数据库字段与实体类属性的映射关系-->
    <resultMap id="userResultMap" type="com.example.demo.helloworld.entity.UserInfo">
        <result column="id" property="id" jdbcType="INTEGER"/>
        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
        <result column="address" property="address" jdbcType="VARCHAR"/>
        <result column="add_time" property="addTime" jdbcType="TIMESTAMP"/>
    </resultMap>

    <!--新增用户-->
    <insert id="addUserInfo" parameterType="com.example.demo.helloworld.entity.UserInfo">
        insert into user_info values(
          #{id},
          #{userName},
          #{address},
          #{addTime}
        )
    </insert>

    <!--更新用户-->
    <update id="update" parameterType="com.example.demo.helloworld.entity.UserInfo" >
        update user_info
        <set>
            <if test="userName != null">
                user_name=#{userName},
            </if>
            <if test="address != null">
                address=#{address},
            </if>
            <if test="addTime != null">
                add_time=#{addTime},
            </if>
        </set>
        <where>
            <if test="userId != null">
               user_id=#{userId}
            </if>
        </where>
    </update>

    <!--删除用户-->
    <delete id="delete" parameterType="Integer">
        delete from user_info where id=#{id}
    </delete>

    <!--查询用户-->
    <select id="selectUser" parameterType="Integer" resultMap="userResultMap">
        select id, user_name, address, add_time from user_info where id=#{id}
    </select>
</mapper>
  1. service层、controller层、entity等均与基于注解的方式相同,见上文即可。
  2. 使用测接口神器PostMan测试,完成!

总结

综合前面两种整合方式,各有千秋。就我个人是偏好第二种的,且是最常用到的,感觉这种写法,遇到长动态SQL不会显得代码很臃肿,也符合各司其职的思想。接口就做接口该做的,xml就负责SQL以及字段映射等操作。个人拙见,还欢迎各路大神来指教,感谢!

  • 参考文献:
    http://www.mybatis.cn/category/relation/
    https://docs.spring.io/spring-boot/docs/current/reference/html/index.html
  • 源码地址:
    https://github.com/zheng-weiwei/public/tree/master/mybatis ----基于注解
    https://github.com/zheng-weiwei/public/tree/master/mybatis-xml ----基于XML

感谢,请多多指教!

猜你喜欢

转载自blog.csdn.net/weixin_38323872/article/details/98752012