SpringBoot数据访问3.1:SpringBoot整合MyBatis

SpringBoot数据访问3系列

3.1 SpringBoot整合MyBatis
3.2 SpringBoot整合JPA
3.3 SpringBoot整合Redis


概括

本文包含:Spring boot整合MyBatis的两种方式
① 不管是哪种方式都需要先创建数据库,创建表,在配置文件中进行数据库的连接和数据源配置,编写两个实体类(两个表对应的)
② 使用注解方式时,不需要编写xml映射文件,在Mapper接口中就完成了定义方法+对数据库进行操作
③ 使用配置文件时,需要编写Mapper接口,xml配置文件,以及在全局配置文件中指定xml文件位置


一、步骤截图

1. 基础环境搭建

1.1 数据库+表+数据

①创建一个数据库springbootdata,
②然后创建两个表t_article和t_comment,
③并向表中插入数据,
④其中评论表t_comment的a_id与文章表t_article的主键id相关联

  1. 新建springboot连接
    在这里插入图片描述

  2. 在连接中新建数据库springbootdata
    在这里插入图片描述

  3. 在这个数据库中创建两个表:t_article和t_comment
    ① 总体
    在这里插入图片描述
    ② 创建过程
    在这里插入图片描述
    ② 创建结果
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

1.2 创建项目,引入相应启动器,编写实体类

  1. 创建项目(名为chapter03),依赖选择SQl模块中的MySql和MyBatis依赖
    ① MySQL:提供MySQL数据库连接驱动
    ② MyBatis:提供MyBatis框架来操作数据库
    注: 我把默认地址换成了aliyun=>https://start.aliyun.com/
    在这里插入图片描述
  2. 编写数据库表对应的实体类:Article和Comment

创建domain包,包内创建两个类
每个实体类都对应一个表
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

1.3 配置文件=>数据库连接+数据源类型

  1. 数据库连接配置(在全局配置文件中)=>编写本地MySql数据库(srpngbootdata)的相关配置
  2. 数据源类型配置
    ①(这里直接用了这个) 使用阿里巴巴的Druid数据源,需要在pom.xml中添加druid-spring-boot-starter依赖 => 引入该依赖后,不需要再进行其它额外配置,springboot项目会自动识别配置Druid数据源
    ② 如果需要修改Druid的运行参数,需要在全局配置文件中修改,并编写自定义配置文件注入这些属性值。因为springboot提供的数据源自动配置类中没有这些配置信息的默认值,所以这些值无法被识别并生效,必须得自己编写一个自定义配置类,然后将配置文件中的属性注入到Druid数据源属性中。
  1. 数据库连接配置=>在application.properties中配置
    密码是自己设置的mysql数据库连接的密码
    在这里插入图片描述
  2. 数据源类型选择配置->Druid数据源=>在pom.xml中添加依赖
    在这里插入图片描述
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
</dependency>
1.3.1演示:修改Druid数据源的参数

这个案例中用了方法一,在pom.xml中引入druid依赖,这里我们演示一下方法二:修改druid数据源参数

  1. 不要注释掉pom.xml中的druid依赖,在全局配置文件中修改druid运行参数
# 添加并配置第三方数据源
# 修改数据源的类型=>写了这一行,项目才会识别配置的Druid数据源
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 初始化连接数
spring.datasource.initialSize=20
# 最小空闲数
spring.datasource.minIdle=10
# 最大连接数
spring.datasource.maxActive=100
  1. 编写自定义配置类,对Druid数据源属性值进行注入
    新建com.wpz.config包,包中创建DataSourceConfig

@Configuration:把DataSourceConfig标识为自定义配置类
@Bean:把DataSource实例对象(new DruidDataSource())放到spring容器中 (因为只有这个该对象在容器中(被springboot扫描到),才能进行后续的属性注入操作)
@ConfigurationProperties(prefix = "spring.datasource"):将全局配置文件中以spring.datasource开头的属性值注入到getDataSource()方法返回的DataSource类对象(new DruidDataSource())的属性中

