SpringBoot 整合MyBatis-Plus3.1詳細教程

一.說明

Mybatis-Plus官網:mp.baomidou.com/java

Mybatis-Plus是一個Mybatis框架的加強插件,根據官方描述,MP只作加強不作改變,引入它不會對現有工程產生影響,如絲般順滑.而且只需簡單配置,便可快速進行 CRUD 操做,從而節省大量時間.代碼生成,分頁,性能分析等功能包羅萬象,最新已經更新到了3.1.1版本了,3.X系列支持lambda語法,讓我在寫條件構造的時候少了不少的"魔法值",從代碼結構上更簡潔了.mysql

二.項目環境

MyBatis-Plus版本: 3.1.0git

SpringBoot版本:2.1.5web

JDK版本:1.8spring

Maven依賴以下:sql

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- mybatisPlus 核心庫 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.0</version>
        </dependency>
        <!-- 引入阿里數據庫鏈接池 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.6</version>
        </dependency>
</dependencies>
複製代碼

配置以下:數據庫

# 配置端口
server:
 port: 8081
spring:
  # 配置數據源
 datasource:
 driver-class-name: com.mysql.cj.jdbc.Driver
 url: jdbc:mysql://localhost:3306/mp_student?useUnicode=true&characterEncoding=utf-8
 username: root
 password: root
 type: com.alibaba.druid.pool.DruidDataSource
# mybatis-plus相關配置
mybatis-plus:
  # xml掃描,多個目錄用逗號或者分號分隔(告訴 Mapper 所對應的 XML 文件位置)
 mapper-locations: classpath:mapper/*.xml
  # 如下配置均有默認值,能夠不設置
 global-config:
 db-config:
      #主鍵類型 AUTO:"數據庫ID自增" INPUT:"用戶輸入ID",ID_WORKER:"全局惟一ID (數字類型惟一ID)", UUID:"全局惟一ID UUID";
 id-type: auto
      #字段策略 IGNORED:"忽略判斷" NOT_NULL:"非 NULL 判斷") NOT_EMPTY:"非空判斷"
 field-strategy: NOT_EMPTY
      #數據庫類型
 db-type: MYSQL
 configuration:
    # 是否開啓自動駝峯命名規則映射:從數據庫列名到Java屬性駝峯命名的相似映射
 map-underscore-to-camel-case: true
    # 返回map時true:當查詢數據爲空時字段返回爲null,false:不加這個查詢數據爲空時,字段將被隱藏
 call-setters-on-nulls: true
    # 這個配置會將執行的sql打印出來,在開發或測試的時候能夠用
 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
複製代碼

表結構:apache

CREATE TABLE `user_info` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(32) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年齡',
  `skill` varchar(32) DEFAULT NULL COMMENT '技能',
  `evaluate` varchar(64) DEFAULT NULL COMMENT '評價',
  `fraction` bigint(11) DEFAULT NULL COMMENT '分數',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb4 COMMENT='學生信息表';
複製代碼

表數據:mybatis

INSERT INTO `user_info` VALUES (1, '小明', 20, '畫畫', '該學生在畫畫方面有必定天賦', 89);
INSERT INTO `user_info` VALUES (2, '小蘭', 19, '遊戲', '近期該學生因爲遊戲的緣由致使分數下降了', 64);
INSERT INTO `user_info` VALUES (3, '張張', 18, '英語', '近期該學生參加英語比賽得到二等獎', 90);
INSERT INTO `user_info` VALUES (4, '大黃', 20, '體育', '該學生近期因爲參加籃球比賽,致使腳傷', 76);
INSERT INTO `user_info` VALUES (5, '大白', 17, '繪畫', '該學生參加美術大賽得到三等獎', 77);
INSERT INTO `user_info` VALUES (7, '小龍', 18, 'JAVA', '該學生是一個在改BUG的碼農', 59);
INSERT INTO `user_info` VALUES (9, 'Sans', 18, '睡覺', 'Sans是一個愛睡覺,而且身材較矮骨骼巨大的骷髏小胖子', 60);
INSERT INTO `user_info` VALUES (10, 'papyrus', 18, 'JAVA', 'Papyrus是一個講話大聲、個性張揚的骷髏,給人自信、有魅力的骷髏小瘦子', 58);
INSERT INTO `user_info` VALUES (11, '刪除數據1', 3, '畫肖像', NULL, 61);
INSERT INTO `user_info` VALUES (12, '刪除數據2', 3, NULL, NULL, 61);
INSERT INTO `user_info` VALUES (13, '刪除數據3', 3, NULL, NULL, 61);
INSERT INTO `user_info` VALUES (14, '刪除數據4', 5, '刪除', NULL, 10);
INSERT INTO `user_info` VALUES (15, '刪除數據5', 6, '刪除', NULL, 10);
複製代碼

二.編寫基礎類

在啓動類上添加掃描DAO的註解app

@SpringBootApplication
@MapperScan(basePackages = {"com.mp.demo.dao"}) //掃描DAO
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
複製代碼

編寫Config配置類

/** * @Description MybatisPlus配置類 * @Author Sans * @CreateTime 2019/5/26 17:20 */
@Configuration
public class MybatisPlusConfig {
    /** * mybatis-plus SQL執行效率插件【生產環境能夠關閉】 */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }
    /** * 分頁插件 */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
}
複製代碼

