文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

SpringBoot 整合 Mybatis 实现数据表增删改查,保姆级教程!

2024-11-29 19:54

关注

原因在于,在 ORM 框架中其实还有另一个翘楚,那就是刚刚说到的 MyBatis,它的实现方式与 Spring Boot JPA 完全不同,MyBatis 框架不会帮助用户动态生成 SQL 语句,它把 SQL 的编写工作完全交给了用户,开发者可以像在本地数据库中写 SQL 语句一样快速的完成对数据库表的操作,非常易于新人上手,唯一的缺点就是配置工作量很大,好在有代码生成器,可以帮助开发者减轻不少的开发工作量。

ORM 框架发展至今,只剩下两家了,一个是以Hibernate为代表,开发者可以不用写一句 SQL 就可以轻松完成对数据库的访问操作;另一个是以MyBatis为代表,开发者可以根据自己的业务需求灵活的编写动态 SQL 完成对数据库的访问操作。

总的来说,两者各有特点,如果当前业务所有的业务操作都是单表并且没有很复杂的查询要求,那么采用 Spring Boot JPA 来开发,效率会更高;如果业务很复杂,各表之间经常需要连表查询,那么采用MyBatis来开发会是一个非常好的选择。在企业级系统开发中,因为业务比较复杂,国内采用MyBatis来开发的项目相对比较多些。

今天这篇文章我们就具体来说说如何在 Spring Boot 中整合 MyBatis 完成数据库表的增删改查操作。

02、应用实践

2.1、工程配置

首先,在pom.xml文件中引入mybatis-spring-boot-starter依赖,具体如下:



    org.mybatis.spring.boot
    mybatis-spring-boot-starter
    2.0.0



    mysql
    mysql-connector-java

关于mybatis-spring-boot-starter与Spring Boot的版本对应关系,可以参考如下:

本项目采用的是Spring Boot 2.1.0构建,因此选择2.0.0版本。

然后,在application.properties文件中添加数据源信息和相关的MyBatis配置参数,内容如下:

# 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# 打印SQL语句
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

MyBatis支持两种开发模式。

下面我们一起来这两种具体的应用方式。

2.2、基于注解的配置实现

基于注解的配置实现,简单的说就是采用注解来开发,具体实现如下。

2.2.1、创建数据库表

首先,mybatis框架不会帮助我们根据实体类自动生成目标数据库表,因此我们需要事先设计好数据库表结构,在此我们以角色表tb_role为例,具体创建命令如下。

