1. 集成到SpringBoot项目中

核心依赖是org.mybatis.spring.boot:mybatis-spring-boot-starter,当然还需要jdbc和数据库驱动

build.gradle

buildscript {
    repositories {
        mavenCentral()
        jcenter()
    }

    dependencies {
        classpath 'org.springframework.boot:spring-boot-gradle-plugin:2.0.3.RELEASE'
    }
}

plugins {
    id 'io.franzbecker.gradle-lombok' version '1.14'
}

apply plugin: 'java'
apply plugin: 'application'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'
apply plugin: 'io.franzbecker.gradle-lombok'

mainClassName = 'bj.App'

dependencies {
    compile 'org.springframework.boot:spring-boot-starter'
    compile 'org.springframework.boot:spring-boot-starter-jdbc'
    compile 'org.mybatis.spring.boot:mybatis-spring-boot-starter:1.3.2'
    compile 'org.projectlombok:lombok'
    compile 'mysql:mysql-connector-java'

    testCompile 'org.springframework.boot:spring-boot-starter-test'
}

repositories {
    mavenCentral()
}

2. 配置数据库连接

application.yml

spring:
  datasource:
    username: foo
    password: foo
    url: jdbc:mysql://localhost:3306/foo

3. 使用MyBatis

需要先创建好相应的数据表

App.java

package bj;

import lombok.Data;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;

import javax.annotation.Resource;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/6/26 下午1:51
 */
@SpringBootApplication
public class App implements ApplicationListener<ApplicationReadyEvent> {
    @Resource
    private AnimalMapper animalMapper;

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

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        System.out.println("Ready.");
        Animal animal = animalMapper.findAnimalById(1);
        System.out.println(animal);
        System.out.println(animal.getName());
    }
}

@Mapper
interface AnimalMapper {

    @Select("SELECT * FROM animal WHERE id = #{id}")
    Animal findAnimalById(int id);
}

@Data
class Animal {
    private Integer id;
    private String name;
}

4. 使用XML格式的Mapper文件

AnimalMapper(可以放到App.java中)

@Mapper
interface AnimalMapper {
    Animal findAnimalById(int id);
}

animalMapper.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="bj.AnimalMapper">
    <select id="findAnimalById" resultType="bj.Animal">
        select *
        from animal
        where id = #{id}
    </select>
</mapper>

注意:mapper.xml文件默认放在Mapper.java文件同一目录下。如果需要指定其他目录,可以在application.yml中进行配置(注意星号):

mybatis:
  mapper-locations: classpath*:*Mapper.xml

具体示例:查询ID范围并带分页

<select id="getIdIn" resultType="bj.Person">
    SELECT *
    FROM person
    <where>
        <if test="ids != null and !ids.isEmpty()">
            id IN
            <foreach collection="ids" item="item" open="(" separator="," close=")">
                #{item}
            </foreach>
        </if>
    </where>
    <if test="pageable != null">
        LIMIT #{pageable.pageSize} OFFSET #{pageable.offset}
    </if>
</select>
List<Person> getIdIn(@Param("ids") List<Integer> ids, @Param("pageable") Pageable pageable);

5. SQL Builder 的使用

interface PersonMapper {
    @Data
    class MyProvider {
        private String allSql = new SQL() {{
            SELECT("*");
            FROM("person");
        }}.toString();
    }

    @SelectProvider(type = MyProvider.class, method = "getAllSql")
    List<Person> getAll();
}

6. 分页

6.1 自带RowBounds分页

MyBatis自带一个RowBounds分页,这是个假分页,在SQL查询出全部结果后,才从中进行分页截取,在实际业务上基本是废柴一个(分分钟卡爆数据库)。用法:Mapper中的查询函数添加一个RowBounds参数即可,例如:

List<Person> findAll(RowBounds rowBounds);

6.2 自己写个简单分页

interface PersonMapper {
    @Data
    class MyProvider {
        private String allSql = new SQL() {{
            SELECT("*");
            FROM("person");
        }}.toString() + " LIMIT #{limit} OFFSET #{offset}";
    }

    @SelectProvider(type = MyProvider.class, method = "getAllSql")
    List<Person> getAll(MyLimit limit);
}

@Data
class MyLimit {
    private int limit;
    private int offset;
}

不能用现成的org.apache.ibatis.session.RowBounds类型,不是纯POJO,MyBatis读不了(至少目前是)

使用SpringDataCommons自带的分页类进行分页查询

package bj;

import lombok.Data;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * Created by BaiJiFeiLong@gmail.com at 2018/6/26 下午1:51
 */
@SpringBootApplication
@MapperScan(basePackageClasses = App.class)
public class App implements ApplicationListener<ApplicationReadyEvent> {

    @Resource
    private PersonMapper personMapper;

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

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        personMapper.findAll(PageRequest.of(0, 2)).forEach(System.out::println);
    }
}

@Data
class Person {
    private Integer id;
    private String username;
    private String firstName;
    private Date createdAt;
    private String remark;
}

interface PersonMapper {
    @Select("SELECT * FROM person LIMIT #{pageable.pageSize} OFFSET #{pageable.offset}")
    List<Person> findAll(@Param("pageable") Pageable pageable);
}

如果需要组装分页结果,可以使用:

// 组装分页结果 没有查询total,先设为-1,以免造成歧义
// Page: org.springframework.data.domain.Page
// PageImpl: org.springframework.data.domain.PageImpl
Page<Person> personPage = new PageImpl<>(people, pageable, -1);

SpringDataCommons是SpringDataJpa的依赖,可以通过添加spring-boot-starter-data-jpa添加此依赖

6.3 MyBatisPlus分页

先引入依赖
compile 'com.baomidou:mybatis-plus-boot-starter:2.2.0'