package com.wzp.config;

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;

/**
 * @author 王胖子
 * @version 1.0
 * 将全局配置文件中的属性值注入Druid数据源的属性中
 */
@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource getDruid() {
        return new DruidDataSource();
    }
}


2. 使用注解的方式整合MyBatis

2.1 创建并编写Mapper接口文件

创建mapper包,创建Mapper接口文件
在这里插入图片描述
编写Mapper接口文件

@Mapper:表示该类是一个MyBatis接口文件,并保证能够被springboot自动扫描到spring容器中
② 在接口内部,通过@Insert、@Update、@Delete、@Select注解,配合SQL语句完成对表t_comment数据的增删改查操作

改进:如果编写的Mapper接口过多时,需要重复为每个接口文件添加@Mapper注解,为避免这种麻烦,可以在启动类上添加@MapperScan("XXX"),就不需要再逐个添加@Mapper注解,"XXX"指定了需要扫描的具体包名,例如本例中,mapper文件所在的包为com.wpz.mapper,所以就@MapperScan(“com.wpz.mapper”)
在这里插入图片描述

2.2 测试方法及测试结果

在这里插入图片描述
测试结果为:在数据库中找到id为1的comment信息
在这里插入图片描述


3. 使用配置文件的方式整合MyBatis

3.1 创建并编写Mapper接口

mapper包中创建并编写ArticleMapper接口
在这里插入图片描述

3.2 创建并编写xml文件

在resources目录下,创建一个mapper包,用于统一管理映射文件
并在该包下 创建并编写与Mapper接口对应的映射文件ArticleMapper.xml
在这里插入图片描述
xml映射文件中通过<mapper>标签中的<select>、<update>等标签内的sql语句对数据进行操作

<?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">
<!--根据接口文件中的方法,编写两个对应的SQL语句-->
<!--namespace的属性值是对应的mapper接口文件的全路径名称-->
<mapper namespace="com.wpz.mapper.ArticleMapper">
    <!--1. 查询文章详细(包括评论信息)-->
    <select id="selectArticle" resultMap="articleWithComment">
        SELECT a.*,c.id c_id,c.content c_content,c.author
        FROM t_article a,t_comment c
        WHERE a.id=#{id} AND a.id=c.a_id
    </select>
    <!--1.1 resultMap中id是唯一的,是resultMap的唯一标识名称  type是里面返回的类型-->
    <resultMap id="articleWithComment" type="Article">
        <!--1.1.1 id标签表示表的主键-->
        <!--1.1.2 column表示数据库的列  property表示实体类的属性-->
        <!--这里column中是select查询结果的数据库列的名字,不相交的属性不用写表名-->
        <id column="id" property="id"></id>
        <!--1.1.3 如果不是主键列,就用result表示-->
        <result column="title" property="title"></result>
        <result column="content" property="content"></result>
        <!--1.1.4 ofType:指的是集合中元素的类型,报错需要加一个javaType -->
        <collection property="commentList" ofType="Comment" javaType="java.util.List">
            <id column="c_id" property="id"></id>
            <result column="c_content" property="content"></result>
            <result column="author" property="author"></result>
        </collection>
    </resultMap>
    <!--2. 根据文章id更新文章信息-->
    <update id="updateArticle" parameterType="Article">
        UPDATE t_article
        <set>
            <if test="title!null and title !=''">
                title=#{title},
            </if>
            <if test="content!null and content !=''">
                content=#{content}
            </if>
        </set>
        WHERE id=#{id}
    </update>
</mapper>

3.3 配置XML映射文件路径

