[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`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
2. Project environment
With the help ofSpringBoot 2.2.1.RELEASE
+ maven 3.5.3
+ IDEA
Develop
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>
DB configuration informationapplication.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:
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
@Data
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);
/**
*Renew
*
* @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
@Slf4j
@Service
public class MoneyService {
@Autowired
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");
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) {
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@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);
}
}
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 as
com.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@MapperScan
Specify the package path of the mapper, and this annotation is directly placed on the mapper interface
@Mapper
public interface MoneyMapper {
...
}
Test output omitted
2.3 mappercannerconfigurer registration method
useMapperScannerConfigurer
To 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"/>
</bean>
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 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();
}
@Bean("sqlSessionTemplate")
public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory storySqlSessionFactory) {
return new SqlSessionTemplate(storySqlSessionFactory);
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setBasePackage("com.git.hui.boot.mybatis.mapper");
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
mapperScannerConfigurer.setSqlSessionTemplateBeanName("sqlSessionTemplate");
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 interfaceMapperScannerConfigurer
: 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