CREATE TABLE `tb_role` (
  `id` int(11) unsigned NOT NULL COMMENT '主键ID',
  `role_name` varchar(50) DEFAULT NULL COMMENT '角色名称',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.2.2、编写对应的实体类

package com.example.springboot.entity;

public class Role {

    
    private Integer id;

    
    private String roleName;

    
    private Date createTime;

    // set、get方法等...
}

2.2.3、编写对应的 Mapper 接口

package com.example.springboot.mapper;

public interface RoleMapper {

    @Select("select * from tb_role")
    @Results({
            @Result(property = "id",  column = "id"),
            @Result(property = "roleName",  column = "role_name"),
            @Result(property = "createTime", column = "create_time")
    })
    List findAll();

    @Select("select * from tb_role where id =#{id}")
    @Results({
            @Result(property = "id",  column = "id"),
            @Result(property = "roleName",  column = "role_name"),
            @Result(property = "createTime", column = "create_time")
    })
    Role findById(@Param("id") Integer id);

    @Insert("insert into tb_role(id, role_name, create_time) VALUES(#{id}, #{roleName}, #{createTime})")
    int insert(Role role);

    @Update("update tb_role set role_name=#{roleName} WHERE id=#{id}")
    int update(Role role);

    @Delete("delete from tb_role where id =#{id}")
    int delete(@Param("id") Integer id);
}

2.2.4、添加 Mapper 接口扫描路径

默认创建的 Mapper 接口无法被自动加载到 Spring IOC 容器中,因此需要在Application启动类上,添加 Mapper 接口的包扫描路径,可以通过@MapperScan注解来完成注入,具体如下。

@MapperScan("com.example.springboot.mapper")
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.2.5、单元测试

最后,我们编写单元测试来验证一下内容的正确性,代码如下:

@RunWith(SpringRunner.class)
@SpringBootTest
@Transactional
public class RoleMapperJunit {

    @Autowired
    private RoleMapper roleMapper;

    @Test
    public void test(){
        // 新增数据
        roleMapper.insert(new Role(1, "开发工程师", new Date()));
        roleMapper.insert(new Role(2, "测试工程师", new Date()));
        roleMapper.insert(new Role(3, "项目经理", new Date()));

        // 查询数据
        List roleList = roleMapper.findAll();
        System.out.println("第一次查询全部数据结果:" + roleList.toString());

        System.out.println("----------------------");

        // 修改单条数据
        roleMapper.update(new Role(1, "技术经理"));

        // 单条查询
        Role role = roleMapper.findById(1);
        System.out.println("查询[id=1]结果:" + role.toString());

        System.out.println("----------------------");

        // 删除单条数据
        roleMapper.delete(1);

        // 查询数据
        List roleList1 = roleMapper.findAll();
        System.out.println("第二次查询全部数据结果:" + roleList1.toString());
    }
}

运行单元测试,输出结果如下!

第一次查询全部数据结果:[Role{id=1, roleName='开发工程师', createTime=Sun Apr 28 11:44:52 CST 2024}, Role{id=2, roleName='测试工程师', createTime=Sun Apr 28 11:44:52 CST 2024}, Role{id=3, roleName='项目经理', createTime=Sun Apr 28 11:44:52 CST 2024}]
----------------------
查询[id=1]结果:Role{id=1, roleName='技术经理', createTime=Sun Apr 28 11:44:52 CST 2024}
----------------------
第二次查询全部数据结果:[Role{id=2, roleName='测试工程师', createTime=Sun Apr 28 11:44:52 CST 2024}, Role{id=3, roleName='项目经理', createTime=Sun Apr 28 11:44:52 CST 2024}]

至此,基于注解模式的实现方式已经介绍完毕了。

如果有一定开发经历的同学可能会感觉到,基于注解方式的开发模式虽然简单,但是弊端也很大,假如查询的时候,需要连接的表很多,字段也多,代码可读性就变得很差,因此大多数情况下,开发者会更倾向于选择基于 XML 的配置实现方式开发,原因是它的可读性更高。

2.3、基于XML的配置实现

基于 XML 的配置实现,是一种最常用的开发模式,具体实现如下。

2.3.1、创建数据库表

与上面类似,我们创建一张新表tb_menu来介绍,具体创建命令如下。

CREATE TABLE `tb_menu` (
  `id` int(11) unsigned NOT NULL COMMENT '主键ID',
  `menu_name` varchar(50) DEFAULT NULL COMMENT '菜单名称',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

2.3.2、编写对应的实体类

package com.example.springboot.entity;

public class Menu {

    
    private Integer id;

    
    private String menuName;

    
    private Date createTime;

    // set、get方法等...
}

2.3.3、编写对应的 Mapper 接口

与上面基于注解的开发模式类似,只是少了注解配置。

package com.example.springboot.mapper;

public interface MenuMapper {

    List findAll();

    Menu findById(@Param("id") Integer id);

    int insert(Menu role);

    int update(Menu role);

    int delete(@Param("id") Integer id);
}

2.3.4、创建 XML 映射文件

在src/main/resources/mybatis/mapper目录下创建MenuMapper.xml文件,并与 Mapper 接口建立映射关系,内容如下:





    
    
        
        
        
    

    
    
        id
        ,menu_name
        ,create_time
    

    
        select
        
        from tb_menu
        where id = #{id,jdbcType=INTEGER}
    

    
        insert into tb_menu(id, menu_name, create_time)
        values(#{id}, #{menuName}, #{createTime})
    

    
        update tb_menu
        set menu_name = #{menuName,jdbcType=VARCHAR}
        where id = #{id,jdbcType=INTEGER}
    

    
        delete from tb_menu
        where id = #{id,jdbcType=INTEGER}
    

2.3.5、创建 Mybatis 全局配置文件

在src/main/resources/mybatis目录下创建mybatis-config.xml文件,可以全局配置 mybatis 相关属性信息,示例如下:





    
        
        
    

    
        
        
        
        
        
        
        
    

更多的配置属性,可以参考这篇文章。

2.3.6、添加 Mapper 接口扫描路径

同上,需要在Application启动类上添加 Mapper 接口的包扫描路径,如果已添加,可以忽略。

@MapperScan("com.example.springboot.mapper")
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

2.3.7、配置 XML 文件扫描路径

与基于注解的开发模式稍有不同,我们还需要在application.properties文件中配置 Mybatis 相关的 XML 文件扫描目录,否则启动报错,内容如下:

# 配置mybatis全局配置文件扫描
mybatis.config-location=classpath:mybatis/mybatis-config.xml
# 配置mybatis的xml配置文件扫描目录
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
# 打印SQL语句,需要注射掉这个mybatis全局属性配置,否则启动报错
#mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

2.3.8、单元测试

最后,我们编写单元测试来验证一下内容的正确性,代码如下:

public class MenuMapperJunit {

    @Autowired
    private MenuMapper menuMapper;

    @Test
    public void test(){
        // 新增数据
        menuMapper.insert(new Menu(1, "用户菜单", new Date()));
        menuMapper.insert(new Menu(2, "角色菜单", new Date()));
        menuMapper.insert(new Menu(3, "系统菜单", new Date()));

        // 查询数据
        List menuList = menuMapper.findAll();
        System.out.println("第一次查询全部数据结果:" + menuList.toString());

        System.out.println("----------------------");

        // 修改单条数据
        menuMapper.update(new Menu(1, "项目菜单"));

        // 单条查询
        Menu menu = menuMapper.findById(1);
        System.out.println("查询[id=1]结果:" + menu.toString());

        System.out.println("----------------------");

        // 删除单条数据
        menuMapper.delete(1);

        // 查询数据
        List menuList1 = menuMapper.findAll();
        System.out.println("第二次查询全部数据结果:" + menuList1.toString());
    }
}

运行单元测试,输出结果如下!

第一次查询全部数据结果:[Menu{id=1, menuName='用户菜单', createTime=Sun Apr 28 14:24:49 CST 2024}, Menu{id=2, menuName='角色菜单', createTime=Sun Apr 28 14:24:49 CST 2024}, Menu{id=3, menuName='系统菜单', createTime=Sun Apr 28 14:24:50 CST 2024}]
----------------------
查询[id=1]结果:Menu{id=1, menuName='项目菜单', createTime=Sun Apr 28 14:24:49 CST 2024}
----------------------
第二次查询全部数据结果:[Menu{id=2, menuName='角色菜单', createTime=Sun Apr 28 14:24:49 CST 2024}, Menu{id=3, menuName='系统菜单', createTime=Sun Apr 28 14:24:50 CST 2024}]

至此,基于 XML 模式的实现方式已经介绍完毕了。

实际开发过程中,如果不需要自定义全局配置 Mybatis 数据,也可以省掉创建 Mybatis 全局配置文件这一步。

03、小结

本文主要围绕利用 Mybatis 框架来实现对数据库表的快速访问操作,与 Spring Boot JPA 相比,Mybatis 在使用上更加灵活,对数据表的操作就像在本地数据库写 SQL 一样方便,对于业务复杂的查询场景,它比 Spring Boot JPA 要灵活很多。而且可维护性更高。

如果是企业级的 web 项目,推荐采用 Mybatis 框架作为持久层。

04、参考

  1. https://mybatis.net.cn/
来源:潘志的研发笔记内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