編寫Entity類

/** * @Description 學生信息實體類 * @Author Sans * @CreateTime 2019/5/26 21:41 */
@Data
@TableName("user_info")//@TableName中的值對應着表名
public class UserInfoEntity {

    /** * 主鍵 * @TableId中能夠決定主鍵的類型,不寫會採起默認值,默認值能夠在yml中配置 * AUTO: 數據庫ID自增 * INPUT: 用戶輸入ID * ID_WORKER: 全局惟一ID,Long類型的主鍵 * ID_WORKER_STR: 字符串全局惟一ID * UUID: 全局惟一ID,UUID類型的主鍵 * NONE: 該類型爲未設置主鍵類型 */
    @TableId(type = IdType.AUTO)
    private Long id;
    /** * 姓名 */
    private String name;
    /** * 年齡 */
    private Integer age;
    /** * 技能 */
    private String skill;
    /** * 評價 */
    private String evaluate;
    /** * 分數 */
    private Long fraction;
}
複製代碼

編寫Dao類

/** * @Description 用戶信息DAO * @Author Sans * @CreateTime 2019/6/8 16:24 */
public interface UserInfoDao extends BaseMapper<UserInfoEntity> {
}
複製代碼

編寫Service類

/** * @Description 用戶業務接口 * @Author Sans * @CreateTime 2019/6/8 16:26 */
public interface UserInfoService extends IService<UserInfoEntity> {
}
複製代碼

編寫ServiceImpl類

/** * @Description 用戶業務實現 * @Author Sans * @CreateTime 2019/6/8 16:26 */
@Service
@Transactional
public class UserInfoSerivceImpl extends ServiceImpl<UserInfoDao, UserInfoEntity> implements UserInfoService {
}
複製代碼

三.MyBatis-Plus基礎演示

這裏咱們看到,service中咱們沒有寫任何方法,MyBatis-Plus官方封裝了許多基本CRUD的方法,能夠直接使用大量節約時間,MP共通方法詳見IService,ServiceImpl,BaseMapper源碼,寫入操做在ServiceImpl中已有事務綁定,這裏咱們舉一些經常使用的方法演示.

/** * @Description UserInfoController * @Author Sans * @CreateTime 2019/6/8 16:27 */
@RestController
@RequestMapping("/userInfo")
public class UserInfoController {

    @Autowired
    private UserInfoService userInfoService;

