SpringBoot series Mybatis integrated full detailed version

Keywords: Java Mybatis Spring xml

SpringBoot series (five) Mybatis integration

Catalog

  1. About mybatis
  2. Project creation
  3. entity
  4. dao
  5. service
  6. serviceImpl
  7. mapper
  8. controller

1. About mybatis

  MyBatis is an excellent persistence framework that supports customized SQL, stored procedures, and advanced mapping. MyBatis avoids almost all JDBC code and manual setting of parameters and getting result sets. MyBatis can use simple XML or annotation to configure and map native information, and map interface and Java POJOs(Plain Ordinary Java Object) to records in database.

  in other words, I think it's much easier to integrate the persistence layer with mybatis. It's not too cool to write jdbc code to operate some connections of the database.

2. Project creation

  create a simple spring boot project with start web dependencies, and then add mybatis related dependencies.

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
</dependency>

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>

  after downloading dependency, you can configure the connection database in the yml file or the properties file.

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true&serverTimezone=GMT%2B8
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

  then we create a student table under the database mybatis

CREATE TABLE `student`(
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT 'Unique identification id',
  `name` varchar(30) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT 'Full name',
  `age` int(3) NOT NULL COMMENT 'Age',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic;

Complete the initial configuration of the project.

3. entity class code

/**
 * (Student)Entity class
 *
 * @author Full stack learning notes
 * @since 2020-04-14 11:39:10
 */
public class Student  {
    private static final long serialVersionUID = -91969758749726312L;
    /**
    * Unique id
    */
    private Integer id;
    /**
    * Full name
    */
    private String name;
    /**
    * Age
    */
    private Integer age;
}

  get and set methods are omitted above.

4. dao layer code

package com.example.demomybatis.dao;

import com.example.demomybatis.entity.Student;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;

/**
 * (Student)Table database access layer
 *
 * @author Full stack learning notes
 * @since 2020-04-14 11:39:18
 */
@Mapper
@Repository
public interface StudentDao {

    /**
     * Query single data by ID
     *
     * @param id Primary key
     * @return Instance object
     */
    Student queryById(Integer id);

    /**
     * Query specified row data
     *
     * @param offset Query start location
     * @param limit Query number
     * @return Object list
     */
    List<Student> queryAllByLimit(@Param("offset") int offset, @Param("limit") int limit);


    /**
     * Query by entity as filter criteria
     *
     * @param student Instance object
     * @return Object list
     */
    List<Student> queryAll(Student student);

    /**
     * New data
     *
     * @param student Instance object
     * @return Number of rows affected
     */
    int insert(Student student);

    /**
     * Modifying data
     *
     * @param student Instance object
     * @return Number of rows affected
     */
    int update(Student student);

    /**
     * Delete data through primary key
     *
     * @param id Primary key
     * @return Number of rows affected
     */
    int deleteById(Integer id);

}


Code Description: dao layer belongs to data access layer. It maps with mybatis xml file to realize the function of SQL statement.

  annotation Description: the class in dao layer needs to be annotated with @ Mapper. This annotation is provided by mybatis, which indicates that this class is a bean in data access layer and is handed over to spring container management. And the previous xml Mapping file can be omitted. When compiling, adding this class will generate its implementation class accordingly.

  if you use idea, when you use @ Autowired to inject beans in serviceImpl, idea will report an error, but it will not affect the operation. The error is reported because @ mapper is not provided by spring. When you need to inject this bean automatically, idea cannot detect whether this bean can be injected into the container in advance. I don't know if the new version of idea will have this problem. If you want to eliminate this error, you can add an @ Repository to the dao layer class. This annotation is provided by spring, so that you can pre detect that the mapper bean can be registered in the spring container.

  you will find that in the code, some interface parameters are annotated with @ Param, while others are not. If you have only one parameter, this annotation is not required. When you have two or more annotations, you need to use this annotation. Otherwise, in the corresponding xml file, it can't tell which one of the parameters is wrong. Using this annotation means identifying the name of the parameter, so that the receiving party can better find and use the value.

5. service layer code

package com.example.demomybatis.service;

import com.example.demomybatis.entity.Student;
import java.util.List;

/**
 * (Student)Table service interface
 *
 * @author Full stack learning notes
 * @since 2020-04-14 11:39:19
 */
public interface StudentService {

    /**
     * Query single data by ID
     *
     * @param id Primary key
     * @return Instance object
     */
    Student queryById(Integer id);

    /**
     * Query multiple data
     *
     * @param offset Query start location
     * @param limit Query number
     * @return Object list
     */
    List<Student> queryAllByLimit(int offset, int limit);

    /**
     * New data
     *
     * @param student Instance object
     * @return Instance object
     */
    Student insert(Student student);

    /**
     * Modifying data
     *
     * @param student Instance object
     * @return Instance object
     */
    Student update(Student student);

    /**
     * Delete data through primary key
     *
     * @param id Primary key
     * @return Success
     */
    boolean deleteById(Integer id);

}

  code Description: This is the interface of the service layer. serviceImpl corresponds to the implementation of the service layer interface.

6. serviceImpl layer code

package com.example.demomybatis.service.impl;

import com.example.demomybatis.entity.Student;
import com.example.demomybatis.dao.StudentDao;
import com.example.demomybatis.service.StudentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

/**
 * (Student)Table service implementation class
 *
 * @author Full stack learning notes
 * @since 2020-04-14 11:39:19
 */
@Service("studentService")
public class StudentServiceImpl implements StudentService {

    @Autowired
    private StudentDao studentDao;

    /**
     * Query single data by ID
     *
     * @param id Primary key
     * @return Instance object
     */
    @Override
    public Student queryById(Integer id) {
        return this.studentDao.queryById(id);
    }

    /**
     * Query multiple data
     *
     * @param offset Query start location
     * @param limit Query number
     * @return Object list
     */
    @Override
    public List<Student> queryAllByLimit(int offset, int limit) {
        return this.studentDao.queryAllByLimit(offset, limit);
    }

    /**
     * New data
     *
     * @param student Instance object
     * @return Instance object
     */
    @Override
    public Student insert(Student student) {
        this.studentDao.insert(student);
        return student;
    }

    /**
     * Modifying data
     *
     * @param student Instance object
     * @return Instance object
     */
    @Override
    public Student update(Student student) {
        this.studentDao.update(student);
        return this.queryById(student.getId());
    }

    /**
     * Delete data through primary key
     *
     * @param id Primary key
     * @return Success
     */
    @Override
    public boolean deleteById(Integer id) {
        return this.studentDao.deleteById(id) > 0;
    }
}

  code Description: @ service identifies that the bean is a service layer, that is, a service layer, and submits it to the spring container for management. The value property of the parameter is the name of the bean, which can be left blank. It defaults to the class name.

  here we can say, @ Resource and @ Autowired, When we need to use the dao layer method in serviceImpl, instead of directly new an object, we need to use annotations to implement custom injection assembly, and use spring container to manage these bean s. In this way, the code is loose coupling, the coupling between classes is lower, and the maintainability is improved.
@Resource and @ Autowired can play the same role. According to the package name, they are not in a package. The differences are as follows:

  1. @Autowired is assembled by type by default. By default, dependent objects must exist. If you want to allow null values, you can set its required property to false, such as @ Autowired(required=false). This annotation belongs to spring. If you want to use name assembly, you can use @ Qualifier annotation.
  2. @Resource is assembled by name by default. The name can be specified by the name attribute. If the name attribute is not specified, when the annotation is written on the field, the field name is selected by default to search the installation name. If the annotation is written on the setter method, the attribute name is selected by default to assemble. Assemble by type when no bean matching the name is found. However, it should be noted that if the name attribute is specified, it will only be assembled by name. This annotation belongs to J2EE.

7. mapper layer code

  the so-called mapper layer, which is an xml file, corresponds to the dao layer.

<?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="com.example.demomybatis.dao.StudentDao">
    <resultMap type="com.example.demomybatis.entity.Student" id="StudentMap">
        <result property="id" column="id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="age" column="age" jdbcType="INTEGER"/>
    </resultMap>

    <!--Query single-->
    <select id="queryById" resultMap="StudentMap">
        select
          id, name, age
        from mybatis.student
        where id = #{id}
    </select>

    <!--Query specified row data-->
    <select id="queryAllByLimit" resultMap="StudentMap">
        select
          id, name, age
        from mybatis.student
        limit #{offset}, #{limit}
    </select>

    <!--Query by entity as filter criteria-->
    <select id="queryAll" resultMap="StudentMap">
        select
          id, name, age
        from mybatis.student
        <where>
            <if test="id != null">
                and id = #{id}
            </if>
            <if test="name != null and name != ''">
                and name = #{name}
            </if>
            <if test="age != null">
                and age = #{age}
            </if>
        </where>
    </select>

    <!--Add all columns-->
    <insert id="insert" keyProperty="id" useGeneratedKeys="true">
        insert into mybatis.student(name, age)
        values (#{name}, #{age})
    </insert>

    <!--Modify data through primary key-->
    <update id="update">
        update mybatis.student
        <set>
            <if test="name != null and name != ''">
                name = #{name},
            </if>
            <if test="age != null">
                age = #{age},
            </if>
        </set>
        where id = #{id}
    </update>

    <!--Delete by primary key-->
    <delete id="deleteById">
        delete from mybatis.student where id = #{id}
    </delete>

</mapper>

  this corresponds to the addition, deletion, modification and query statement of SQL, and then the method of dao layer corresponds to each SQL statement, in which the id of SQL statement corresponds to each interface method of dao layer.
The default configuration cannot detect this xml file, and then we need to do the following configuration.
I put the xml file under the dao folder under the resources folder.
Then we add the following configuration in yml.

mybatis:
  type-aliases-package: com.example.demomybatis.entity
  mapper-locations: classpath:dao/*Mapper.xml

8. controller layer code

  the code of the controller layer is used for testing, and it is also the place where the data is returned to the front end.

package com.example.demomybatis.controller;

import com.example.demomybatis.entity.Student;
import com.example.demomybatis.service.StudentService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;

/**
 * (Student)Table control layer
 *
 * @author Full stack learning notes
 * @since 2020-04-14 11:39:20
 */
@RestController
@RequestMapping("student")
public class StudentController {
    /**
     * service object
     */
    @Resource
    private StudentService studentService;

    /**
     * Query single data through primary key
     *
     * @param id Primary key
     * @return Single data
     */
    @GetMapping("selectOne")
    public Student selectOne(Integer id) {
        return this.studentService.queryById(id);
    }

}

  code Description: @ RestController is equivalent to @ Controller plus @ ResponseBody. Adding this annotation is to let this class return json string, which is the json parsing provided by spring. @The RequesMapping annotation is an address mapping annotation. According to this address, you can find this method, this class, annotation to the class, which is equivalent to the parent class address of the method.

Give it a test. Let's add a piece of data to the database first.

insert into student(id,name,age) VALUES(2,'Full stack learning notes',22)

  then enter: localhost:8088/student/selectOne?id=2 in the browser to see the data we got. Port configuration depends on your project.

Well, this issue of mybatis integration is here. If you are interested in it, you can learn notes in wx search stack, pay attention to it, and push wonderful articles to your hands every day!

Posted by pkellum on Tue, 14 Apr 2020 00:48:17 -0700