Springboot项目集成Mybatis

Springboot作为业界最为流行的微服务架构框架,对数据的操作是最基本的需求。

1. 数据操作方案对比

传统JDBC方式操作数据库,配置参数,获取执行结果,然后将结果填充到接口bean,及其繁琐耗时,早已满足不了解放程序员生产力的要求。
JDBCTemplate则是JDBC的一个改进版,像基本的
而Hibernate使得程序员可以像开发业务模块一样,直接写代码来操作数据库,理论上可以完全不懂SQL,因为这部分工作它替我们做了。但是,最强大的之处也往往是最薄弱之处。正因为转化成SQL这个工作hibernate替我们做了,这是个黑箱,我们写代码的时候,往往不知道它会转成什么样子,感觉不可控,尤其是出了问题调试的时候。用Hibernate学习成本也高,要学习HQL(Hibernate Query Language)。
Mybatis就不一样了。它一款优秀的持久层框架,支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集, 可以使用简单的 Xml 或注解来配置。灵活而不是强大,所以得到了越来越多互联网公司的青睐。

2. Springboot集成Mybatis步骤

2.1 maven pom文件引入配置

    <properties>
        <java.version>1.8</java.version>
        <mysql.version>5.1.45</mysql.version>
        <mybatis.version>1.3.2</mybatis.version>
        <druid.version>1.1.17</druid.version>
    </properties>

        <!-- MySql -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>

        <!--mybatis stater-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>${mybatis.version}</version>
        </dependency>

        <!--druid stater-->
        <dependency>
           <groupId>com.alibaba</groupId>
           <artifactId>druid-spring-boot-starter</artifactId>
           <version>${druid.version}</version>
        </dependency>

2.2 配置数据库连接
设置application.yml文件,添加数据库连接池配置和mybatis配置。这里采用的阿里的druid连接池,更新详细的配置可以参考阿里的github,里面介绍了更详细的属性含义,以及多数据源的配置方式。

spring:
  datasource:
    url: jdbc:mysql://192.168.245.101:3306/studyDB?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 921230
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      initial-size: 8
      min-idle: 1
      max-active: 20
      max-wait: 60000
      time-between-eviction-runsMillis: 60000
      min-evictable-idle-timeMillis: 300000
      validation-query: select 'x' FROM DUAL
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      pool-prepared-statements: true
      max-open-prepared-statements: 20
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat
      connection-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
      use-global-data-source-stat: true

