[springboot + mybatis series] several methods of mapper interface registration


[springboot + mybatis series] several methods of mapper interface registration

[springboot + mybatis series] several methods of mapper interface registration

In the springboot project, the database is operated with the help of mybatis, which is no stranger to most small partners of the Java technology stack; As we know, using mybatis, there are generally the following

  • Entity: database entity class
  • Mapper: DB operation interface
  • Service: service class

The comments in this blog post are put on mapper. Do you know how to register mapper (how many ways do you write the word “fennel”)

<!– more –>

1. Environmental preparation

1. Database preparation

Use MySQL as the example database of this article and add a new table

CREATE TABLE `money` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `Name ` varchar (20) not null default '' comment 'user name',
  `Money ` int (26) not null default '0' comment 'money',
  `is_deleted` tinyint(1) NOT NULL DEFAULT '0',
  `create_ at` timestamp NOT NULL DEFAULT CURRENT_ Timestamp comment 'creation time',
  `update_ at` timestamp NOT NULL DEFAULT CURRENT_ TIMESTAMP ON UPDATE CURRENT_ Timestamp comment 'update time',
  PRIMARY KEY (`id`),
  KEY `name` (`name`)

2. Project environment

With the help ofSpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEADevelop

POM dependencies are as follows


DB configuration informationapplication.yml

    url: jdbc:mysql://
    username: root

II. Example demonstration

The basic environment has been built. Next, prepare the basic classes such as entity and mapper of mybatis

1. Entity class, mapper class

Database entity classMoneyPo

public class MoneyPo {
    private Integer id;

    private String name;

    private Long money;

    private Integer isDeleted;

    private Timestamp createAt;

    private Timestamp updateAt;

Corresponding mapper interface (curd is implemented directly by annotation here)

public interface MoneyMapper {

     *Save the data and save the primary key ID
     * @param po
     * @return int
    @Options(useGeneratedKeys = true, keyProperty = "po.id", keyColumn = "id")
    @Insert("insert into money (name, money, is_deleted) values (#{po.name}, #{po.money}, #{po.isDeleted})")
    int save(@Param("po") MoneyPo po);

     * @param id    id
     *@ param money
     * @return int
    @Update("update money set `money`=#{money} where id = #{id}")
    int update(@Param("id") int id, @Param("money") long money);

     *Delete data
     * @param id id
     * @return int
    @Delete("delete from money where id = #{id}")
    int delete(@Param("id") int id);

     *Primary key query
     * @param id id
     * @return {@link MoneyPo}
    @Select("select * from money where id = #{id}")
    @Results(id = "moneyResultMap", value = {
            @Result(property = "id", column = "id", id = true, jdbcType = JdbcType.INTEGER),
            @Result(property = "name", column = "name", jdbcType = JdbcType.VARCHAR),
            @Result(property = "money", column = "money", jdbcType = JdbcType.INTEGER),
            @Result(property = "isDeleted", column = "is_deleted", jdbcType = JdbcType.TINYINT),
            @Result(property = "createAt", column = "create_at", jdbcType = JdbcType.TIMESTAMP),
            @Result(property = "updateAt", column = "update_at", jdbcType = JdbcType.TIMESTAMP)})
    MoneyPo getById(@Param("id") int id);

Corresponding service class

public class MoneyService {
    private MoneyMapper moneyMapper;

