首先我们引入依赖
compile group: 'org.springframework.boot', name: 'spring-boot-starter-thymeleaf', version: '2.4.2'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-data-jpa', version: '2.4.2'
runtimeOnly 'mysql:mysql-connector-java'
我们以Article为例来说明如何使用spring data jpa 和 thymeleaf
创建相关的表,因为jpa本省也可以通过对象来创建表,所以先创建对象,先创建表都可以
CREATE TABLE `article` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(255) CHARACTER SET armscii8 COLLATE armscii8_bin NULL DEFAULT NULL,
`content` text CHARACTER SET armscii8 COLLATE armscii8_bin NULL,
`author` varchar(255) CHARACTER SET armscii8 COLLATE armscii8_bin NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = armscii8 COLLATE = armscii8_bin ROW_FORMAT = Dynamic;
通过创建的表可以在idea中很方便的生成实体类和持久Repository
@Repository
public interface ArticleRepository extends JpaRepository<Article, Integer>, JpaSpecificationExecutor<Article> {
}
@Entity
@Table(name = "article")
@Data
@EqualsAndHashCode()
public class Article implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "title")
private String title;
@Column(name = "content")
private String content;
@Column(name = "author")
private String author;
@Override
public String toString() {
return "Article{" +
"id=" + id + '\'' +
"title=" + title + '\'' +
"content=" + content + '\'' +
"author=" + author + '\'' +
'}';
}
}
application.properties中配置数据库链接和thymeleaf,thymeleaf也可以不用配置,默认是开启的。
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/springboot?serverTimezone=UTC&useSSL=false
spring.datasource.username=root
spring.datasource.password=123456
#thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.enabled=true
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
在新建一个article_list.html 展示文章列表
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head><title>文章列表</title></head>
<body>
<h1>文章列表</h1>
<table>
<thead>
<tr>
<th>id</th>
<th>标题</th>
<th>作者</th>
<th>内容</th>
</tr>
</thead>
<tbody>
<tr th:each="item: ${articles}">
<td th:text="${item.id}"></td>
<td th:text="${item.title}"></td>
<td th:text="${item.author}"></td>
<td th:text="${item.content}"></td>
</tr>
</tbody>
</table>
</body>
</html>
ok 大工搞成,我们已经学会使用thymeleaf和Spring Data JPA了,非常的简单。接下来我们使用mock测试增删改
package com.example.springboot.controller;
import com.example.springboot.model.Article;
import com.example.springboot.repository.ArticleRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/article/")
public class ArticleController {
@Autowired
ArticleRepository articleRepository;
@GetMapping("/findAll")
private String findAllArticle(Model model){
List<Article> articles= articleRepository.findAll();
model.addAttribute("articles",articles);
return "article_list";
}
@PostMapping(value="/save")
private ResponseEntity<Article> save(@RequestBody Article article){
Article add= articleRepository.save(article);
return new ResponseEntity<Article>(add, HttpStatus.CREATED);
}
@PutMapping("/update")
private ResponseEntity<Article> update(@RequestBody Article article){
return new ResponseEntity<Article>(articleRepository.save(article), HttpStatus.OK);
}
@DeleteMapping("/delete/{id}")
private ResponseEntity<HttpStatus> delete(@PathVariable("id") Integer id){
articleRepository.deleteById(id);
return new ResponseEntity<HttpStatus>(HttpStatus.ACCEPTED);
}
}
使用springboot测试,模拟http请求,并和方法的返回值作比较来验证程序的正确性。
package com.example.springboot;
import com.example.springboot.model.Article;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
@AutoConfigureMockMvc
public class ArticleCrudTest {
@Autowired
private MockMvc mvc;
@Test
public void testSave() throws Exception {
mvc.perform(MockMvcRequestBuilders
.post("/article/save")
.content(asJsonString(new Article(null, "math", "数学", "张衡")))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isCreated())
.andExpect(MockMvcResultMatchers.jsonPath("$.id").exists())
.andReturn().getResponse().getOutputStream();
}
@Test
public void testUpdate() throws Exception {
mvc.perform(MockMvcRequestBuilders
.put("/article/update")
.content(asJsonString(new Article(2, "java", "java开发实战经典", "李新")))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.content").value("java开发实战经典"));
}
@Test
public void testDelete() throws Exception {
mvc.perform(MockMvcRequestBuilders.delete("/article/delete/{id}", 1))
.andExpect(status().isAccepted());
}
public static String asJsonString(final Object obj) {
try {
return new ObjectMapper().writeValueAsString(obj);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
我们使用rest风格的形式实现springboot工程的增删改查了,到目前位置我们没有做很多的配置,注意我们在跳转到thymeleaf页面时使用的时@Controller而不是@RestController