#mybatis
mybatis:
  mapper-locations: classpath:/mapper/*Mapper.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.qinghaihu.springbootmybatis.entity

2.3 核心代码编写

数据源为一张系统用户信息表sys_user,其定义如下,我们要通过mybatis实现对sys_user的增删改查。

/*
 Navicat Premium Data Transfer

 Source Server         : studyDb
 Source Server Type    : MySQL
 Source Server Version : 50725
 Source Host           : 192.168.245.101:3306
 Source Schema         : studyDB

 Target Server Type    : MySQL
 Target Server Version : 50725
 File Encoding         : 65001

 Date: 28/03/2020 15:20:01
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for sys_user
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` varchar(50) NOT NULL COMMENT '主键',
  `userName` varchar(50) NOT NULL COMMENT '用户名',
  `password` varchar(50) NOT NULL COMMENT '密码',
  `userState` int(2) NOT NULL DEFAULT '1' COMMENT '用户状态,1-启用,-1禁用',
  `createTime` datetime DEFAULT NULL COMMENT '创建时间',
  `userDesc` varchar(300) DEFAULT NULL COMMENT '描述',
  `userImg` varchar(300) DEFAULT '/app/img/user2-160x160.jpg' COMMENT '头像',
  `deptId` varchar(50) DEFAULT NULL COMMENT '部门主键',
  PRIMARY KEY (`id`),
  UNIQUE KEY `username_unique_index` (`userName`(5)) USING BTREE COMMENT '用户名唯一索引'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用户表';

-- ----------------------------
-- Records of sys_user
-- ----------------------------
BEGIN;
INSERT INTO `sys_user` VALUES ('1', 'admin', '999999', 1, '2019-11-03 11:08:28', '超级管理员,具有最高权限', '/app/img/user2-160x160.jpg', '111');
INSERT INTO `sys_user` VALUES ('2', 'tenant', '000000', 1, '2019-11-03 11:51:36', '租客公用账户', '/app/img/user2-160x160.jpg', '222');
INSERT INTO `sys_user` VALUES ('3', 'zhanglianzhong', '222222', 1, '2019-11-03 11:43:36', '系统运维人员', '/app/img/user2-160x160.jpg', '333');
INSERT INTO `sys_user` VALUES ('4', 'guoyunping', '333333', 1, '2019-11-03 11:09:43', '二房东管理用户', '/app/img/user2-160x160.jpg', '444');
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

2.3.1 entity实体类

编写操作表对应的实体bean类,字段命名建议采用驼峰形式。bean字段的set和get方法可以使用lombok来简化编码。

import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@NoArgsConstructor
public class SysUser {

    //用户id
    private String id;

    //用户名
    private String username;

    //密码
    private String password;

    //用户状态
    private Integer userstate;

    //创建时间
    private Date createtime;

    //用户描述
    private String userdesc;

    //用户图像
    private String userimg;

    //所属部门id
    private String deptid;


}

2.3.2 dao接口类

需要编写一个dao接口类,用于描述dao层对外提供的接口方法。用mybatis的@Mapper进行注解。

import com.qinghaihu.springbootmybatis.entity.SysUser;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

@Mapper
@Repository
public interface SysUserDao {
   
    int insert(SysUser record);

    SysUser selectByPrimaryKey(String id);

    int updateByPrimaryKey(SysUser record);

    int deleteByPrimaryKey(String id);
}

2.3.3 编写数据操作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.qinghaihu.springbootmybatis.dao.SysUserDao">
  <resultMap id="BaseResultMap" type="com.qinghaihu.springbootmybatis.entity.SysUser">
    <id column="id" jdbcType="VARCHAR" property="id" />
    <result column="userName" jdbcType="VARCHAR" property="username" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="userState" jdbcType="INTEGER" property="userstate" />
    <result column="createTime" jdbcType="TIMESTAMP" property="createtime" />
    <result column="userDesc" jdbcType="VARCHAR" property="userdesc" />
    <result column="userImg" jdbcType="VARCHAR" property="userimg" />
    <result column="deptId" jdbcType="VARCHAR" property="deptid" />
  </resultMap>
  
  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    from sys_user
    where id = #{id,jdbcType=VARCHAR}
  </select>
  
  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
    delete from sys_user
    where id = #{id,jdbcType=VARCHAR}
  </delete>
  
  <insert id="insert" parameterType="com.qinghaihu.springbootmybatis.entity.SysUser">
    insert into sys_user (id, userName, password, 
      userState, createTime, userDesc, 
      userImg, deptId)
    values (#{id,jdbcType=VARCHAR}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{userstate,jdbcType=INTEGER}, #{createtime,jdbcType=TIMESTAMP}, #{userdesc,jdbcType=VARCHAR}, 
      #{userimg,jdbcType=VARCHAR}, #{deptid,jdbcType=VARCHAR})
  </insert>

  
  <update id="updateByPrimaryKey" parameterType="com.qinghaihu.springbootmybatis.entity.SysUser">
    update sys_user
    set userName = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      userState = #{userstate,jdbcType=INTEGER},
      createTime = #{createtime,jdbcType=TIMESTAMP},
      userDesc = #{userdesc,jdbcType=VARCHAR},
      userImg = #{userimg,jdbcType=VARCHAR},
      deptId = #{deptid,jdbcType=VARCHAR}
    where id = #{id,jdbcType=VARCHAR}
  </update>
  
</mapper>

用insert、delete、update和select表征增删改查基本操作,reslutMap描述了JDBC数据类型和JAVA类型映射关系。parameterType为输入参数类型,#{xxxx}用于引用输入参数值。
mapper.xml文件与dao接口文件是相互绑定文件,为了实现关系绑定,mybatis有如下约定:

1 xml文件中的namespace为完整的dao全路径接口名
2 dao接口的方法名对应mapper.xml中的sql id
3 dao接口方法入参和出参与mapper.xml须一致

service类

服务层使用@Autowired注解自动注入dao接口,对外提供增删改查的数据操作服务。

@Service
public class SysUserService {
    
    @Autowired
    SysUserDao sysUserDao;
    
    public SysUser selectById(String id){
       return sysUserDao.selectByPrimaryKey(id);
    }
    
    
    public  boolean updateUserInfo(SysUser sysUser){
        int count = sysUserDao.updateByPrimaryKey(sysUser);
        if(count>0){
            return true;
        }else {
            return false;
        }
    }
    
    
    public boolean deleteById(String id){
        int count = sysUserDao.deleteByPrimaryKey(id);
        if(count>0){
            return true;
        }else {
            return  false;
        }
    }
    
    public boolean insertUserInfo(SysUser sysUser){
        int count = sysUserDao.insert(sysUser);
        if(count>0){
            return true;
        }else {
            return  false;
        } 
    }
}

3 单元测试

编写Service层的单元测试案例,测试服务正确性。

package com.qinghaihu.springbootmybatis;


import com.qinghaihu.springbootmybatis.entity.SysUser;
import com.qinghaihu.springbootmybatis.service.SysUserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;

@SpringBootTest
class SpringbootMybatisApplicationTests {

    @Autowired
    SysUserService sysUserService;


    @Test
    public void testInsert(){
        SysUser sysUser = new SysUser();
        sysUser.setId("5");
        sysUser.setUsername("qinghaihu");
        sysUser.setPassword("88888888");
        sysUser.setCreatetime(new Date());
        sysUser.setUserdesc("奔跑吧程序猿");
        sysUser.setUserimg("/user/images/qinghaihu.jpg");
        sysUser.setUserstate(0);

        boolean insertResult = sysUserService.insertUserInfo(sysUser);
        if(insertResult){
            System.out.println("成功插入用户记录!");
        }else {
            System.out.println("插入用户记录失败");
        }
    }

    @Test
    public  void testSelect(){
        String id = "5";
        SysUser sysUser = sysUserService.selectById(id);
        System.out.println(sysUser);
    }

    @Test
    public void testUpdate() {
        SysUser sysUser = new SysUser();
        sysUser.setId("5");
        sysUser.setUsername("qinghaihu");
        sysUser.setPassword("88889999");
        sysUser.setCreatetime(new Date());
        sysUser.setUserdesc("奔跑吧程序猿");
        sysUser.setUserimg("/user/images/qinghaihu.jpg");
        sysUser.setUserstate(0);

        boolean updateResult = sysUserService.updateUserInfo(sysUser);
        if (updateResult) {
            System.out.println("成功修改用户信息!");
        } else {
            System.out.println("修改用户信息失败");
        }

    }

    @Test
    public void testdelete() {
        String id = "5";
        boolean deleteResult = sysUserService.deleteById(id);

        if (deleteResult) {
            System.out.println("成功删除用户信息!");
        } else {
            System.out.println("删除用户信息失败");
        }
    }


}

执行单元测试后的结果


unit test.png

4 项目源码

https://github.com/zhanglianzhong/sprinboot-tech.git

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,755评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,369评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,799评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,910评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,096评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,159评论 3 411
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,917评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,360评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,673评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,814评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,509评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,156评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,123评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,641评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,728评论 2 351

推荐阅读更多精彩内容