Mapper类中查询函数加入分页参数

interface PersonMapper {
    @Select("SELECT * FROM person ")
    List<Person> findAll(Pagination pagination);
}

直接调用即可

personMapper.findAll(new Pagination(2, 2)).forEach(System.out::println);

注意:MyBatisPlus的分页页数基数是1。查询完成后,对应的Pagination会更新总数、页数等(不更内容,需要手动更新),此时查询Pagination可获得记录总数

MyBatisPlus查询的结果是List不是分页(区别于PageHelper)

6.4 PageHelper分页(TkMyBatis)

首先,注入一个MyBatis拦截器。必须设置helperDialect参数,否则会报空指针(NullPointerException)。

@Bean
public PageInterceptor pageInterceptor() {
    PageInterceptor pageInterceptor = new PageInterceptor();
    pageInterceptor.setProperties(new Properties() {{
        this.setProperty("helperDialect", "mysql");
    }});
    return pageInterceptor;
}

用法:

(1). 直接使用RowBounds(PageHelper做了处理)

interface PersonMapper {
    @Select("SELECT * FROM person ")
    List<Person> findAll(RowBounds rowBounds);
}

(2). 添加PageRowBounds参数(可以获取记录总数。RowBounds不支持)

(3). 使用PageHelper.startPage

PageHelper.startPage(2, 2);
Page<Person> people = personMapper.findAll();

注意:

  • startPage会把分页参数放在当前线程(通过ThreadLocal),执行完查询后会自动清理。如果不保证MyBatis查询会被执行,可以通过PageHelper.clearPage()清除状态
  • PageHelper分页查询返回的结果是实现了List接口的Page类型(非分页查询也返回Page类型),可以在Mapper类中直接将返回类型定义为Page类型,省去类型强转
  • PageHelper的分页页数基数也是1
interface PersonMapper {
    @Select("SELECT * FROM person ")
    Page<Person> findAll();
}

小技巧与提示

  • 使用@MapperScan注解,开启自动扫描,每个Mapper类都可以省去@Mapper注解,例@MapperScan(basePackageClasses = App.class)
  • mybatis.type-aliases-package可以省去XML文件中实体类的包前缀
  • mybatis.configuration.map-underscore-to-camel-case: 可以将数据库的下划线命名法映射为java的驼峰命名法
  • auto-mapping-unknown-column-behavior设为'failing',可以保证数据库查询到的每一列都进行了映射

文章首发链接:https://baijifeilong.github.io/2018/06/27/mybatis/

MyBatis大杂烩的更多相关文章

  1. SSM(Spring,SpringMVC,Mybatis)框架整合项目

    快速上手SSM(Spring,SpringMVC,Mybatis)框架整合项目 环境要求: IDEA MySQL 8.0.25 Tomcat 9 Maven 3.6 数据库环境: 创建一个存放书籍数据 ...

  2. 【分享】标准springMVC+mybatis项目maven搭建最精简教程

    文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...

  3. Java MyBatis 插入数据库返回主键

    最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...

  4. [原创]mybatis中整合ehcache缓存框架的使用

    mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...

  5. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  6. mybatis plugins实现项目【全局】读写分离

    在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...

  7. MyBatis基础入门--知识点总结

    对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...

  8. Mybatis XML配置

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...

  9. MyBatis源码分析(一)开篇

    源码学习的好处不用多说,Mybatis源码量少.逻辑简单,将写个系列文章来学习. SqlSession Mybatis的使用入口位于org.apache.ibatis.session包中的SqlSes ...

随机推荐

  1. 347. Top K Frequent Elements 最常用的k个元素

    [抄题]: Given a non-empty array of integers, return the k most frequent elements. For example,Given [1 ...

  2. 646. Maximum Length of Pair Chain 最长的链条长度

    [抄题]: You are given n pairs of numbers. In every pair, the first number is always smaller than the s ...

  3. VMWare 14.1 15 Pro 安装 macOS Mojave 10.14.1系统 遇到的问题解决方案

    安装环境 WIN10VMware Workstation Pro 15.0.0 Build 10134415工具准备1.VMware Workstation Pro 15.0.0 Build 1013 ...

  4. (22)Embrace the near win

    https://www.ted.com/talks/sarah_lewis_embrace_the_near_win/transcript?referrer=playlist-talks_to_get ...

  5. boost-字符文本处理

    1.lexical_cast 一些常见的数值,字符互转函数: 整型int: itoa()._itoa_s atoi()._ttoi 无符号整型unsigned int: _ultoa_s()._ult ...

  6. MySQL 三 二进制安装

    二进制格式安装   何谓二进制格式安装?   二进制格式安装,编译好的打包在tar文件里,安装时需要下载后解包至编译时指定的位置,然后进行相关配置,完成安装   版本信息:CentOS 7.4 安装m ...

  7. Maths | 为什么点积等价于投影后的乘积

    目录 1. 复习点积 2. 点积的对称性 3. 矩阵与变换的关系 4. 一维矩阵也是一种线性变换 5. 最终解释:为什么是投影 先上结论: \(\boldsymbol v\)和\(\boldsymbo ...

  8. Linux下nautilus的右键快捷菜单项设置

    某一天我的Linux更新完后, 我照常在文件夹下点击右键想打开终端, 却发现右键快捷菜单没有Open in terminal的菜单项了. 在网上查找了一下, 结合自己系统的情况发现了解决办法. 由于我 ...

  9. Javascript学习之:JSON

    JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式.它是基于ECMAScript的一个子集,采用完全独立于语言的文本格式.这些特性使JSON成为理想的数据交换 ...

  10. form表单数据进行json转换

    $.fn.serializeJson = function() { var o = {}; var a = this.serializeArray(); $.each(a, function() { ...