栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

快速掌握 MyBatis 框架(二)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

快速掌握 MyBatis 框架(二)

文章目录
    • 一、前言
      • 1.1 数据库与表
      • 1.2 实体类
      • 1.3 MyBatisX 插件
      • 1.4 SQL 日志查看配置
    • 二、多表查询
      • 2.1 一对一
      • 2.2 一对多
    • 三、动态 SQL 使用
      • 3.1 < if > 标签
      • 3.2 < trim > 标签
      • 3.3 < where > 标签
      • 3.4 < set > 标签
      • 3.5 < foreach > 标签

一、前言

快速掌握 MyBatis 框架(一)

1.1 数据库与表
create database if not exists library;
use library;

drop table if exists book;
create table book(
    id int primary key auto_increment,  -- 书籍Id
    bookName varchar(100) not null,     -- 书名
    content varchar(1024) not null,     -- 书籍内容
    authorId int not null,              -- 作者Id
    `state` int default 1               -- 借出状态,默认为1,未借出
);
drop table if exists author;
create table author(
    id int primary key auto_increment,  -- 作者Id
    authorName varchar(100) not null,   -- 作者名字
    age int,                            -- 作者年龄
    nationality varchar(250)            -- 作者国籍
);
1.2 实体类
//书籍类
@Data
public class Book {
    private Integer id;
    private String bookName;
    private String content;
    private Integer authorId;
    private Integer state;
    private Author author;
}
//作者类
@Data
public class Author {
    private Integer id;
    private String authorName;
    private Integer age;
    private String nationality;
    private List books;
}
1.3 MyBatisX 插件

在写 MyBatis 代码的时候有一个非常好用的插件——MyBatisX。

选择 File->Settings ,然后进行如下操作进行插件的安装

该插件可以实现接口代码和对应的 XML 文件中的代码的跳转

而且写好一个 接口方法后可以在对应的 XML 文件中自动生成代码(出现红下划线,Alt+Enter,选择第一个选项),当然,这样的方式生成的标签不一定是我们想要的


1.4 SQL 日志查看配置

为了查看写好的 SQL ,可以在配置文件中进行配置,如此,在控制台就可以查看 SQL 日志

mybatis:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
二、多表查询

在前面一篇文章中有讲数据库的增加(insert)、删除(delete)、修改(update)、查询(select)操作

增删改这三个操作返回的值都是影响的行数,所以在写 SQL 的 XML 时并不需要指定返回类型,但是如果是查询操作就需要通过 resultType 来设置返回类型,就算是 String 类型,返回值也要设置为 resultType =“java.lang.String”

但是如果进行多表查询,实体类中就会有一个属性为另一个实体类,比如上面的实体类定义中,一本书对应一个作者,想要将作者的完整信息都放在书籍类中。一个作者可以写很多本书,想要将这个作者写的所有书的信息都放在一个 List 中。这样的情况,简简单单通过 resultType 已经没有办法实现,如果只是使用 resultType ,会发现对应的类的属性值为 null(变量 author 和 变量 books 的值为 null)

此时就需要使用 resultMap ,返回一个字典映射

2.1 一对一

一本书对应一个作者的情况

interface

@Mapper
public interface BookMapper {
    public Book getBookById(Integer id);
}

XML

BookMapper.xml





    
        
        
        
        
        
        
        
    
    
        select a.*,b.id b_id,b.bookName b_bookName,b.content b_content
        from author a left join book b
        on a.id = b.authorId where a.id = #{id}
    
 

关联的BookMapper 中的 BaseMap 在上面一对一的代码中已经写了

单元测试代码

@Test
void getAuthor() {
    List list = mapper.getAuthor(1);
    list.stream().forEach(n-> System.out.println(n));
}

结果展示

三、动态 SQL 使用

为了应对各种各样的需求,就需要动态 SQL 完成不同条件下不同的 SQL 拼接

3.1 < if > 标签

在完善信息的时候,有些信息是必须要填的,有些是非必填的。就像 author 表中作者的信息一样,只有 authorName 是一定要填写的,age 和 nationality 是非必填的,那么在插入数据的时候,就需要应对各种信息插入情况,就需要用 < if > 标签来判断传来的值是否为 null,如果是就不将内容拼接到 SQL 中

interface

public int setAuthor3(Author author);

XML


    insert into author(authorName
    
        ,age
    
    
        ,nationality
    
    ) values(#{authorName}
    
        ,#{age}
    
    
        ,#{nationality}
    
    )

解释:

  1. 通过 if 标签中的 test属性中的内容(对象中的属性)是否为空来决定是否将其拼接到 SQL 语句中
  2. 需要注意拼接时的逗号以及括号,保证在任何情况下都能组装成正确的 SQL 语句
  3. 由于需要判空,因此创建实体类的时候最好使用包装类,比如使用 Integer 类型而不是 int 类型。因为 int 类型默认值为 0 ,不会为 null,而 0 和 null 还是有很大区别的,使用 int 类型会存在报错的风险

测试代码展示

@Test
void setAuthor3() {
    Author author = new Author();
    author.setAuthorName("钱七");
    author.setNationality("马来西亚");
    System.out.println("更新的数据条数:"+mapper.setAuthor3(author));
}

结果显示

3.2 < trim > 标签

该标签是配合 if 标签进行使用,试想极端情况,所有的参数都是非必传的,那么在不知道哪个参数是第一个,哪个参数是最后一个的情况下,一定会有多出来的逗号,trim 标签就可以解决这样的问题

trim 标签的属性

  • prefix:表示整个语句块以 prefix 的值作为前缀
  • suffix:表示整个语句块以 suffix 的值作为后缀
  • prefixOverrides:表示整个语句块要去除的前缀
  • suffixOverrides:表示整个语句块要去除的后缀

interface

public int setAuthor4(Author author);

XML


    insert into author
    
        
            ,authorName
        
        
            ,age
        
        
            ,nationality
        
    
    values
    
        
            #{authorName},
        
        
            #{age},
        
        
            #{nationality},
        
    

注意:如果 trim 标签中的内容没有一条条件成立 ,就不会执行 trim 语句的内容了,包括其属性也不会生效。因此如果有必传参数,就往 trim 标签中添加必传参数;如果没有任何必传参数,前缀后缀相关属性就在 trim 中设置

单元测试代码

@Test
void setAuthor4() {
    Author author = new Author();
    author.setAuthorName("朱八");
    author.setAge(66);
    System.out.println("更新的数据条数:"+mapper.setAuthor4(author));
}

结果显示

3.3 < where > 标签

传入一个对象,根据属性进行 where 条件查询,只要对象中的属性不为 null 就是查询条件

interface

public List getBookByIdOrAuthorId(Book book);

XML