Spring Boot 2.x + myBatis full annotation to realize CRUD and automatic table creation

Keywords: Java Mybatis Spring Database

This paper mainly introduces a demo program based on Spring Boot 2.x, mySQL and myBatis, which uses Web to operate the database, and then implements it in the way of full annotation without xml configuration (a full xml configuration demo will be written later). It mainly supports the following functions:
(1) the database automatically creates tables, such as the user table in this example.
(2) database CRUD(create read update delete) operation.
(3) operate the user table through http get.

Environmental preparation:
(1) IDEA (it is recommended to use Ultimate version, which will bring the function of operating database through IDEA)
(2) MySQL
(3) Maven + JDK8

Project directory structure:

\---main
    +---java
    |   \---hello
    |       |   MainApplication.java
    |       |   
    |       +---bean
    |       |       User.java
    |       |       
    |       +---config
    |       |       MyBatisMapperScannerConfig.java
    |       |       MybatisTableConfig.java
    |       |       
    |       +---controller
    |       |       UserController.java
    |       |       
    |       +---dao
    |       |       UserDao.java
    |       |       
    |       \---service
    |               UserService.java
    |               
    \---resources
            application.properties
            sql.txt
pom.xml

Database and user tables:
The default database is sakila under MySQL. You can change the local database name by modifying the configuration in application.properties.
The user table is created with a SQL statement similar to the following:

CREATE TABLE `user` (
    `id` int(13) NOT NULL AUTO_INCREMENT,
    `name` varchar(33) DEFAULT NULL,
    `age` int(3) DEFAULT NULL,
    `money` double DEFAULT NULL,
    PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8

This demo adopts the method of automatically creating tables, that is, when Spring Boot is started, it will automatically create tables according to the
(1) configuration in application.properties
(2) config/MyBatisMapperScannerConfig.java and config/ MybatisTableConfig.java
(3) notes set in bean/user.json
Through the third-party framework mybatis. Able to complete the automatic creation of tables.
For details, please refer to https://segmentfault.com/a/11...

Note that the following four dependencies need to be introduced when using the third-party framework mybatis.executable:

        <dependency>
            <groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
            <artifactId>mybatis-enhance-actable</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.18</version>
        </dependency>

In pom.xml POM, we need to add four dependencies: boot starter web dependency, MySQL connection dependency, myBatis dependency, and the third-party framework myBatis.able.

<?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>MybatisDemo</groupId>
    <artifactId>MybatisDemo</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
    </parent>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.gitee.sunchenbin.mybatis.actable</groupId>
            <artifactId>mybatis-enhance-actable</artifactId>
            <version>1.0.3</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.18</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Configure application.properties, connect to local MySQL database and automatically create table configuration

server.port=8333
# The database is sakila
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/sakila?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# The configuration of automatic table creation, combined with hello.config, can automatically create user's table
mybatis.table.auto=create
mybatis.model.pack=hello.bean
mybatis.database.type=mysql

MyBatisMapperScannerConfig.java automatic table creation configuration class

package hello.config;

import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration
@AutoConfigureAfter(MybatisTableConfig.class)
public class MyBatisMapperScannerConfig {

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer() throws Exception{
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.example.mapper.*;com.gitee.sunchenbin.mybatis.actable.dao.*");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        return mapperScannerConfigurer;
    }

}

MybatisTableConfig.java automatically creates a table configuration class. You need to configure the User class path hello.bean*

package hello.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.PropertiesFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

@Configuration
@ComponentScan(basePackages = {"com.gitee.sunchenbin.mybatis.actable.manager.*"})
public class MybatisTableConfig {

    @Value("${spring.datasource.driver-class-name}")
    private String driver;

    @Value("${spring.datasource.url}")
    private String url;

    @Value("${spring.datasource.username}")
    private String username;

    @Value("${spring.datasource.password}")
    private String password;

    @Bean
    public PropertiesFactoryBean configProperties() throws Exception{
        PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        propertiesFactoryBean.setLocations(resolver.getResources("classpath*:application.properties"));
        return propertiesFactoryBean;
    }

    @Bean
    public DruidDataSource dataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(driver);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);
        dataSource.setMaxActive(30);
        dataSource.setInitialSize(10);
        dataSource.setValidationQuery("SELECT 1");
        dataSource.setTestOnBorrow(true);
        return dataSource;
    }

    @Bean
    public DataSourceTransactionManager dataSourceTransactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(dataSource());
        return dataSourceTransactionManager;
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource());
        PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath*:com/gitee/sunchenbin/mybatis/actable/mapping/*/*.xml"));
        sqlSessionFactoryBean.setTypeAliasesPackage("hello.bean.*");
        return sqlSessionFactoryBean;
    }

}

User.java
User class, based on full annotation to realize automatic table creation

package hello.bean;

import com.gitee.sunchenbin.mybatis.actable.annotation.Column;
import com.gitee.sunchenbin.mybatis.actable.annotation.Table;
import com.gitee.sunchenbin.mybatis.actable.command.BaseModel;
import com.gitee.sunchenbin.mybatis.actable.constants.MySqlTypeConstant;

@Table(name = "user")
public class User extends BaseModel {
    private static final long serialVersionUID = 5199200306752426433L;

    @Column(name = "id", type = MySqlTypeConstant.INT, isAutoIncrement = true, length = 13, isKey = true)
    private int id;

    @Column(name = "name", type = MySqlTypeConstant.VARCHAR , length = 33, isNull = false)
    private String name;

    @Column(name = "age", type = MySqlTypeConstant.INT, length = 3, isNull = false)
    private int age;

    @Column(name = "money", type = MySqlTypeConstant.DOUBLE, isNull = false)
    private double money;

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

UserDao.java
The development of Dao layer realizes CRUD operation of database based on full annotation

package hello.dao;

import hello.bean.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * Crud based on annotation (create read update delete)
 */
