Product Management Demo
This example uses Spring Boot,MyBatis-Plus, MySQL and Druid to implement paginated associated queries between goods and categories.
1. Prepare the database
create java2601 database and import goods.sql Table structure and test data in. The example requires at least the following two tables:
goods: Commodity list.category: Commodity Category List.
in the commodity list cid Object used to associate category tables cid。
2. Create the Spring Boot project
Introduce dependence
in pom.xml Add the following dependencies to. The version number can be managed uniformly based on the Spring Boot version of the course project.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.6</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>1.2.23</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>Configure data sources and MyBatis-Plus
in application.yml Configure database connections and MyBatis-Plus:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
druid:
url: jdbc:mysql://localhost:3306/java2601?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
initial-size: 2
min-idle: 3
max-active: 10
max-wait: 10000
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
type-aliases-package: com.hyxy.goods.po
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
# table-prefix: tb_
# logic-delete-field: deleteFlag
# logic-delete-value: 1
# logic-not-delete-value: 0The development environment can directly write user names and passwords, and the actual project should manage database credentials through environment variables or external configuration.
create a directory structure
It is recommended to subcontract according to controller, business layer, data access layer, and entity classes.

Use reverse engineering to generate basic code
may be used MyBatis-Plus The code generator generates entity classes, Mappers, Services, and corresponding XML files.

After generation, you need to check the package name, table name, primary key policy, and storage location of the generated files. You cannot directly assume that all configurations are consistent with the current project.
3. Scan the Mapper interface
Using on the startup class @MapperScan, uniformly scan the Mapper interface:
package com.hyxy.goods;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
@MapperScan("com.hyxy.goods.mapper")
public class GoodsApplication {
public static void main(String[] args) {
SpringApplication.run(GoodsApplication.class, args);
}
}use @MapperScan After that, there is usually no need to add it on each Mapper interface @Mapper。Just choose one of the two methods.
package com.hyxy.goods.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hyxy.goods.po.Category;
public interface CategoryMapper extends BaseMapper<Category> {
}package com.hyxy.goods.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.hyxy.goods.po.Goods;
public interface GoodsMapper extends BaseMapper<Goods> {
}4. Configure paging plug-ins
in config Create a configuration class in the package and register it MyBatis-Plus Page Interceptors:
package com.hyxy.goods.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}Use of this courseware MyBatis-Plus 3.5.6。If you upgrade to 3.5.9 Or higher, the parser related to paging plug-in has been split into optional dependencies, and modules need to be supplemented according to the official instructions of the corresponding version.
5. Realize related query between goods and categories
When querying products, the category name is also displayed.
Add non-table fields to the commodity entity class
cname From related query, not goods Table, so you need to use the @TableField(exist = false):
package com.hyxy.goods.po;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
@Data
public class Goods {
// 省略 goods 表中的其他字段
@TableField(exist = false)
private String cname;
}Declare query methods in the Mapper interface
Paging parameters should be placed before the method parameter list, and query criteria should be used @Param Explicit naming:
package com.hyxy.goods.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyxy.goods.po.Goods;
import org.apache.ibatis.annotations.Param;
public interface GoodsMapper extends BaseMapper<Goods> {
IPage<Goods> selectJoinCategory(
Page<Goods> page,
@Param("gname") String gname,
@Param("cid") Integer cid
);
}Writing Mapper XML
in resources/mapper Create under the directory GoodsMapper.xml。namespace Must be consistent with the fully qualified class name of the Mapper interface.
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hyxy.goods.mapper.GoodsMapper">
<select id="selectJoinCategory" resultType="Goods">
SELECT
g.gid,
g.gname,
g.price,
g.stock,
g.cid,
g.sales,
g.onsale,
g.createtime,
c.cname AS cname
FROM goods AS g
LEFT JOIN category AS c ON g.cid = c.cid
<where>
<if test="gname != null and gname != ''">
AND g.gname LIKE CONCAT('%', #{gname}, '%')
</if>
<if test="cid != null">
AND g.cid = #{cid}
</if>
</where>
ORDER BY g.gid DESC
</select>
</mapper>Table aliases should be added to columns in associated queries as much as possible to avoid ambiguity when two tables have fields with the same name.
6. Writing tests
Use the Spring Boot test class to verify paging and association query results:
package com.hyxy.goods;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hyxy.goods.mapper.GoodsMapper;
import com.hyxy.goods.po.Goods;
import jakarta.annotation.Resource;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class GoodsApplicationTests {
@Resource
private GoodsMapper goodsMapper;
@Test
void selectJoinCategory() {
Page<Goods> page = new Page<>(1, 3);
IPage<Goods> pageResult = goodsMapper.selectJoinCategory(
page,
null,
null
);
pageResult.getRecords().forEach(System.out::println);
System.out.println("总记录数:" + pageResult.getTotal());
System.out.println("总页数:" + pageResult.getPages());
}
}During testing, you should confirm that the console generates SQL with paging restrictions and check the cname Whether the mapping is correct.
7. Common questions
Mapper method cannot find corresponding SQL
Check the following:
- of XML
namespaceWhether it is consistent with the fully qualified name of the Mapper interface. <select>theidWhether it is consistent with the interface method name.mapper-locationsWhether to overwrite the directory where the XML file is located.
Pagination does not take effect
Confirm that you have registered MybatisPlusInterceptor and PaginationInnerInterceptor, and ensure that paging parameters are in front of the Mapper method parameter list.
Error reported in category number condition or abnormal query result
Using in multi-table queries g.cid, don’t write directly without table aliases cid, otherwise field ambiguity may occur.
If you enjoyed this, leave a comment~