# 配置MyBatis的XML映射文件路径=>因为springboot扫描不到xml文件,所以要配置
mybatis.mapper-locations=classpath:mapper/*.xml
# 配置XML映射文件中指定的实体类别名路径=>没有使用com.wpz.domain.Article而是使用Article(如果使用全路径,则不用配置了)
mybatis.type-aliases-package=com.wpz.domain

3.4 测试方法及测试结果

package com.wpz;

import com.wpz.domain.Article;
import com.wpz.mapper.ArticleMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class Chapter03ApplicationTests {
    @Autowired
    private ArticleMapper articleMapper;
    @Test
    public void selectArticle() {
        Article article = articleMapper.selectArticle(1);
        //这里我为了方便看输出,把Article的toString()中的commentList删掉了,这里用迭代器遍历
        System.out.println(article);
        Iterator<Comment> iterator = article.getCommentList().iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }
    }
}

输出结果:
在这里插入图片描述

二、两种方式的输出结果

在这里插入图片描述
在这里插入图片描述

三、整体代码

目录结构

在这里插入图片描述

1. 两个实体类

package com.wpz.domain;

import java.util.List;

/**
 * @author 王胖子
 * @version 1.0
 * Article实体类:对应数据库表 t_article => 文章表
 */
public class Article {
    private Integer id;//主键id
    private String title;//标题
    private String content;//内容
    private List<Comment> commentList;//该文章的评论集合

    //下面是get、set、toString方法

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public List<Comment> getCommentList() {
        return commentList;
    }

    public void setCommentList(List<Comment> commentList) {
        this.commentList = commentList;
    }

    @Override
    public String toString() {
        return "Article{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content;
    }
}

package com.wpz.domain;

/**
 * @author 王胖子
 * @version 1.0
 * Comment实体类:对应数据库表 t_comment => 评论表
 */
public class Comment {
    private Integer id;//主键id
    private String content;//评论的内容
    private String author;//发表评论的人
    private Integer aId;//关联t_article的主键(t_comment的外键)

    //下面是get、set、toString方法

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

    public Integer getaId() {
        return aId;
    }

    public void setaId(Integer aId) {
        this.aId = aId;
    }

    @Override
    public String toString() {
        return "Comment{" +
                "id=" + id +
                ", content='" + content + '\'' +
                ", author='" + author + '\'' +
                ", aId=" + aId +
                '}';
    }
}

2. Mapper接口文件

2.1 使用注解整合MyBatis

package com.wpz.mapper;

import com.wpz.domain.Comment;
import org.apache.ibatis.annotations.*;

/**
 * @author 王胖子
 * @version 1.0
 * 该Mapper接口文件:用于对表t_comment中的数据进行操作
 */
//@Mapper:表示该类是一个MyBatis接口文件,并保证能够被springboot自动扫描到spring容器中
//在接口内部,通过@Insert、@Update、@Delete、@Select注解,配合SQL语句完成对表t_comment数据的增删改查操作
@Mapper
public interface CommentMapper {
    //#{id} => 表示传入的id值,id=#{id}为表中的id值与传入参数的id值相等
    @Select("SELECT * FROM t_comment WHERE id =#{id}")
    Comment findById(Integer id);

    @Insert("INSERT INTO t_comment(content,author,a_id)" +
            "values (#{content}),(#{author}),(#{a_id})")
    int insertComment(Comment comment);

    @Update("UPDATE t_comment SET content=#{content} WHERE id=#{id}")
    int updateComment(Comment comment);

    @Delete("DELETE FROM t_comment WHERE id=#{id}")
    int deleteComment(Comment comment);
}

2.2 使用配置文件整合

package com.wpz.mapper;

import com.wpz.domain.Article;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author 王胖子
 * @version 1.0
 * 在mapper包中,创建一个操作表t_article的接口ArticleMapper
 */