    /** * 根據ID獲取用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:34 * @Param userId 用戶ID * @Return UserInfoEntity 用戶實體 */
    @RequestMapping("/getInfo")
    public UserInfoEntity getInfo(String userId){
        UserInfoEntity userInfoEntity = userInfoService.getById(userId);
        return userInfoEntity;
    }
    /** * 查詢所有信息 * @Author Sans * @CreateTime 2019/6/8 16:35 * @Param userId 用戶ID * @Return List<UserInfoEntity> 用戶實體集合 */
    @RequestMapping("/getList")
    public List<UserInfoEntity> getList(){
        List<UserInfoEntity> userInfoEntityList = userInfoService.list();
        return userInfoEntityList;
    }
    /** * 分頁查詢所有數據 * @Author Sans * @CreateTime 2019/6/8 16:37 * @Return IPage<UserInfoEntity> 分頁數據 */
    @RequestMapping("/getInfoListPage")
    public IPage<UserInfoEntity> getInfoListPage(){
        //須要在Config配置類中配置分頁插件
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(5); //當前頁
        page.setSize(1);    //每頁條數
        page = userInfoService.page(page);
        return page;
    }
    /** * 根據指定字段查詢用戶信息集合 * @Author Sans * @CreateTime 2019/6/8 16:39 * @Return Collection<UserInfoEntity> 用戶實體集合 */
    @RequestMapping("/getListMap")
    public Collection<UserInfoEntity> getListMap(){
        Map<String,Object> map = new HashMap<>();
        //kay是字段名 value是字段值
        map.put("age",20);
        Collection<UserInfoEntity> userInfoEntityList = userInfoService.listByMap(map);
        return userInfoEntityList;
    }
    /** * 新增用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:40 */
    @RequestMapping("/saveInfo")
    public void saveInfo(){
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setName("小龍");
        userInfoEntity.setSkill("JAVA");
        userInfoEntity.setAge(18);
        userInfoEntity.setFraction(59L);
        userInfoEntity.setEvaluate("該學生是一個在改BUG的碼農");
        userInfoService.save(userInfoEntity);
    }
    /** * 批量新增用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:42 */
    @RequestMapping("/saveInfoList")
    public void saveInfoList(){
        //建立對象
        UserInfoEntity sans = new UserInfoEntity();
        sans.setName("Sans");
        sans.setSkill("睡覺");
        sans.setAge(18);
        sans.setFraction(60L);
        sans.setEvaluate("Sans是一個愛睡覺,而且身材較矮骨骼巨大的骷髏小胖子");
        UserInfoEntity papyrus = new UserInfoEntity();
        papyrus.setName("papyrus");
        papyrus.setSkill("JAVA");
        papyrus.setAge(18);
        papyrus.setFraction(58L);
        papyrus.setEvaluate("Papyrus是一個講話大聲、個性張揚的骷髏,給人自信、有魅力的骷髏小瘦子");
        //批量保存
        List<UserInfoEntity> list =new ArrayList<>();
        list.add(sans);
        list.add(papyrus);
        userInfoService.saveBatch(list);
    }
    /** * 更新用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:47 */
    @RequestMapping("/updateInfo")
    public void updateInfo(){
        //根據實體中的ID去更新,其餘字段若是值爲null則不會更新該字段,參考yml配置文件
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(19);
        userInfoService.updateById(userInfoEntity);
    }
    /** * 新增或者更新用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:50 */
    @RequestMapping("/saveOrUpdateInfo")
    public void saveOrUpdate(){
        //傳入的實體類userInfoEntity中ID爲null就會新增(ID自增)
        //實體類ID值存在,若是數據庫存在ID就會更新,若是不存在就會新增
        UserInfoEntity userInfoEntity = new UserInfoEntity();
        userInfoEntity.setId(1L);
        userInfoEntity.setAge(20);
        userInfoService.saveOrUpdate(userInfoEntity);
    }
    /** * 根據ID刪除用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:52 */
    @RequestMapping("/deleteInfo")
    public void deleteInfo(String userId){
        userInfoService.removeById(userId);
    }
    /** * 根據ID批量刪除用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:55 */
    @RequestMapping("/deleteInfoList")
    public void deleteInfoList(){
        List<String> userIdlist = new ArrayList<>();
        userIdlist.add("12");
        userIdlist.add("13");
        userInfoService.removeByIds(userIdlist);
    }
    /** * 根據指定字段刪除用戶信息 * @Author Sans * @CreateTime 2019/6/8 16:57 */
    @RequestMapping("/deleteInfoMap")
    public void deleteInfoMap(){
        //kay是字段名 value是字段值
        Map<String,Object> map = new HashMap<>();
        map.put("skill","刪除");
        map.put("fraction",10L);
        userInfoService.removeByMap(map);
    }
}
複製代碼

