前言
本文主要描述搭建一个spring boot简单应用的整个过程,涉及到前后端的开发。最终的应用功能较为简单,主要是对一张数据库表的简单操作和一个第三方接口的调用。
生成项目
-
打开idea,点击File>New>Project
-
选中【Spring Initializr】,然后点【Next】,设置项目的属性
-
选择项目依赖
Developer Tools > Spring Boot DevTools
Web > Spring Web
Template Engines > Thymeleaf
SQL > MyBatis Framework
SQL > MySQL Driver
Spring Cloud Routing > OpenFeign
-
点击下一步,最后完成项目创建。
-
项目建立完成后,在项目中再创建package:controller,entity,mapper,service,最终结构如下:
创建数据库
CREATE DATABASE IF NOT EXISTS `library`;
CREATE TABLE IF NOT EXISTS `library`.`book` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(10) DEFAULT NULL,
`author` VARCHAR(10) DEFAULT NULL,
`release_date` Date DEFAULT NULL,
PRIMARY KEY (`id`))
ENGINE = InnoDB;
后端配置和代码
- com.example.springbootdemo.entity.BookEntity
package com.example.springbootdemo.entity;
import org.springframework.format.annotation.DateTimeFormat;
import java.util.Date;
public class BookEntity {
private Long id;
private String name;
private String author;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date releaseDate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public Date getReleaseDate() {
return releaseDate;
}
public void setReleaseDate(Date releaseDate) {
this.releaseDate = releaseDate;
}
}
- resources下application.properties配置:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/library?useUnicode=true&serverTimezone=UTC
spring.datasource.password=密码
spring.datasource.username=账号
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
mybatis.type-aliases-package=com.example.springbootdemo.entity
#使用了聚合数据的接口(https://www.juhe.cn/)
api.key=自己的KEY
- com.example.springbootdemo.mapper.BookMapper
package com.example.springbootdemo.mapper;
import com.example.springbootdemo.entity.BookEntity;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.Date;
import java.util.List;
@Mapper
public interface BookMapper {
@Select("select * from book")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "author", column = "author"),
@Result(property = "releaseDate", column = "release_date", javaType= Date.class)
})
List<BookEntity> selectAllBooks();
@Insert("insert into book(name,author,release_date) values(#{name}, #{author}, #{releaseDate})")
void insertBook(BookEntity bookEntity);
@Select("select * from book where name like '%#{name}%'")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "author", column = "author"),
@Result(property = "releaseDate", column = "release_date", javaType= Date.class)
})
List<BookEntity> selectByName(String name);
}
- com.example.springbootdemo.service.BookService
package com.example.springbootdemo.service;
import com.example.springbootdemo.entity.BookEntity;
import com.example.springbootdemo.mapper.BookMapper;
import org.springframework.stereotype.Service;
import java.util.List;
import javax.annotation.Resource;
@Service
public class BookService {
@Resource
private BookMapper bookMapper;
public void createBook(BookEntity bookEntity) {
bookMapper.insertBook(bookEntity);
}
public List<BookEntity> listAllBooks() {
return bookMapper.selectAllBooks();
}
public List<BookEntity> listBooksByName(String name) {
return bookMapper.selectByName(name);
}
}
- com.example.springbootdemo.service.CatalogService
package com.example.springbootdemo.service;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Map;
@FeignClient(url="http://apis.juhe.cn/goodbook", name="catalog")
public interface CatalogService {
@RequestMapping(value = "/catalog", method = RequestMethod.GET)
public Map<String, Object> listCatalog(@RequestParam("key") String key);
}
- com.example.springbootdemo.controller.IndexController
package com.example.springbootdemo.controller;
import com.example.springbootdemo.entity.BookEntity;
import com.example.springbootdemo.service.BookService;
import com.example.springbootdemo.service.CatalogService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Resource;
@Controller
public class IndexController {
@Resource
private BookService bookService;
@Resource
private CatalogService catalogService;
@Value("${api.key}")
private String apiKey;
@RequestMapping("/")
public String index(Model model) {
Map<String, Object> map = new HashMap<String, Object>();
Map<String, Object> reusltMap = catalogService.listCatalog(apiKey);
model.addAttribute("catalogs", reusltMap);
List<BookEntity> books = bookService.listAllBooks();
model.addAttribute("books", books);
model.addAttribute("book", new BookEntity());
return "index";
}
@RequestMapping(value="/book", method = RequestMethod.POST)
public String addBook(@ModelAttribute(value="book") BookEntity book) {
bookService.createBook(book);
return "redirect:/";
}
}
- com.example.springbootdemo.SpringBootDemoApplication
package com.example.springbootdemo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableFeignClients
public class SpringBootDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDemoApplication.class, args);
}
}
前端
-
增加static/css/bootstrap.min.css,可以自行下载bootstrap
-
template/index.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/web/thymeleaf/layout"
layout:decorator="layouts/table-template">
<head>
<title>图书馆首页</title>
<link type="text/css" rel="stylesheet" th:href="@{/css/bootstrap.min.css}" />
</head>
<body>
<div>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">图书馆</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav" aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item" th:each="item : ${catalogs.result}">
<a class="nav-link" href="#" th:text="${item.catalog}"></a>
</li>
</ul>
</div>
</nav>
<div class="container">
<form th:action="@{/book}" th:object="${book}" method="post">
<label>书名</label>
<div class="input-group">
<input type="text" class="form-control" th:field="*{name}">
</div>
<label>作者</label>
<div class="input-group">
<input type="text" class="form-control" th:field="*{author}">
</div>
<label>出版日期</label>
<div class="input-group">
<input type="date" class="form-control" th:field="*{releaseDate}">
</div>
<div class="offset-6 pt-1 pb-1">
<button type="submit" class="btn-info">提交</button>
</div>
</form>
<table class="table">
<tr>
<th>书名</th>
<th>作者</th>
<th>出版日期</th>
</tr>
<tr th:each="prod : ${books}">
<td th:text="${prod.name}"></td>
<td th:text="${prod.author}"></td>
<td th:text="${#dates.format(prod.releaseDate,'yyyy-MM-dd')}"></td>
</tr>
</table>
</div>
</body>
</html>
运行
运行SpringBootDemoApplication,访问localhost:8080/