JAVA学习-实战2 MyBatis+Web依赖实现部门管理
はじまりですか…?だれもだれも気づかない
MyBatis+Web依赖实现部门管理
准备工作
1.创建SpringBoot工程,引入依赖:lombok、web开发起步依赖、mybatis、mysql驱动
2.创建数据库表dept,并在application.yml中配置数据库的基本信息
3.准备基础代码结构,并引入实体类Dept以及统一的响应结果封装类Result

创建数据库表的SQL语句
CREATE TABLE dept (
id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT 'ID, 主键',
name varchar(10) NOT NULL UNIQUE COMMENT '部门名称',
create_time datetime DEFAULT NULL COMMENT '创建时间',
update_time datetime DEFAULT NULL COMMENT '修改时间'
) COMMENT '部门表';
INSERT INTO dept VALUES (1,'学工部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
(2,'教研部','2024-09-25 09:47:40','2024-09-09 15:17:04'),
(3,'咨询部','2024-09-25 09:47:40','2024-09-30 21:26:24'),
(4,'就业部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
(5,'人事部','2024-09-25 09:47:40','2024-09-25 09:47:40'),
(6,'行政部','2024-11-30 20:56:37','2024-09-30 20:56:37');
基础代码结构编辑如下,主要有三层架构,MyBatis持久层定义,数据实体类封装,以及MyBatis配置文件

其中结果实体类如下所示:
//Result.java
@Data
public class Result {
private Integer code; //编码:1成功,0为失败
private String msg; //错误信息
private Object data; //数据
public static Result success() { //响应成功
Result result = new Result();
result.code = 1;
result.msg = "success";
return result;
}
public static Result success(Object object) { //带数据实体的响应成功
Result result = new Result();
result.data = object;
result.code = 1;
result.msg = "success";
return result;
}
public static Result error(String msg) { //响应失败
Result result = new Result();
result.msg = msg;
result.code = 0;
return result;
}
}
部门管理
部门列表查询
这里只写控制层的代码了
@GetMapping(value = "/dept")
public Result GetList() {
System.out.println("查询全部部门数据");
List<Dept> deptList = deptService.selectAll();
return Result.success(deptList);
}
此时我们发现了一个问题,那就是普通查询下返回结果封装的数据里创建时间和更新时间为null

这和MyBatis的封装机制有关,如果实体类属性名和数据库表查询返回字段一致,MyBatis就会自动封装,反之若不一致就会不封装
那么该如何解决这个问题呢?有以下几种方法
①注解
使用@Results和@Result注解来解决
@Results({
@Result(column = "create_time",property = "createTime"),
@Result(column = "updates_time",property = "updateTime")
})
@Select("select * from dept")
List<Dept> selectAll();
②起别名
直接在@Select注解中对不一样的列名标注别名,别名和类属性名保持一致
public interface DeptMapper {
@Select("select id, name, create_time createTime, update_time updateTime from dept")
List<Dept> selectAll();
}
③开启驼峰命名(常用,推荐)
在application.yml中开启驼峰命名规则的开关,那么如果数据表的列名和类的属性名经过驼峰映射之后一致则默认二者相同,mybatis会自动进行驼峰命名规则映射
#开启该规则后的映射如下:
#create_time → createTime
#
mybatis:
configuration:
map-underscore-to-camel-case: true
不过我为了方便直接使用XML映射配置,在其中使用别名注解
<select id="selectAll" resultType="org.example.pojo.Dept">
select id,name,create_time createTime,update_time updateTime from dept
</select>
部门删除
根据ID实现部门删除
如何接受前段传入的ID /deptdelete?id=1
方法1:通过原始的HttpServletRequest获取参数
@DeleteMapping(value="/dept")
public Result DeleteByID(HttpServletRequest request) {
int ID = Integer.parseInt(request.getParameter("id"));
System.out.println("根据ID删除部门: "+ID);
}
方法2:使用@RequestParam注解
@DeleteMapping(value="/dept")
public Result DeleteByID(@RequestParam("id") Integer ID) {
System.out.println("根据ID删除部门: "+ID);
}
值得注意的是,该方法下必须客户端必须传递id参数,否则报错400
通过设置required参数,设置为false表示不必传递,设置为true表示必须传递,一般默认设置为true
@DeleteMapping(value="/dept")
public Result DeleteByID(@RequestParam(value="id",required=false) Integer ID) {
System.out.println("根据ID删除部门: "+ID);
}
方法3:服务端响应请求方法形参名和客户端传递形参名保持一致
该情况下可以省略相关注解
@DeleteMapping(value="/dept")
public Result DeleteByID(Integer id) {
System.out.println("根据ID删除部门: "+id);
}
XML映射配置文件代码
<delete id="deleteByID" parameterType="int"> //指定传递参数类型为int
delete from dept where id = #{id}
</delete>
部门新增
接受json格式的请求数据,通常会使用一个实体对象进行接收。
规则:JSON数据的键名和方法形参对象的属性名相同,并需要使用@RequestBody注解标识
@PostMapping(value="/dept")
public Result InsertIntoList(@RequestBody Dept newDept) {
System.out.println("新增部门: "+newDept.getName());
deptService.insertIntoList(newDept);
return Result.success();
}
XML映射配置文件代码如下:
其中制定传递参数类型为封装类,并且使用了
useGeneratedKeys="true":这个属性告诉MyBatis使用JDBC的getGeneratedKeys方法来获取数据库自动生成的主键值
keyProperty="id":这个属性指定了将数据库生成的主键值设置到Java对象的id属性中。例如,我们的实体类有一个id属性,那么设置keyProperty="id"就会将数据库生成的主键值赋给实体类的id属性。
<insert id="insertIntoList" parameterType="org.example.pojo.Dept" useGeneratedKeys="true" keyProperty="id" >
insert into dept(name,create_time,update_time) values(#{name},#{createTime},#{updateTime})
</insert>
部门查询
需要根据查询的路径获取id从而返回对应的部门信息,例如/dept/3,就是返回id为3的部门信息
获取id有两种方法
方法一:通过@PathVariable注解标识路径参数
@GetMapping(value="/dept/{id}")
public Result getInfo(@PathVariable("id") Integer deptId) {
System.out.println("根据ID查询部门数据: "+deptId);
return Result.success();
}
方法二:通过@PathVariable注解标识且路径参数与响应方法传递形参一致
@GetMapping(value="/dept/{id}")
public Result getInfo(@PathVariable("id") Integer id) {
System.out.println("根据ID查询部门数据: "+id);
return Result.success();
}
XML映射配置文件代码如下:
<select id="getDeptByID" parameterType="int" resultType="org.example.pojo.Dept">
select id,name,create_time createTime,update_time updateTime from dept where id = #{id}
</select>
部门更新
接受json格式的请求数据,使用@RequestBody注解标识。
//控制层代码
@PutMapping(value="/dept")
public Result updateByID(@RequestBody Dept requestDept) {
System.out.println("Now we Update: "+requestDept.getId()+" , "+requestDept.getName());
deptService.updateByID(requestDept);
return Result.success();
}
//XML映射配置文件代码
<update id="updateByID" parameterType="org.example.pojo.Dept">
update dept set name = #{name},update_time = #{updateTime} where id = #{id}
</update>
@RequestMapping注解优化
回过头来我们看控制层代码的结构
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
// @RequestMapping(value = "/dept",method = RequestMethod.GET)
@GetMapping(value = "/dept")
public Result GetList() {
System.out.println("查询全部部门数据");
List<Dept> deptList = deptService.selectAll();
return Result.success(deptList);
}
@DeleteMapping(value="/dept")
public Result DeleteByID(@RequestParam("id") Integer ID) {
System.out.println("根据ID删除部门: "+ID);
deptService.deleteByID(ID);
return Result.success();
}
@PostMapping(value="/dept")
public Result InsertIntoList(@RequestBody Dept newDept) {
System.out.println("新增部门: "+newDept.getName());
deptService.insertIntoList(newDept);
return Result.success();
}
@GetMapping(value="/dept/{id}")
public Result getInfoByID(@PathVariable("id") Integer deptId) {
System.out.println("根据ID查询部门数据: "+deptId);
Dept deptResult = deptService.getDeptByID(deptId);
return Result.success(deptResult);
}
@PutMapping(value="/dept")
public Result updateByID(@RequestBody Dept requestDept) {
System.out.println("Now we Update: "+requestDept.getId()+" , "+requestDept.getName());
deptService.updateByID(requestDept);
return Result.success();
}
}
发现请求路径均存在都同样的前缀/dept,所以我们可以使用@RequestMapping注解优化
@RequestMapping("/dept") //在类上提出公共前缀
@RestController
public class DeptController {
@Autowired
private DeptService deptService;
// @RequestMapping(value = "/deptlist",method = RequestMethod.GET)
@GetMapping
public Result GetList() {
System.out.println("查询全部部门数据");
List<Dept> deptList = deptService.selectAll();
return Result.success(deptList);
}
@DeleteMapping
public Result DeleteByID(@RequestParam("id") Integer ID) {
System.out.println("根据ID删除部门: "+ID);
deptService.deleteByID(ID);
return Result.success();
}
@PostMapping
public Result InsertIntoList(@RequestBody Dept newDept) {
System.out.println("新增部门: "+newDept.getName());
deptService.insertIntoList(newDept);
return Result.success();
}
@GetMapping(value="/{id}") //id并非公共部门,所以保留
public Result getInfoByID(@PathVariable("id") Integer deptId) {
System.out.println("根据ID查询部门数据: "+deptId);
Dept deptResult = deptService.getDeptByID(deptId);
return Result.success(deptResult);
}
@PutMapping
public Result updateByID(@RequestBody Dept requestDept) {
System.out.println("Now we Update: "+requestDept.getId()+" , "+requestDept.getName());
deptService.updateByID(requestDept);
return Result.success();
}
}

浙公网安备 33010602011771号