四.MyBatis-Plus的QueryWrapper條件構造器

當查詢條件複雜的時候,咱們可使用MP的條件構造器,請參考下面的QueryWrapper條件參數說明

查詢方式 方法說明
setSqlSelect 設置 SELECT 查詢字段
where WHERE 語句,拼接 + WHERE 條件
and AND 語句,拼接 + AND 字段=值
or OR 語句,拼接 + OR 字段=值
eq 等於=
allEq 基於 map 內容等於=
ne 不等於<>
gt 大於>
ge 大於等於>=
lt 小於<
le 小於等於<=
like 模糊查詢 LIKE
notLike 模糊查詢 NOT LIKE
in IN 查詢
notIn NOT IN 查詢
isNull NULL 值查詢
isNotNull IS NOT NULL
groupBy 分組 GROUP BY
having HAVING 關鍵詞
orderBy 排序 ORDER BY
orderByAsc ASC 排序 ORDER BY
orderByDesc DESC 排序 ORDER BY
exists EXISTS 條件語句
notExists NOT EXISTS 條件語句
between BETWEEN 條件語句
notBetween NOT BETWEEN 條件語句
addFilter 自由拼接 SQL
last 拼接在最後,例如:last("LIMIT 1")

下面咱們來舉一些常見的示例

/** * @Description UserInfoPlusController * @Author Sans * @CreateTime 2019/6/9 14:52 */
@RestController
@RequestMapping("/userInfoPlus")
public class UserInfoPlusController {

    @Autowired
    private UserInfoService userInfoService;