    public void basicTest() {
        int id = save();
        log.info("save {}", getById(id));
        boolean update = update(id, 202L);
        log.info("update {}, {}", update, getById(id));
        boolean delete = delete(id);
        log.info("delete {}, {}", delete, getById(id));

    private int save() {
        MoneyPo po = new MoneyPo();
        po. Setname ("a gray blog");
        return po.getId();

    private boolean update(int id, long newMoney) {
        int ans = moneyMapper.update(id, newMoney);
        return ans > 0;

    private boolean delete(int id) {
        return moneyMapper.delete(id) > 0;

    private MoneyPo getById(int id) {
        return moneyMapper.getById(id);

2. Registration method

Note that after the above is written, if mapper interface is not registered through the following methods, the project startup will fail, indicating that the bean corresponding to moneymapper cannot be found

Field moneyMapper in com.git.hui.boot.mybatis.service.MoneyService required a bean of type 'com.git.hui.boot.mybatis.mapper.MoneyMapper' that could not be found.

2.1 @ mapperscan registration method

On the configuration class or startup class, add@MapperScanAnnotation to specify the package path of mapper interface, so as to realize the registration of mapper interface

@MapperScan(basePackages = "com.git.hui.boot.mybatis.mapper")
public class Application {

    public Application(MoneyService moneyService) {

    public static void main(String[] args) {

After execution, the output results are as follows

2021-07-06 19:12:57.984  INFO 1876 --- [           main] c.g.h.boot. mybatis. service. Moneyservice: save moneypo (id = 557, name = a gray blog, money = 101, isdeleted = 0, createat = 2021-07-06 19:12:57.0, updateatt = 2021-07-06 19:12:57.0)
2021-07-06 19:12:58.011  INFO 1876 --- [           main] c.g.h.boot. mybatis. service. Moneyservice: update true, moneypo (id = 557, name = a gray blog, money = 202, isdeleted = 0, createat = 2021-07-06 19:12:57.0, updateatt = 2021-07-06 19:12:57.0)
2021-07-06 19:12:58.039  INFO 1876 --- [           main] c.g.h.boot.mybatis.service.MoneyService  : delete true, null

be careful:

  • Basepackages: package path passed into mapper, array. Multiple packages can be passed in
  • The package path supports regular, such ascom.git.hui.boot.*.mapper

    • In this way, we can avoid putting all our mappers under one package path, which will lead to unfriendly reading

2.2 @ mapper registration method

ahead@MapperScanSpecify the package path of the mapper, and this annotation is directly placed on the mapper interface

public interface MoneyMapper {

Test output omitted

2.3 mappercannerconfigurer registration method

useMapperScannerConfigurerTo implement mapper interface registration. Long ago, when spring’s XML was used for bean declaration, mybatis mapper played like this

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="xxx"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>

The corresponding java code is as follows:

public class AutoConfig {
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
                //Set the location of mybatis XML. Here, the mybatis annotation method is used, and the XML file is not configured
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/*.xml"));
        return bean.getObject();

    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory storySqlSessionFactory) {
        return new SqlSessionTemplate(storySqlSessionFactory);

    public MapperScannerConfigurer mapperScannerConfigurer() {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        return mapperScannerConfigurer;

Test output omitted

3. Summary

This paper mainly introduces three registration methods of mapper interface in mybatis, including two common annotation methods

  • @MapperScan: Specifies the package path for the mapper interface
  • @Mapper: put it on the mapper interface
  • MapperScannerConfigurer: registered programmatically

So the question is, why should we introduce these three methods? In our actual business development, the first two are basically satisfied; What scenario uses the third approach?

  • For example, write a general mapper (similar to the basemapper in mybatis plus)
  • For example, in a mapper scenario with multiple data sources (such as master-slave database, hot and cold database, DB operation mapper is the same, but the underlying data sources are different)

This concludes here, with examples of the two scenes above, case, and then official account.Ash blog

3. Can not miss the source code and related knowledge points

0. Project

  • Project: https://github.com/liuyueyi/spring-boot-demo
  • Source code: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/104-mybatis-ano

1. A gray blog

The above contents are only the words of one family. Due to limited personal ability, it is inevitable that there are omissions and mistakes. If you find a bug or have better suggestions, you are welcome to criticize and correct and be grateful

The following is a gray personal blog, which records all blog posts in study and work. Welcome to visit

  • A personal blog https://blog.hhui.top
  • A gray blog spring special blog http://spring.hhui.top

[springboot + mybatis series] several methods of mapper interface registration

Recommended Today

Big data Hadoop — spark SQL + spark streaming

catalogue 1、 Spark SQL overview 2、 Sparksql version 1) Evolution of sparksql 2) Comparison between shark and sparksql 3)SparkSession 3、 RDD, dataframes and dataset 1) Relationship between the three 1)RDD 1. Core concept 2. RDD simple operation 3、RDD API 1)Transformation 2)Action 4. Actual operation 2)DataFrames 1. DSL style syntax operation 1) Dataframe creation 2. SQL […]