Spring Boot + MyBatis + thymeleaf for simple message board applications
This project mainly introduces the use of spring Boot + MyBatis + Thymeleaf + Bootstrap to implement a simple delete and modify (CRUD) message Board application. Advanced people can skip directly.
Source code: Https://github.com/qingwenwei/spring-boot-crud-example
function Introduction
Publish a list of posts and posts
Edit a Post
Building projects with Spring INITIALIZR
Spring INITIALIZR is a web-based tool for quickly building a spring boot project.
- Login Https://start.spring.io
- Select the dependencies you want.
- Click Generate Project to download the item compression package.
Import Project
This tutorial uses eclipse as the IDE.
- Unzip the compressed package.
- Import the project, such as.
- Select the project root directory (the directory where the Pom.xml file resides).
Configuring the MySQL Database
In the local MySQL database, create a user named root
password for root
the user.
Create a database named crudDemoDB
empty (schema), using the UTF8 encoding format to be more friendly to Chinese character storage:
CREATE DATABASE crudDemoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Configuration file
Maven Dependency Management profile: Pom.xml
<?xml version= "1.0" encoding= "UTF-8"? ><project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http ://www.w3.org/2001/XMLSchema-instance "xsi:schemalocation=" http://maven.apache.org/POM/4.0.0/http Maven.apache.org/xsd/maven-4.0.0.xsd "> <modelVersion>4.0.0</modelVersion> <groupId> Com.example</groupid> <artifactId>demo</artifactId> <version>0.0.1-snapshot</version > <packaging>jar</packaging> <name>demo</name> <description>demo Project for SPR ing boot</description> <parent> <groupId>org.springframework.boot</groupId> <a Rtifactid>spring-boot-starter-parent</artifactid> <version>2.0.1.RELEASE</version> < Relativepath/> <!--lookup parent from repository to </parent> <properties> <project .build.sourceencoding>utf-8</project.build.sourceencoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1. 8</java.version> </properties> <dependencies> <dependency> <groupId> Org.springframework.boot</groupid> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <ARTIFACTID>MYBATIS-SPRING-BOOT-STARTER&L t;/artifactid> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupid>org.springframework.boot</ Groupid> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scop e> </dependency> </dependencies> <build> <plugins> <plugin> ; <groupId>org.springframework.boot</groupId> <artifactid>spring-boot-maven-plugin</arti factid> </plugin> </plugins> </build></project>
Configuration file for Spring boot app: src/main/resources/application.properties
# databasespring.datasource.driverClassName = com.mysql.jdbc.Driverspring.datasource.url = jdbc:mysql://localhost:3306/crudDemoDB?useSSL=false&useUnicode=true&characterEncoding=UTF-8spring.datasource.username = rootspring.datasource.password = rootspring.datasource.initialization-mode=always# MyBatismybatis.type-aliases-package=com.example.demo.modelmybatis.config-locations=classpath:mybatis/mybatis-config.xmlmybatis.mapper-locations=classpath:mybatis/mapper/*.xml# thymeleafspring.thymeleaf.cache=falsespring.thymeleaf.mode=HTML
MyBatis
Under resources
new directory, under new directory mybatis
mybatis
mapper
. Also, add the following two files.
Configuration file for MyBatis: Src/main/resources/mybatis/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> <typeAliases> <typeAlias alias="Integer" type="java.lang.Integer" /> <typeAlias alias="Long" type="java.lang.Long" /> <typeAlias alias="String" type="java.lang.String" /> <typeAlias alias="HashMap" type="java.util.HashMap" /> <typeAlias alias="Date" type="java.util.Date" /> <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" /> <typeAlias alias="ArrayList" type="java.util.ArrayList" /> <typeAlias alias="LinkedList" type="java.util.LinkedList" /> </typeAliases></configuration>
Mapper File: Src/main/resources/mybatis/mapper/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.example.demo.dao.PostDao" > <resultmap id= "postresultmap" type= " Com.example.demo.model.Post "> <id property=" id "column=" post_id "/> <result property=" title "Colu mn= "Post_title"/> <result property= "content" column= "post_content"/> <result property= "CreationD Ate "column=" post_creation_date "/> </resultMap> <insert id=" save "> insert INTO ' t_post ' (title , content, CreationDate) VALUES (#{title}, #{content}, #{creationdate}) </insert> <select id= "FindAll" resultmap= "Postresultmap" > select P.id as post_id, p.title as Post_title, P.con Tent as Post_content, p.creationdate as post_creation_date from T_post p ORDER by p.creationdate DESC </select> <select id= "Find" resultmap= "Postresultmap" > select P.id as post_id, P.title as Post_title, p.content as Post_content, p.creationdate as Post_creation_date from T_post p WHERE p.id = #{postid} </select> <update id= "Update" parametertype= "Com.example.demo.mo Del. Post "> UPDATE t_post SET title = #{title}, content = #{content} where id = #{id} </update> <delete id= "delete" parametertype= "Long" > Delete from t_post WHERE id = #{postid} </delete></mapper>
DAO layer
The DAO interface method needs to correspond to the above mapper.
Src/main/java/com/example/demo/dao/postdao.java
package com.example.demo.dao;import java.util.List;import org.apache.ibatis.annotations.Mapper;import com.example.demo.model.Post;@Mapperpublic interface PostDao { void save(Post post); void delete(Long postId); void update(Post post); Post find(Long postId); List<Post> findAll(); }
Entity class
Src/main/java/com/example/demo/model/post.java
Package Com.example.demo.model;import Java.io.serializable;import Java.sql.timestamp;public class Post implements Serializable {private static final long serialversionuid = 1L; Private Long ID; Private String title; Private String content; Private Timestamp CreationDate; Public Long GetId () {return id; } public void SetId (Long id) {this.id = ID; } public String GetTitle () {return title; public void Settitle (String title) {this.title = title; } public String GetContent () {return content; The public void SetContent (String content) {this.content = content; } public Timestamp Getcreationdate () {return creationdate; } public void Setcreationdate (Timestamp creationdate) {this.creationdate = CreationDate; } @Override Public String toString () {return "Post [id=" + ID + ", title=" + title + ", content=" + content +", creationdate=" + CreationDate + "]"; } }
Business Logic Layer
Interface design
Src/main/java/com/example/demo/service/postservice.java
package com.example.demo.service;import java.util.Map;import com.example.demo.model.Post;public interface PostService { void createPost(Post post); void deletePost(Long postId); void updatePost(Post post); Map<String, Object> findPost(Long postId); Map<String, Object> findAllPosts(); }
Specific implementation
Src/main/java/com/example/demo/service/impl/postserviceimpl.java
Package Com.example.demo.service.impl;import Java.sql.timestamp;import Java.util.hashmap;import java.util.List; Import Java.util.map;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.stereotype.service;import Org.springframework.transaction.annotation.transactional;import Com.example.demo.dao.postdao;import Com.example.demo.model.post;import com.example.demo.service.postservice;@ Service ("Postservice") @Transactionalpublic class Postserviceimpl implements postservice{@Autowired private Postdao Postdao; @Override public void Createpost (post post) {Post.setcreationdate (New Timestamp (System.currenttimemillis ())); This.postDao.save (POST); } @Override public void Deletepost (Long postid) {this.postDao.delete (PostID); } @Override public void Updatepost (post post) {this.postDao.update (POST); } @Override public map<string, object> findpost (Long postid) {map<string, OBJect> attributes = new hashmap<> (); Post post = This.postDao.find (PostID); Attributes.put ("Post", post); return attributes; } @Override public map<string, object> findallposts () {map<string, object> attributes = new Hashmap<> (); list<post> allposts = This.postDao.findAll (); All posts Attributes.put ("posts", allposts); Provide a new data transfer object Attributes.put ("Postdto", New Post ()); return attributes; } }
Controller
Src/main/java/com/example/demo/controller/postcontroller.java
Package Com.example.demo.controller;import Java.util.map;import Javax.validation.valid;import Org.slf4j.Logger; Import Org.slf4j.loggerfactory;import Org.springframework.beans.factory.annotation.autowired;import Org.springframework.stereotype.controller;import Org.springframework.ui.model;import Org.springframework.web.bind.annotation.modelattribute;import Org.springframework.web.bind.annotation.pathvariable;import Org.springframework.web.bind.annotation.requestmapping;import Org.springframework.web.bind.annotation.requestmethod;import Com.example.demo.model.post;import Com.example.demo.service.PostService; @Controllerpublic class Postcontroller {public static final Logger Logger = L Oggerfactory.getlogger (Postcontroller.class); @Autowired private Postservice Postservice; /* Create a new post */@RequestMapping (value = "/posts", method = requestmethod.post) public String creat EPost (model model, @Valid @ModelAttribute ("Postdto") post post) {Logger.info ("Creating post >>" + post); This.postService.createPost (POST); return "Redirect:/posts"; }/* * Delete a post */@RequestMapping (value = "/posts/{postid}", method = Requestmethod.delete) Pub Lic String Deletepost (@PathVariable ("PostID") Long PostID) {logger.info ("Deleting Post ID:" + postid); This.postService.deletePost (PostID); return "Redirect:/posts"; }/* Update a post */@RequestMapping (value = "/posts", method = requestmethod.put) Public String u Pdatepost (@Valid @ModelAttribute ("Postdto") post post) {Logger.info ("Updating post >>" + post); This.postService.updatePost (POST); return "Redirect:/posts"; }/* * List all Posts */@RequestMapping (value = "/posts", method = requestmethod.get) public String Listallposts (model model) {Logger.info ("litsing all Posts ..."); map<string, object> attributes = This.postseRvice.findallposts (); Model.addallattributes (attributes); return "Post-index"; }/* Display post Details */@RequestMapping (value = "/posts/{postid}", method = Requestmethod.get) Public String Displaypostdetails (model model, @PathVariable ("PostID") Long PostID) {logger.info ("Displaying post Details >> PostID: "+ PostID); map<string, object> attributes = This.postService.findPost (PostID); Model.addallattributes (attributes); return "Post-details"; } }
Spring Boot Entry Class
Src/main/java/com/example/demo/demoapplication.java
package com.example.demo;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); }}
SQL script
Spring Boot checks the resources
directory for two SQL script files that are well-known in the catalog at run time schema.sql
data.sql
, and executes these two files after the database connection pool is established.
Src/main/resources/schema.sql
DROP TABLE IF EXISTS `T_POST`;CREATE TABLE `T_POST`( `id` BIGINT NOT NULL AUTO_INCREMENT, `title` VARCHAR(255) NOT NULL, `content` TEXT, `creationDate` DATETIME, PRIMARY KEY (`id`));
Src/main/resources/data.sql
INSERT INTO `T_POST` (title, content, creationDate) VALUES (‘测试标题1‘, ‘测试正文1‘, ‘2018-01-23‘);INSERT INTO `T_POST` (title, content, creationDate) VALUES (‘测试标题2‘, ‘测试正文2‘, ‘2018-01-25‘);
Front Page
The front page code is not posted here. Interested friends can download the project code to see.
Posts List page
src/main/resources/templates/post-index.html
Post Content
src/main/resources/templates/post-details.html
Import Bootstrap and jquery via CDN
src/main/resources/templates/head.html
Source
Source code: Https://github.com/qingwenwei/spring-boot-crud-example
Spring Boot + MyBatis + thymeleaf for simple message board applications