@Mapper
public interface ArticleMapper {
    //根据文章id查询文章
    Article selectArticle(Integer id);
    //更新文章,返回更新的条数
    int updateArticle(Article article);
}

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">
<!--根据接口文件中的方法,编写两个对应的SQL语句-->
<!--namespace的属性值是对应的mapper接口文件的全路径名称-->
<mapper namespace="com.wpz.mapper.ArticleMapper">
    <!--1. 查询文章详细(包括评论信息)-->
    <select id="selectArticle" resultMap="articleWithComment">
        SELECT a.*,c.id c_id,c.content c_content,c.author
        FROM t_article a,t_comment c
        WHERE a.id=#{id} AND a.id=c.a_id
    </select>
    <!--1.1 resultMap中id是唯一的,是resultMap的唯一标识名称  type是里面返回的类型-->
    <resultMap id="articleWithComment" type="Article">
        <!--1.1.1 id标签表示表的主键-->
        <!--1.1.2 column表示数据库的列  property表示实体类的属性-->
        <!--这里column中是select查询结果的数据库列的名字,不相交的属性不用写表名-->
        <id column="id" property="id"></id>
        <!--1.1.3 如果不是主键列,就用result表示-->
        <result column="title" property="title"></result>
        <result column="content" property="content"></result>
        <!--1.1.4 ofType:指的是集合中元素的类型,报错需要加一个javaType -->
        <collection property="commentList" ofType="Comment" javaType="java.util.List">
            <id column="c_id" property="id"></id>
            <result column="c_content" property="content"></result>
            <result column="author" property="author"></result>
        </collection>
    </resultMap>
    <!--2. 根据文章id更新文章信息-->
    <update id="updateArticle" parameterType="Article">
        UPDATE t_article
        <set>
            <if test="title!null and title !=''">
                title=#{title},
            </if>
            <if test="content!null and content !=''">
                content=#{content}
            </if>
        </set>
        WHERE id=#{id}
    </update>
</mapper>

4. 测试类

package com.wpz;

import com.wpz.domain.Comment;
import com.wpz.mapper.CommentMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.wpz.domain.Article;
import com.wpz.mapper.ArticleMapper;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Iterator;

@SpringBootTest
class Chapter03ApplicationTests {
    //测试使用注解整合MyBatis
    @Autowired
    private CommentMapper commentMapper;

    @Test
    public void commentTest() {
        Comment commentById = commentMapper.findById(1);
        System.out.println(commentById);
    }

    //测试使用配置文件整合MyBatis
    @Autowired
    private ArticleMapper articleMapper;

    @Test
    public void selectArticle() {
        Article article = articleMapper.selectArticle(1);
        //这里我为了方便看输出,把Article的toString()中的commentList删掉了,这里用迭代器遍历
        System.out.println(article);
        Iterator<Comment> iterator = article.getCommentList().iterator();
        while (iterator.hasNext()) {
            Object next = iterator.next();
            System.out.println(next);
        }
    }
}

5. 全局配置文件

# MySQl数据库springbootdata连接配置
# 数据库连接地址
spring.datasource.url=jdbc:mysql://localhost:3306/springbootdata?serverTimezone=UTC
# 数据库用户名&密码:
spring.datasource.username=root
spring.datasource.password=123456
# 配置MyBatis的XML映射文件路径=>因为springboot扫描不到xml文件,所以要配置
mybatis.mapper-locations=classpath:mapper/*.xml
# 配置XML映射文件中指定的实体类别名路径=>没有使用com.wpz.domain.Article而是使用Article(如果使用全路径,则不用配置了)
mybatis.type-aliases-package=com.wpz.domain


## 添加并配置第三方数据源
## 修改数据源的类型=>写了这一行,项目才会识别配置的Druid数据源
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
## 初始化连接数
#spring.datasource.initialSize=20
## 最小空闲数
#spring.datasource.minIdle=10
## 最大连接数
#spring.datasource.maxActive=100

6. 引申:修改Druid数据源的自定义配置类

package com.wpz.config;

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;

/**
 * @author 王胖子
 * @version 1.0
 * 演示修改Druid数据源的参数
 * 将全局配置文件中的属性值注入Druid数据源的属性中
 */
@Configuration
public class DataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource getDruid() {
        return new DruidDataSource();
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值