crud using Mybatis-plus

Introduction to 1 Mybatis-Plus

1.1 What is Mybatis-Plus

MyBatis-Plus (MP) is an enhancement tool for MyBatis. Based on MyBatis, only enhancements are made without changes. It is created to simplify development and increase efficiency.

1.2 Why study Mybatis-Plus

We have already learned the framework of Mybatis. We only need to define abstract interfaces in the dao layer to crud a database based on the zero implementation of Mybatis.When there are many types of business, we need to redefine a bunch of functionally similar interface methods.

Using the Mybatis-plus tool, we only need to inherit a common BaseMapper<T>interface from the abstract interface we define to get a common set of crud methods to operate the database.With Mybatis-plus, you don't even need any xml mapping files or interface method annotations, a true dao layer zero implementation.

2 Starter Samples

2.1 Requirements

Use Mybatis-Plus to crud users.

2.2 Configuration steps

  1. Set up environment (create project, import package)
  2. Configure Mybaits-Plus (based on Spring implementation)
  3. Write test code

2.3 Configuration steps

2.3.1 Step 1: Setting up the environment

2.3.1.1 Database Preparation

CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL COMMENT 'Primary key ID',
  `name` varchar(30) DEFAULT NULL COMMENT 'Full name',
  `age` int(11) DEFAULT NULL COMMENT 'Age',
  `email` varchar(50) DEFAULT NULL COMMENT 'mailbox',
  PRIMARY KEY (`id`)
)

2.3.1.2 Description

  1. Instead of providing a separate jar package, Mybatis-Plus manages jar dependencies through Maven (or gradle).
  2. Mybatis-Plus is implemented based on the Spring framework, so using Mybatis-Plus, you must import Spring-related dependencies.

2.3.1.3 Add Dependency

Write pom profile

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.oza.mybatisplus</groupId>
    <artifactId>mybatisplus-demo-start</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>3.1.2</version>
        </dependency>
        <!--spring Base Dependency-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <!--spring jdbc rely on-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <!--spring test-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.2.RELEASE</version>
        </dependency>
        <!--mysql drive-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <!--Connection Pool-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.9</version>
        </dependency>
        <!--junit-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
</project>

Step 2.3.2: Create a User entity class

Using Mybatis-Plus, instead of using xml files, you can solve mapping problems between entity classes and database tables based on a set of annotations.The following comments apply to field declarations of entity classes:

annotation Meaning
@TableName(value="tb_user") Specify the corresponding table and omit the value attribute if the table name and class name are identical.
@TableId Specifies the primary key of the table.The Value property specifies the primary key field of the table and can be omitted if it is consistent with the property name.Type specifies the growth policy for the primary key.
@TableField Specifies the table field for the attribute mapping of the class, which can be omitted if the names are consistent.

The source code is as follows:

package org.oza.mybatisplus.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;

@TableName("tb_user")
public class User {

    @TableId(value = "u_id", type = IdType.AUTO)
    private Long id;
    @TableField("u_name")
    private String name;
    @TableField("u_age")
    private Integer age;
    @TableField("u_email")
    private String email;
}

2.3.3 Step 3: Create the UserMapper interface

Simply inherit the BaseMapper public interface.

package org.oza.mybatisplus.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.oza.mybatisplus.pojo.User;

import java.util.List;


public interface UserMapper extends BaseMapper<User> {
    /**
     * Customize the method to display the user names of all users
     * @return Collection of user names
     */
    @Select("select u_name from tb_user")
    List<String> listAllUsername();

    /**
     * Custom method to search all users'mailboxes and encapsulate them in the user object
     * @return
     */
    @Select("select u_email from tb_user")
    @Results(
            @Result(column = "u_email", property = "email")
    )
    List<User> listAllEmail();
}

2.3.4 Step 4: Configure the spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd


        http://www.springframework.org/schema/tx
        http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!--open spring Component Scan-->
    <context:component-scan base-package="org.oza.mybatisplus"/>

    <!--1. data source-->
    <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatisplus?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
        <property name="maxActive" value="10"/>
        <property name="minIdle" value="5"/>
    </bean>

    <!--2. mybatis-plus integration spring-->
    <bean name="sqlSessionFactoryBean" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
        <!--Load Data Source-->
        <property name="dataSource" ref="dataSource"/>
        <!--Configure Plugins-->
        <property name="plugins">
            <array>
                <!--Physical Paging Support-->
                <bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor"/>
                <!--SQL Statement Output-->
                <bean class="com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor"/>
            </array>
        </property>
    </bean>

    <!--3. To configure mybatis-plus Dynamic Proxy-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean"/>
        <property name="basePackage" value="org.oza.mybatisplus.mapper"/>
    </bean>

    <!--4. Configure Transaction Manager-->
    <bean name="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <!--5. Turn on transaction annotation support, specify transaction manager-->
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>