    /** * MP擴展演示 * @Author Sans * @CreateTime 2019/6/8 16:37 * @Return Map<String,Object> 返回數據 */
    @RequestMapping("/getInfoListPlus")
    public Map<String,Object> getInfoListPage(){
        //初始化返回類
        Map<String,Object> result = new HashMap<>();
        //查詢年齡等於18歲的學生
        //等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age = 18
        QueryWrapper<UserInfoEntity> queryWrapper1 = new QueryWrapper<>();
        queryWrapper1.lambda().eq(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList1 = userInfoService.list(queryWrapper1);
        result.put("studentAge18",userInfoEntityList1);
        //查詢年齡大於5歲的學生且小於等於18歲的學生
        //等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE age > 5 AND age <= 18
        QueryWrapper<UserInfoEntity> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.lambda().gt(UserInfoEntity::getAge,5);
        queryWrapper2.lambda().le(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList2 = userInfoService.list(queryWrapper2);
        result.put("studentAge5",userInfoEntityList2);
        //模糊查詢技能字段帶有"畫"的數據,並按照年齡降序
        //等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE skill LIKE '%畫%' ORDER BY age DESC
        QueryWrapper<UserInfoEntity> queryWrapper3 = new QueryWrapper<>();
        queryWrapper3.lambda().like(UserInfoEntity::getSkill,"畫");
        queryWrapper3.lambda().orderByDesc(UserInfoEntity::getAge);
        List<UserInfoEntity> userInfoEntityList3 = userInfoService.list(queryWrapper3);
        result.put("studentAgeSkill",userInfoEntityList3);
        //模糊查詢名字帶有"小"或者年齡大於18的學生
        //等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE name LIKE '%小%' OR age > 18
        QueryWrapper<UserInfoEntity> queryWrapper4 = new QueryWrapper<>();
        queryWrapper4.lambda().like(UserInfoEntity::getName,"小");
        queryWrapper4.lambda().or().gt(UserInfoEntity::getAge,18);
        List<UserInfoEntity> userInfoEntityList4 = userInfoService.list(queryWrapper4);
        result.put("studentOr",userInfoEntityList4);
        //查詢評價不爲null的學生,而且分頁
        //等價SQL: SELECT id,name,age,skill,evaluate,fraction FROM user_info WHERE evaluate IS NOT NULL LIMIT 0,5
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(5);
        QueryWrapper<UserInfoEntity> queryWrapper5 = new QueryWrapper<>();
        queryWrapper5.lambda().isNotNull(UserInfoEntity::getEvaluate);
        page = userInfoService.page(page,queryWrapper5);
        result.put("studentPage",page);
        return result;
    }
}
複製代碼

五.自定義SQL

引入Mybatis-Plus不會對項目現有的 Mybatis 構架產生任何影響,並且Mybatis-Plus支持全部 Mybatis 原生的特性,這也是我喜歡使用它的緣由之一,因爲某些業務複雜,咱們可能要本身去寫一些比較複雜的SQL語句,咱們舉一個簡單的例子來演示自定義SQL.

示例:查詢大於設置分數的學生(分數爲動態輸入,且有分頁)

編寫Mapper.xml文件

<mapper namespace="com.mp.demo.dao.UserInfoDao">
    <!-- Sans 2019/6/9 14:35 -->
    <select id="selectUserInfoByGtFraction" resultType="com.mp.demo.entity.UserInfoEntity" parameterType="long">
	SELECT * FROM user_info WHERE fraction > #{fraction}
    </select>
</mapper>
複製代碼

在DAO中加入方法

/** * 查詢大於該分數的學生 * @Author Sans * @CreateTime 2019/6/9 14:28 * @Param page 分頁參數 * @Param fraction 分數 * @Return IPage<UserInfoEntity> 分頁數據 */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction);
複製代碼

在service加入方法

/** * 查詢大於該分數的學生 * @Author Sans * @CreateTime 2019/6/9 14:27 * @Param page 分頁參數 * @Param fraction 分數 * @Return IPage<UserInfoEntity> 分頁數據 */
    IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page,Long fraction);
複製代碼

在serviceImpl加入方法

/** * 查詢大於該分數的學生 * @Author Sans * @CreateTime 2019/6/9 14:27 * @Param page 分頁參數 * @Param fraction 分數 * @Return IPage<UserInfoEntity> 分頁數據 */
    @Override
    public IPage<UserInfoEntity> selectUserInfoByGtFraction(IPage<UserInfoEntity> page, Long fraction) {
        return this.baseMapper.selectUserInfoByGtFraction(page,fraction);
    }
複製代碼

在Controller中測試

/** * MP自定義SQL * @Author Sans * @CreateTime 2019/6/9 14:37 * @Return IPage<UserInfoEntity> 分頁數據 */
    @RequestMapping("/getInfoListSQL")
    public IPage<UserInfoEntity> getInfoListSQL(){
        //查詢大於60分以上的學生,而且分頁
        IPage<UserInfoEntity> page = new Page<>();
        page.setCurrent(1);
        page.setSize(5);
        page = userInfoService.selectUserInfoByGtFraction(page,60L);
        return page;
    }
複製代碼

六.項目源碼

項目源碼: gitee.com/liselotte/s…

我的確實很喜歡用MyBatis-Plus,不只節約時間,代碼也簡潔乾淨,它給了我那時候從SSM到SpringBoot過分的那種感受

嗯,這玩意真香~

謝謝你們閱讀,若是喜歡,請收藏點贊,文章不足之處,也請給出寶貴意見.

相關文章
相關標籤/搜索