文件變更
本節(jié)文件變更如下
創(chuàng)建 post(文章)表
DROP TABLE IF EXISTS `post`;
CREATE TABLE `post` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`author_id` int(11) NOT NULL,
`title` varchar(100) NOT NULL,
`content` text NOT NULL,
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;
Post 類
新增 Post.java
public class Post {
private Integer id;
private User author;
private Integer authorId; // 作者的 id
private String title; // 文章標(biāo)題
private String content; // 文章內(nèi)容
private Date createTime;
// ... getter and setter
}
Controller 層
新增 PostApi.java
/**
* 文章接口
*/
@RestController
@RequestMapping("/api/post")
public class PostApi {
private PostService postService;
@Autowired
public PostApi(PostService postService) {
this.postService = postService;
}
@PostMapping("")
@LoginRequired
public Post add(@RequestBody Post post, @CurrentUser User user) {
post.setAuthorId(user.getId());
post = postService.add(post);
return post;
}
@GetMapping("/{id}")
public Object findById(@PathVariable int id) {
Post post = postService.findById(id);
if (post == null) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("message", "文章不存在");
return jsonObject;
} else {
return post;
}
}
}
add
方法用上了前兩節(jié)寫的 @LoginRequired 注解進行登錄攔截和 @CurrentUser 注解獲取當(dāng)前登錄用戶茂洒。
Service 層
新增 PostService.java
@Service
public class PostService {
private PostMapper postMapper;
@Autowired
public PostService(PostMapper postMapper) {
this.postMapper = postMapper;
}
@Transactional
public Post add(Post post) {
postMapper.add(post);
return findById(post.getId());
}
public Post findById(Integer id) {
Post param = new Post();
param.setId(id);
return postMapper.findOne(param);
}
}
這里說下 @Transactional
(事務(wù)管理)注解秤掌,假如這個這個方法里面有多個數(shù)據(jù)庫操作,想要某個操作出錯時回滾這個方法里面的所有操作,就在這個方法里面加上這個注解。比如 add
方法,假設(shè)第一步添加成功,第二步查詢失敗,因為有 @Transactional
注解的存在誓沸,拋出異常之后數(shù)據(jù)庫也會回滾到未添加時的狀態(tài)。
Mapper 接口
新增 PostMapper.java
public interface PostMapper {
int add(Post post);
Post findOne(Post param);
}
新增 PostMapper.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.hpm.blog.mapper.PostMapper">
<resultMap id="PostResultMap" type="com.hpm.blog.model.Post" autoMapping="true">
<id column="id" property="id" /> <!-- id 很重要 -->
<!--關(guān)聯(lián)作者次氨,post 表和 user 表可能會用一些字段重復(fù)蔽介,比如 id 這個屬性,所以給 user 表的字段加上columnPrefix(前綴)-->
<association property="author" autoMapping="true" columnPrefix="author__"
javaType="com.hpm.blog.model.User">
<id column="author_id" property="id" />
</association>
</resultMap>
<insert id="add" useGeneratedKeys="true" keyProperty="id">
INSERT INTO post (author_id, title, content) VALUES (#{authorId}, #{title}, #{content});
</insert>
<select id="findOne" resultMap="PostResultMap">
SELECT
post.id,
post.author_id ,
post.title ,
post.content ,
post.create_time ,
post.update_time,
<!-- 作者信息煮寡,password 不需要就不查了 -->
`user`.id as author__id,
`user`.`name` as author__name
FROM post
LEFT JOIN `user` ON `user`.id=post.author_id
<where>
<if test="id!=null">
AND post.id=#{id}
</if>
</where>
</select>
</mapper>
查詢接口用了關(guān)聯(lián)查詢虹蓄,并且寫了個 ResultMap
來映射文章和用戶的一對一關(guān)系。association
的 columnPrefix
屬性在多表查詢中特別有用幸撕。
測試
重啟項目薇组,使用 postman 發(fā)送一個 post
請求到 /api/post
不要忘了帶上
token
查看項目完整代碼
項目地址: https://github.com/hyrijk/spring-boot-blog
克隆項目到本地
git clone https://github.com/hyrijk/spring-boot-blog.git
checkout 到當(dāng)前版本
git checkout 239b170322e5734a06dde32c1648a3cde53acf8a
完。