Spring boot + MyBatis 查询返回Map时设置值为null的字段也在结果集中

本文解决了一个在SpringBoot结合MyBatis项目中遇到的问题:如何确保查询返回的Map包含值为null的字段。通过加载XML配置文件并设置callSettersOnNulls参数为true来实现。

Spring boot + MyBatis 查询返回Map时设置值为null的字段也在结果集中


参考:

http://blog.youkuaiyun.com/abc_email/article/details/49641073

http://blog.youkuaiyun.com/massivestars/article/details/53064158


最近项目中因为直接使用map返回查询数据,导致如果查询出来的数据为 null 时map中会缺少相应的属性,经过各种查资料尝试才解决,


在代码中尝试了设置 SqlSessionFactoryBean  中的 setConfigurationProperties 属性无果

尝试了再application.yml 文件中配置 mybatis:callSettersOnNulls:true 也无效


最后通过代码加载xml 配置文件的方式解决


SqlSessionFactoryBean bean = new SqlSessionFactoryBean();

bean.setConfigLocation(new ClassPathResource("mybatis-config.xml"));



<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全局参数 -->
<settings>
<setting name="callSettersOnNulls" value="true" />
</settings>


</configuration>



<think>我们被要求整合Spring Boot + MyBatis + Swagger。这是一个常见的Java Web开发技术栈组合。 我们将创建一个简单的Spring Boot项目,集成MyBatis(用于数据访问)和Swagger(用于API文档)。 步骤如下: 1. 创建Spring Boot项目 2. 添加相关依赖(Spring Boot, MyBatis, Swagger, 数据库驱动等) 3. 配置数据源和MyBatis 4. 创建实体类、Mapper接口和Mapper XML文件 5. 创建Service和Controller 6. 配置Swagger 7. 运行并测试 下面我们逐步实现: 步骤1:创建Spring Boot项目 可以使用Spring Initializr(https://start.spring.io/)创建一个基础的Spring Boot项目,选择以下依赖: - Spring Web - MyBatis Framework - MySQL Driver (这里以MySQL为例,也可以选择其他数据库) 步骤2:添加Swagger依赖 在pom.xml中添加Swagger相关依赖(这里使用Swagger2): ```xml <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency> ``` 步骤3:配置数据源和MyBatis 在application.properties(或application.yml)中配置数据源和MyBatis: ```properties # 数据源配置 spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver # MyBatis配置 # 指定Mapper.xml文件位置 mybatis.mapper-locations=classpath:mapper/*.xml # 指定实体类所在的包 mybatis.type-aliases-package=com.example.demo.entity ``` 步骤4:创建实体类、Mapper接口和Mapper XML文件 假设我们有一个User实体类: 实体类:User.java ```java package com.example.demo.entity; public class User { private Long id; private String name; private Integer age; // 省略getter和setter } ``` Mapper接口:UserMapper.java ```java package com.example.demo.mapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.Mapper; import java.util.List; @Mapper public interface UserMapper { List<User> findAll(); } ``` Mapper XML文件:在resources/mapper目录下创建UserMapper.xml ```xml <?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.demo.mapper.UserMapper"> <select id="findAll" resultType="User"> select * from user </select> </mapper> ``` 步骤5:创建Service和Controller Service接口:UserService.java ```java package com.example.demo.service; import com.example.demo.entity.User; import java.util.List; public interface UserService { List<User> findAll(); } ``` Service实现:UserServiceImpl.java ```java package com.example.demo.service.impl; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> findAll() { return userMapper.findAll(); } } ``` Controller:UserController.java ```java package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/list") public List<User> list() { return userService.findAll(); } } ``` 步骤6:配置Swagger 创建Swagger配置类:SwaggerConfig.java ```java package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")) // 指定controller存放的目录 .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot整合Swagger") .description("Spring Boot整合Swagger,详细信息......") .version("1.0.0") .build(); } } ``` 步骤7:运行并测试 启动Spring Boot应用,访问Swagger UI:http://localhost:8080/swagger-ui.html 注意:确保数据库中有user表,并且有数据。 以上就是一个简单的Spring Boot + MyBatis + Swagger的整合示例。 但是,请注意,在实际开发中,我们可能还需要考虑事务管理、异常处理、日志、分页等。这里只是一个最基础的整合。 相关问题: 1. 如何配置MyBatis的驼峰命名转换? 2. 如何在Spring Boot中配置多数据源? 3. 如何对Swagger进行安全配置(比如添加登录认证)? 4. 如何整合MyBatis-Plus来简化MyBatis的开发? </think> 以下是一个完整的Spring Boot + MyBatis + Swagger整合方案,包含详细代码和解释: ### 解决方案 我们将创建一个简单的用户管理系统,包含以下模块: 1. Spring Boot基础框架 2. MyBatis操作MySQL数据库 3. Swagger生成API文档 4. RESTful接口示例 --- ### 1. 项目结构 ``` src ├── main │ ├── java │ │ └── com │ │ └── example │ │ └── demo │ │ ├── config │ │ │ └── SwaggerConfig.java │ │ ├── controller │ │ │ └── UserController.java │ │ ├── entity │ │ │ └── User.java │ │ ├── mapper │ │ │ └── UserMapper.java │ │ ├── service │ │ │ ├── UserService.java │ │ │ └── impl │ │ │ └── UserServiceImpl.java │ │ └── DemoApplication.java │ └── resources │ ├── mapper │ │ └── UserMapper.xml │ ├── application.yml │ └── schema.sql ``` --- ### 2. 核心代码实现 #### 依赖 (`pom.xml`) ```xml <dependencies> <!-- Spring Boot Starter --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- MyBatis + MySQL --> <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> <scope>runtime</scope> </dependency> <!-- Swagger --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>3.0.0</version> </dependency> <!-- Lombok --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> </dependencies> ``` #### 配置文件 (`application.yml`) ```yaml server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/demo_db?useSSL=false&serverTimezone=UTC username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver mybatis: mapper-locations: classpath:mapper/*.xml # MyBatis映射文件位置 configuration: map-underscore-to-camel-case: true # 自动驼峰命名转换 # 初始化数据库脚本 spring.sql.init.mode: always ``` #### 数据库初始化 (`schema.sql`) ```sql CREATE TABLE IF NOT EXISTS users ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, email VARCHAR(50) NOT NULL UNIQUE, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com'), ('李四', 'lisi@example.com'); ``` #### 实体类 (`User.java`) ```java package com.example.demo.entity; import lombok.Data; import java.time.LocalDateTime; @Data public class User { private Integer id; private String name; private String email; private LocalDateTime createdAt; } ``` #### Mapper接口 (`UserMapper.java`) ```java package com.example.demo.mapper; import com.example.demo.entity.User; import org.apache.ibatis.annotations.*; import java.util.List; @Mapper public interface UserMapper { @Select("SELECT * FROM users") List<User> findAll(); @Insert("INSERT INTO users(name, email) VALUES(#{name}, #{email})") @Options(useGeneratedKeys = true, keyProperty = "id") int insert(User user); @Delete("DELETE FROM users WHERE id = #{id}") int deleteById(Integer id); } ``` #### Service层 (`UserService.java` 和 `UserServiceImpl.java`) ```java // UserService.java package com.example.demo.service; import com.example.demo.entity.User; import java.util.List; public interface UserService { List<User> getAllUsers(); void createUser(User user); void deleteUser(Integer id); } // UserServiceImpl.java package com.example.demo.service.impl; import com.example.demo.entity.User; import com.example.demo.mapper.UserMapper; import com.example.demo.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public List<User> getAllUsers() { return userMapper.findAll(); } @Override public void createUser(User user) { userMapper.insert(user); } @Override public void deleteUser(Integer id) { userMapper.deleteById(id); } } ``` #### Controller (`UserController.java`) ```java package com.example.demo.controller; import com.example.demo.entity.User; import com.example.demo.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/api/users") @Api(tags = "用户管理接口") public class UserController { @Autowired private UserService userService; @GetMapping @ApiOperation("获取所有用户") public List<User> getAllUsers() { return userService.getAllUsers(); } @PostMapping @ApiOperation("创建新用户") public void createUser(@RequestBody User user) { userService.createUser(user); } @DeleteMapping("/{id}") @ApiOperation("删除用户") public void deleteUser(@PathVariable Integer id) { userService.deleteUser(id); } } ``` #### Swagger配置 (`SwaggerConfig.java`) ```java package com.example.demo.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; @Configuration public class SwaggerConfig { @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.demo.controller")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("用户管理系统API文档") .description("Spring Boot整合MyBatis和Swagger示例") .version("1.0.0") .build(); } } ``` #### 主启动类 (`DemoApplication.java`) ```java package com.example.demo; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("com.example.demo.mapper") // 扫描Mapper接口 public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` --- ### 3. 功能验证 1. 启动应用:运行 `DemoApplication` 2. 访问Swagger UI:`http://localhost:8080/swagger-ui/` 3. 测试接口: - GET `/api/users` 获取用户列表 - POST `/api/users` 创建用户 - DELETE `/api/users/{id}` 删除用户 --- ### 4. 关键点解释 1. **MyBatis集成**: - `@MapperScan` 自动扫描Mapper接口 - `mapper-locations` 配置XML映射文件路径 - 驼峰命名自动转换简化字段映射 2. **Swagger配置**: - `@Api`标注控制器分类 - `@ApiOperation`标注接口功能 - 访问路径 `/swagger-ui/` 3. **RESTful设计**: - 使用标准HTTP方法 (GET/POST/DELETE) - 资源化URL设计 (`/api/users`) --- ###
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值