@Mapper
public interface UserDao {

    /**
     * Insert user information
     */
    @Insert("INSERT INTO user(name, age, money) VALUES(#{name}, #{age}, #{money})")
    void insertUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money);

    /**
     * Query user information by name
     */
    @Select("SELECT * FROM user WHERE name = #{name}")
    List<User> findUserByName(@Param("name") String name);

    /**
     * Query all user information
     */
    @Select("SELECT * FROM user")
    List<User> findAllUser();

    /**
     * Update user information based on id
     */
    @Update("UPDATE user SET name = #{name},age = #{age},money= #{money} WHERE id = #{id}")
    void updateUser(@Param("name") String name, @Param("age") Integer age, @Param("money") Double money,
                    @Param("id") int id);

    /**
     * Delete user information according to id
     */
    @Delete("DELETE from user WHERE name = #{name}")
    void deleteUser(@Param("name") String name);

    /**
     * Delete all data in the user table
     */
    @Delete("DELETE from user WHERE 1 = 1")
    void deleteAllUserData();
}

UserController.java
The Controller layer implements the insert, query, update, delete, clear and other operations of http get.

package hello.controller;

import hello.bean.User;
import hello.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;


/**
 * Implement the controller interface corresponding to CRUD http request
 */
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    // http://localhost:8333/user/insert?name=ace&age=18&money=0
    @GetMapping("/insert")
    public List<User> insert(@RequestParam(value = "name", required = true) String name,
                             @RequestParam(value = "age", required = true) int age,
                             @RequestParam(value = "money", required = true) double money) {
        userService.insertOneService(name, age, money);
        return userService.selectAllUser();
    }

    // http://localhost:8333/user/query?name=ace
    @GetMapping("/query")
    public List<User> queryByName(@RequestParam(value = "name", required = false) String name) {
        if (name == null) {
            return userService.selectAllUser();
        }
        return userService.selectUserByName(name);
    }

    @GetMapping("/update")
    public List<User> update(@RequestParam(value = "name", required = true) String name,
                             @RequestParam(value = "age", required = true) int age,
                             @RequestParam(value = "money", required = true) double money) {
        userService.updateService(name, age, money);
        return userService.selectUserByName(name);
    }

    @GetMapping("/delete")
    public String delete(@RequestParam(value = "name", required = true) String name) {
        userService.deleteService(name);
        return "OK";
    }

    @GetMapping("/clear")
    public List<User> testClear() {
        userService.clearService();
        return userService.selectAllUser();
    }

    @GetMapping("/changemoney")
    public List<User> testchangemoney() {
        userService.insertService();
        userService.changemoney();
        return userService.selectAllUser();
    }

}

UserService.java
Service level

package hello.service;

import hello.bean.User;
import hello.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserService {
    @Autowired
    private UserDao userDao;


    /**
     * Find users by name
     */
    public List<User> selectUserByName(String name) {
        return userDao.findUserByName(name);
    }

    /**
     * Find all users
     */
    public List<User> selectAllUser() {
        return userDao.findAllUser();
    }

    /**
     * Insert two users
     */
    public void insertService() {
        userDao.insertUser("Ace", 22, 3000.0);
        userDao.insertUser("Blink", 19, 3000.0);
    }

    /**
     * Insert a specified user
     */
    public void insertOneService(String name, int age, double money) {
        userDao.insertUser(name, age, money);
    }

    /**
     * Update user information by name
     */
    @Transactional
    public void updateService(String name, int age, double money) {
        List<User> users = userDao.findUserByName(name);
        if (users.isEmpty()) {
            return;
        }
        List<Integer> ids = users.stream().map(User::getId).collect(Collectors.toList());
        ids.forEach(id -> userDao.updateUser(name, age, money, id));
    }

    /**
     * Delete user by id
     */
    public void deleteService(String name) {
        userDao.deleteUser(name);
    }

    /**
     * Clear all data in the table
     */
    public void clearService() {
        userDao.deleteAllUserData();
    }

    /**
     * Simulate transactions. Due to the @ Transactional annotation, if there is an accident in the middle of the transfer, Ace and Blink's money will not change.
     */
    @Transactional
    public void changemoney() {
        userDao.updateUser("Ace", 22, 2000.0, 3);
        // Unexpected situations that may be encountered in the process of simulated transfer
        int temp = 1 / 0;
        userDao.updateUser("Blink", 19, 4000.0, 4);
    }
}

MainApplication.java
Spring Boot startup class. When Spring Boot is started by inheriting CommandLineRunner, some data will be inserted into the table after the table is automatically created.

package hello;

import hello.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * This demo requires mySQL to be installed locally, and will automatically create a user table under the sakila database according to the statement in sql.txt when Spring Boot is started.
 */
@SpringBootApplication
public class MainApplication implements CommandLineRunner {

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

    @Autowired
    UserService userService;

    @Override
    public void run(String... args) throws Exception {
        userService.insertService();
    }
}

Function demonstration:
(1) the database table is automatically created. You can see the creation of the user table through the console

(2) query

(3) insert data

(4) update data

(5) delete delete data

Up to now, a simple demo program based on Spring Boot 2.x, mySQL and myBatis with full annotation of Web operation database has been completed~

Posted by jets on Tue, 12 Nov 2019 10:08:40 -0800