前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 整合Mybatis

Spring Boot 整合Mybatis

作者头像
LCyee
发布2020-08-05 17:17:02
4170
发布2020-08-05 17:17:02
举报

一、构建流程

0x01 引入启动器

  • Mysql 驱动
  • Mybatis 启动器
<!--Mybatis配置-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.1</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

0x02 配置数据源

  • 配置 Mysql 连接信息
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/friday?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
    username: root
    password: 123123
    platform: mysql

0x03 配置Mybatis

  • java bean 映射数据表
  • Mapper 定义 sql 行为
# Mybatis配置
mybatis:
  type-aliases-package: com.springbootstudy.first_springboot.model  # 实体pojo的储存路径,项目包名.model
  mapper-locations: classpath:/mybatis-mappers/*  # mapper 配置文件路径
  configuration:
    mapUnderscoreToCamelCase: true # 驼峰转换:将名字从abc_edf 转换微abcEdf

0x04 编写实体类

model 包中建立BaseEntity

@Data
public abstract class BaseEntity<ID extends Serializable> implements Serializable {
    private static final long serialVersionUID = 8925514045582235838L;
    private ID id;
    private Date createTime = new Date();
    @JsonFormat(pattern = "yyyy-MM-dd  HH:mm:ss")
    private Date updateTime = new Date();

}

建立SysUser

@Data
public class SysUser extends BaseEntity<Long> {
    private static final long serialVersionUID = -6525908145032868837L;
    private String username;
    private String password;
    private String nickname;
    private String headImgUrl;
    private String phone;
    private String telephone;
    private String email;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private Integer sex;
    private Integer status;
    private String intro;
}

0x05 编写mapper映射接口

  • 对应我们的 mapper 行为信息

model 下创建 BaseEntity

@Data
public abstract class BaseEntity<ID extends Serializable> implements Serializable {
    private static final long serialVersionUID = 8925514045582235838L;
    private ID id;
    private Date createTime = new Date();
    @JsonFormat(pattern = "yyyy-MM-dd  HH:mm:ss")
    private Date updateTime = new Date();

}

model 下创建 SysUser

@Data
public class SysUser extends BaseEntity<Long> {
    private static final long serialVersionUID = -6525908145032868837L;
    private String username;
    private String password;
    private String nickname;
    private String headImgUrl;
    private String phone;
    private String telephone;
    private String email;

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private Integer sex;
    private Integer status;
    private String intro;
}

在dao下创建UserDao

@Mapper
public interface UserDao {
    @Select("select * from sys_user t where t.username = #{username}")
    SysUser getUser(String username);
}

@Mapper注解

  • 为了把 mapper 这个DAO交给 Spring IOC 容器管理
  • 为了不再写 mapper 映射文件
  • 添加 @Mapper 注解的接口生成一个实现类。

@MapperScan注解

可以直接在Springboot的主入口处添加 @MapperScan 扫描指定路径的mapper,就不用在每个dao上都加一个@mapper 注解了。

@MapperScan(basePackages = "com.springboot.study.mapper")

0x06 编写测试代码

@SpringBootTest
class FirstSpringbootApplicationTests {

    //@Autowired 在测试单元中使用Autowried会报错,所以这里使用resource代替
    @Resource
    UserDao userDao;

    @Test
    void contextLoads() {
        SysUser info = userDao.getUser("admin");
        System.out.println(info);
    }
}

测试结果

0x08 sql数据

-- ----------------------------
-- Table structure for `sys_user`
-- ----------------------------
DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) NOT NULL,
  `password` varchar(60) NOT NULL,
  `nickname` varchar(255) DEFAULT NULL,
  `headImgUrl` varchar(255) DEFAULT NULL,
  `phone` varchar(11) DEFAULT NULL,
  `telephone` varchar(30) DEFAULT NULL,
  `email` varchar(50) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `sex` tinyint(1) DEFAULT NULL,
  `status` tinyint(1) NOT NULL DEFAULT '1',
  `createTime` datetime NOT NULL,
  `updateTime` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=45 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of sys_user
-- ----------------------------
INSERT INTO `sys_user` VALUES ('1', 'admin', '$2a$10$DFIwAy//Ol3X6Q1e5CEue.FfUnJ5Fj709z9oY1pwCWzpca.SpYs72', '管理员', null, null, '158784879852', '12@qq.com', null, null, '1', '2019-04-08 00:20:51', '2019-04-08 00:20:51');
INSERT INTO `sys_user` VALUES ('2', 'user', '$2a$10$ILWAB4ZOoRr2pXqarliI6uAuL7Q/7dAMTpWO9p7dyVSHHO7zQMTeW', '用户', null, null, '1111111111', '11@qq.com', '2019-03-31', null, '1', '2019-04-09 06:44:50', '2019-04-09 06:44:50');
INSERT INTO `sys_user` VALUES ('3', 'alex', '534b44a19bf18d20b71ecc4eb77c572f', '讲师', null, '', '13245698712', 'alex@qq.com', '2019-03-31', '1', '1', '2019-03-27 02:27:35', '2019-04-09 07:57:17');
INSERT INTO `sys_user` VALUES ('18', 'user1', '96e79218965eb72c92a549dd5a330112', '111', null, null, '123455432123', '134@qq.com', '2019-05-12', null, '1', '2019-05-14 04:44:22', '2019-05-14 04:44:22');

二、整合Druid连接池

什么是连接池?

连接池技术技术会预先建立多个数据库连接对象,然后将连接对象保存到连接池中,当客户请求到来时,从池中取出一个连接对象为客户服务,当请求完成后,客户程序调用close()方法,将连接对象放回池中。

连接池比较

连接池配置

配置依赖

<!--Druid连接池-->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>

在spring.datasource下配置以下信息

# 初始化大小,最小,最大
initialSize: 1
minIdle: 3
maxActive: 20
# 配置获取连接等待超时的时间
maxWait: 60000
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
timeBetweenEvictionRunsMillis: 60000
# 配置一个连接在池中最小生存的时间,单位是毫秒
minEvictableIdleTimeMillis: 30000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
# 是否缓存preparedStatement,打开PSCache,并且指定每个连接上PSCache的大小。官方建议MySQL下建议关闭,如果用SQL防火墙 建议打开
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20

创建config包,新建DruidConfig.java

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return new DruidDataSource();
    }
}

运行测试单元是否正常输出。

三、注解方式进行CRUD

@Setect注解

使用@Result注解定义字段别名

@Results(
    @Result(property = "userName", column = "username"),
    @Result(property = "passWord", column = "password")
)

propertycolumn 分别表示本地pojo和数据库表中字段的对应。

@Insert注解

返回自增主键,使用 @Option

@Options(useGeneratedKeys = true, keyProperty = "id")

返回非自增主键,使用 @SelectKey

@SelectKey(statement = "SELECT LASST_INSERT_ID()", keyProperty = "主键名", resultType = Long.class, before = false)

案例

@Mapper
public interface UserDao {

    // 根据用户名获取用户信息
    @Results(
            @Result(property = "username", column = "username")
    )
    @Select("select * from sys_user t where t.username = #{username}")
    SysUser getUser(String username);

    //删除指定id的用户信息
    @Delete("delete from sys_user where id = #{id}")
    int deleteUser(Long id);

    //插入用户信息
    @Options(useGeneratedKeys = true, keyProperty = "id")
    @Insert("insert into sys_user(username, password, nickname, headImgUrl, phone, telephone, email, birthday, sex, status, createTime, updateTime) values(#{username}, #{password}, #{nickname}, #{headImgUrl}, #{phone}, #{telephone}, #{email}, #{birthday}, #{sex}, #{status}, now(), now())")
    int save(SysUser sysUser);

    //根据用户id获取信息
    @Select("select * from sys_user where id = #{id}")
    SysUser getById(Long id);

}

四、使用配置方式CRUD

官方文档: http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html

注解+xml的编码步骤

在通常的情况下,一些简单的sql操作我们都使用注解方式进行,较为复杂的一些操作我们使用xml配置进行,因为xml配置更便于后期的维护。

  • 编写抽象的方法
  • 配置xml扫描路径
  • 编写mapper.xml

编写抽象接口

//更新用户信息
int updateUser(SysUser user);

配置xml扫描路径

# Mybatis配置
mybatis:
  type-aliases-package: com.springbootstudy.first_springboot.model  # 实体pojo的储存路径,项目包名.model
  mapper-locations: classpath:/mybatis-mappers/*  # mapper 配置文件路径
  configuration:
    mapUnderscoreToCamelCase: true # 驼峰转换;将名字从abc_edf 转换微AbcEdf

在项目resources 目录下新建mybatis-mappers目录,编写mapper.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.sxbang.friday.dao.UserDao">
   
   <update id="updateUser">
      update sys_user t
      <set>
         <if test="username != null">
            username = #{username},
         </if>
         <if test="nickname != null">
            nickname = #{nickname},
         </if>
         <if test="headImgUrl != null">
            headImgUrl = #{headImgUrl},
         </if>
         <if test="phone != null">
            phone = #{phone},
         </if>
         <if test="telephone != null">
            telephone = #{telephone},
         </if>
         <if test="email != null">
            email = #{email},
         </if>
         <if test="birthday != null">
            birthday = #{birthday},
         </if>
         <if test="sex != null">
            sex = #{sex},
         </if>
         <if test="status != null">
            status = #{status},
         </if>
         updateTime = #{updateTime}
      </set>
      where t.id = #{id}
   </update>
</mapper>

五、单元测试

  • 单元测试 是测试应用程序的功能是否能按需要正常运行。
  • 单元测试 是一个对单一实体(类或方法)的测试
  • 单元测试 是软件公司提高产品质量、满足客户需求的重要环节。

六、代码生成插件

在IDEA中安装 GenerateAllSetter 插件,在创建实体类时可以自动为我们生成对象的 setter 方法,例如

TbUser tbUser = new TbUser();
tbUser.setUsername("Lusifer");
tbUser.setPassword("123456");
tbUser.setPhone("15888888888");
tbUser.setEmail("topsale@vip.qq.com");
tbUser.setCreated(new Date());
tbUser.setUpdated(new Date());
tbUserMapper.insert(tbUser);

案例代码如下

import java.util.Date;
import com.funtl.hello.spring.boot.domain.TbUser;
import com.funtl.hello.spring.boot.mapper.TbUserMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
@Rollback
public class HelloSpringBootApplicationTests {
    /**
     * 注入 DAO
     */
    @Autowired
    private TbUserMapper tbUserMapper;
    /**
     * 查询
     */
    @Test
    public void testSelectAll() {
        List<TbUser> tbUsers = tbUserMapper.selectAll();
        tbUsers.forEach(tbUser -> {
            System.out.println(tbUser);
        });
    }
    /**
     * 条件查询
     */
    @Test
    public void testSelectCondition() {
        Example example = new Example(TbUser.class);
        example.createCriteria().andEqualTo("username", "zhangsan");
        List<TbUser> tbUsers = tbUserMapper.selectByExample(example);
        tbUsers.forEach(tbUser -> {
            System.out.println(tbUser);
        });
    }
    /**
     * 新增
     */
    @Test
    public void testInsert() {
        TbUser tbUser = new TbUser();
        tbUser.setUsername("Lusifer");
        tbUser.setPassword("123456");
        tbUser.setPhone("15888888888");
        tbUser.setEmail("topsale@vip.qq.com");
        tbUser.setCreated(new Date());
        tbUser.setUpdated(new Date());
        tbUserMapper.insert(tbUser);
    }
    /**
     * 更新
     */
    @Test
    public void testUpdate() {
        TbUser tbUser = tbUserMapper.selectByPrimaryKey(37L);
        tbUser.setUsername("Happy");
        tbUserMapper.updateByPrimaryKey(tbUser);
    }
    /**
     * 修改
     */
    @Test
    public void testDelete() {
        tbUserMapper.deleteByPrimaryKey(37L);
    }
    /**
     * 分页
     */
    @Test
    public void testPage() {
        Example example = new Example(TbUser.class);
        example.createCriteria().andLike("username", "z%");
        PageHelper.startPage(1, 5);
        PageInfo<TbUser> pageInfo = new PageInfo<>(tbUserMapper.selectByExample(example));
        System.out.println(pageInfo.getTotal());
        System.out.println(pageInfo.getPages());
        pageInfo.getList().forEach(tbUser -> {
            System.out.println(tbUser);
        });
    }
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、构建流程
    • 0x01 引入启动器
      • 0x02 配置数据源
        • 0x03 配置Mybatis
          • 0x04 编写实体类
            • 0x05 编写mapper映射接口
              • @Mapper注解
              • @MapperScan注解
            • 0x06 编写测试代码
              • 0x08 sql数据
              • 二、整合Druid连接池
                • 什么是连接池?
                  • 连接池配置
                  • 三、注解方式进行CRUD
                    • @Setect注解
                      • @Insert注解
                        • 案例
                        • 四、使用配置方式CRUD
                        • 五、单元测试
                        • 六、代码生成插件
                          • 案例代码如下
                          相关产品与服务
                          云数据库 MySQL
                          腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档