2.3.5 Step 5: Write test code

package org.oza.mybatisplus;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.apache.ibatis.session.RowBounds;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.oza.mybatisplus.mapper.UserMapper;
import org.oza.mybatisplus.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.sql.SQLOutput;
import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-mybatisplus.xml")
public class CrudTest {
    @Autowired
    private UserMapper userMapper;

    /**
     * Insert a piece of data
     */
    @Test
    public void insert() {
        User user = new User(null, "Zhang Wuji", 18, "zwj@qq.com");
        int insert = userMapper.insert(user);
        System.out.println("Affected rows: " + insert);
    }

    /**
     * Delete by ID
     */
    @Test
    public void deleteById(){
        int delete = userMapper.deleteById(1);
        System.out.println("Affected rows: " + delete);

    }

    /**
     * Query by ID
     */
    @Test
    public void selectById() {
        User user = userMapper.selectById(1);
        System.out.println(user);
    }

    /**
     * Delete by condition, delete names containing characters
     */
    @Test
    public void deleteByCondition(){
        QueryWrapper<User> userWrapper = new QueryWrapper<>();
        userWrapper.like("u_name", "Zhang");
        int delete = userMapper.delete(userWrapper);
        System.out.println("Affected rows: " + delete);
    }

    /**
     * Modify according to Id, only data that is not empty
     */
    @Test
    public void update() {
        User user = new User(4L, null, 25, null);
        int update = userMapper.updateById(user);
        System.out.println("Affected rows: " + update);
    }

    /**
     * Batch change, change all names including Zhang
     */
    @Test
    public void updateByCondition() {
        User user = new User(null, null, 25, null);
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.like("u_name", "Zhang");
        int update = userMapper.update(user, updateWrapper);
        System.out.println("Affected rows: " + update);
    }

    /**
     * Find out all names by conditional query
     */
    @Test
    public void selectByCondition() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("u_name", "Zhang");
        List<User> users = userMapper.selectList(queryWrapper);
        users.forEach(user -> System.out.println(user));
    }

    /**
     * Paging query, selectPage can pass in two parameters
     *  Parameter 1:Page object, which contains paging information, and its construction method parameters
     *      Parameter 1: Current page, starting from 1
     *      Parameter 2: Page capacity
     *  Parameter 2: QueryWrapper object, set search criteria
     * Result: The subclass object of the IPage abstract class contains the following information:
     *  1. Current Page
     *  2. PageCount
     *  3. Total Records
     *  4. Page capacity
     *  5. Records on Current Page
     */
    @Test
    public void selectByPage() {
        IPage iPage = userMapper.selectPage(new Page(1L, 2), null);
        System.out.println("current page: " + iPage.getCurrent());
        System.out.println("total pages: " + iPage.getPages());
        System.out.println("total records: " + iPage.getTotal());
        System.out.println("page size: " + iPage.getSize());
        System.out.println("records: " + iPage.getRecords());
    }

    /**
     * Custom Method Test
     */
    @Test
    public void listAllUsername() {
        List<String> usernames = userMapper.listAllUsername();
        System.out.println(usernames);

        List<User> users = userMapper.listAllEmail();
        users.forEach(user -> System.out.println(user.getEmail()));
    }
}

2.3.6 Step 6: Write the Service Layer

mybatis-plus also provides a quick implementation of the Service layer.It is also easy to build a Service layer without writing any implementation.

It is important to note that the service layer method name is slightly different from the dao layer method name

Write UserService interface

package org.oza.mybatisplus.service;

import com.baomidou.mybatisplus.extension.service.IService;
import org.oza.mybatisplus.pojo.User;

/**
 * Inherit IService, write pojo class in generic
 */
public interface UserService extends IService<User> {
}

Write UserServiceImpl implementation class

package org.oza.mybatisplus.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.oza.mybatisplus.mapper.UserMapper;
import org.oza.mybatisplus.pojo.User;
import org.oza.mybatisplus.service.UserService;
import org.springframework.stereotype.Service;

/**
 * Inherit ServiceImpl and implement UserService interface
 *      ServiceImpl: This class implements the IService interface and requires two generic parameters
 *          Parameter 1: corresponding Mapper class
 *          Parameter 2: Corresponding Pojo class
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
}

Test Code

/**
 * Executing paging queries using the service layer
 */
@Test
public void serviceTest() {
    IPage iPage = userService.page(new Page(1L, 2), null);
    System.out.println("current page: " + iPage.getCurrent());
    System.out.println("total pages: " + iPage.getPages());
    System.out.println("total records: " + iPage.getTotal());
    System.out.println("page size: " + iPage.getSize());
    System.out.println("records: " + iPage.getRecords());
}

Keywords: Java Mybatis Spring Apache Junit

Added by guarriman on Fri, 16 Aug 2019 04:49:08 +0300