“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

【SpringBoot + Mybatis series 】Mapper interface registration methods

SpringBoot project with Mybatis to operate the database, for most of the Java technology stack partners, will not be unfamiliar; As we know, using Mybatis, there will generally be the following several

  • Entity: database Entity class
  • Mapper: indicates the DB operation interface
  • Service: Service classes
  • XML file: Where SQL is written

In this blog post, we will focus on the postulate of how the Mapper interface relates to the corresponding XML file.

I. Environment preparation

1. Prepare the database

Using mysql as the instance database for this article, add a new table

CREATE TABLE `money` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) NOT NULL DEFAULT ' ' COMMENT 'Username',
  `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`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Copy the code

2. Project environment

This article is developed with SpringBoot 2.2.1.RELEASE + Maven 3.5.3 + IDEA

Pom dependencies are as follows

<dependencies>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
</dependencies>
Copy the code

Db configuration information Application.yml

spring:
  datasource:
    url: JDBC: mysql: / / 127.0.0.1:3306 / story? useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
    username: root
    password:
Copy the code

II. Example demonstration

The establishment of the previous basic environment is completed, and the next step is to prepare the Entity of Mybatis,Mapper and other basic classes

1. Entity class,Mapper class

Database entity class MoneyPo

@Data
public class MoneyPo {
    private Integer id;

    private String name;

    private Long money;

    private Integer isDeleted;

    private Timestamp createAt;

    private Timestamp updateAt;
}
Copy the code

Corresponding Mapper interface (CURD is implemented using annotations directly 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);

    /** * update **@param id    id
     * @paramMoney 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);
}
Copy the code

Corresponding Service class

@Slf4j
@Service
public class MoneyService {
    @Autowired
    private MoneyMapper moneyMapper;

    public void basicTest(a) {
        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(a) {
        MoneyPo po = new MoneyPo();
        po.setName("A Gray Blog");
        po.setMoney(101L);
        po.setIsDeleted(0);
        moneyMapper.save(po);
        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) {
        returnmoneyMapper.getById(id); }}Copy the code

2. Registration method

Note that if you do not register the Mapper interface in any of the following ways, the project will fail to start, 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.
Copy the code

2.1 @mapperscan Registration mode

In the configuration class or startup class, add @mapperscan annotation 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")
@SpringBootApplication
public class Application {

    public Application(MoneyService moneyService) {
        moneyService.basicTest();
    }

    public static void main(String[] args) { SpringApplication.run(Application.class); }}Copy the code

The output is as follows

The 19:12:57 2021-07-06. 1876-984 the INFO [main] C.G.H.B oot. Mybatis. Service. MoneyService: Save MoneyPo(id=557, name= a blog, money=101, isDeleted=0, createAt=2021-07-06 19:12:57.0, UpdateAt = 2021-07-06 19:12:57. 0) 19:12:58 2021-07-06. 1876-011 the INFO [main] C.G.H.B oot. Mybatis. Service. MoneyService: Update true, MoneyPo(id=557, name= a gray blog, money=202, isDeleted=0, createAt=2021-07-06 19:12:57.0, MoneyPo(id=557, money=202, isDeleted=0, createAt=2021-07-06 19:12:57.0, UpdateAt = 2021-07-06 19:12:57. 0) 19:12:58 2021-07-06. 1876-039 the INFO [main] C.G.H.B oot. Mybatis. Service. MoneyService: delete true, nullCopy the code

Note:

  • BasePackages: Package paths passed to Mapper
  • Package paths support re, such ascom.git.hui.boot.*.mapper
    • This way, we avoid putting all of our Mappers in one package path, which would be unreadable

2.2 @mapper Registration Mode

The previous @mapperscan annotation specifies the mapper package path, and this annotation is placed directly on the Mapper interface

@Mapper
public interface MoneyMapper {... }Copy the code

Test output omitted…

2.3 MapperScannerConfigurer Registration mode

You can register the Mapper interface with MapperScannerConfigurer, which is how MyBatis’s Mapper worked long ago, when Spring XML was used to declare beans

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

The corresponding Java code is as follows:

@Configuration
public class AutoConfig {
    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(
                // Set the XML location of Mybatis
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapping/*.xml"));
        return bean.getObject();
    }

    @Bean("sqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory storySqlSessionFactory) {
        return new SqlSessionTemplate(storySqlSessionFactory);
    }

    @Bean
    public MapperScannerConfigurer mapperScannerConfigurer(a) {
        MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
        mapperScannerConfigurer.setBasePackage("com.git.hui.boot.mybatis.mapper");
        mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
        mapperScannerConfigurer.setSqlSessionTemplateBeanName("sqlSessionTemplate");
        returnmapperScannerConfigurer; }}Copy the code

Test output omission

3. Summary

This paper mainly introduces three registration methods of Mapper interface in Mybatis, including two common annotation methods

  • @MapperScan: Specifies the packet path of the Mapper interface
  • @Mapper: Placed on a Mapper interface
  • MapperScannerConfigurer: Register programmatically

So the question comes, why to introduce these three ways, our actual business development, the first two basically meet; What scenario would use the third method?

  • Write a general Mapper (similar to BaseMapper in Mybatis-Plus)
  • Such as a Mapper, multi-data source scenario (such as master/slave library, hot/cold library, DB operation Mapper is consistent, but the underlying data source is different)

This is the end of this article, about the above two scenes of the case, later when free to fill, I am a Gray, goodbye (welcome to pay attention to Changcao’s public account a gray blog)

III. Can’t miss the source code and related knowledge points

0. Project

  • Project: github.com/liuyueyi/sp…
  • Source: github.com/liuyueyi/sp…

1. An ashy Blog

As far as the letter is not as good, the above content is purely one’s opinion, due to the limited personal ability, it is inevitable that there are omissions and mistakes, if you find bugs or have better suggestions, welcome criticism and correction, don’t hesitate to appreciate

Below a gray personal blog, record all the study and work of the blog, welcome everyone to go to stroll

  • A grey Blog Personal Blog blog.hhui.top
  • A Grey Blog-Spring feature Blog Spring.hhui.top