Spring Boot + MyBatis + Thymeleaf实现简单留言板应用

Spring Boot + MyBatis + Thymeleaf实现简单留言板应用

本项目主要介绍使用Spring Boot + MyBatis + Thymeleaf + Bootstrap来实现一个简单的增删改查(CRUD)留言板应用。高阶人士可以直接跳过。

源代码:https://github.com/qingwenwei/spring-boot-crud-example

功能介绍

发表帖子、帖子列表

编辑帖子

使用Spring Initializr构建项目

Spring Initializr是一个基于web的快速构建Spring Boot项目的工具。

  1. 登录https://start.spring.io
  2. 选择需要的依赖。
  3. 点击Generate Project下载项目压缩包。

导入项目

本教程使用eclipse作为IDE。

  1. 解压压缩包。
  2. 导入项目,如下图。
  3. 选择项目根目录(pom.xml文件所在的目录)。

配置MySQL数据库

在本地MySQL数据库创建用户名为root密码为root的用户。

创建一个名为crudDemoDB空的数据库(schema),使用UTF8编码格式是为了对汉字存储更友好:

CREATE DATABASE crudDemoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

配置文件

maven依赖管理配置文件: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 Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </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</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</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

Spring Boot应用的配置文件:src/main/resources/application.properties

# database
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/crudDemoDB?useSSL=false&useUnicode=true&characterEncoding=UTF-8
spring.datasource.username = root
spring.datasource.password = root
spring.datasource.initialization-mode=always

# MyBatis
mybatis.type-aliases-package=com.example.demo.model
mybatis.config-locations=classpath:mybatis/mybatis-config.xml
mybatis.mapper-locations=classpath:mybatis/mapper/*.xml

# thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.mode=HTML

MyBatis

resources下新建目录mybatismybatis下新建目录mapper。同时,添加以下两个文件。

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文件: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" column="post_title"/>
        <result property="content" column="post_content"/>
        <result property="creationDate" 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.content 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.model.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层

Dao接口的方法需要与上面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;

@Mapper
public interface PostDao {

    void save(Post post);

    void delete(Long postId);

    void update(Post post);

    Post find(Long postId);

    List<Post> findAll();

}

实体类

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;
    }

    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 + "]";
    }

}

业务逻辑层

接口设计

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();

}

具体实现

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")
@Transactional
public 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;
    }

}

控制器

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;

@Controller
public class PostController {

    public static final Logger logger = LoggerFactory.getLogger(PostController.class);

    @Autowired
    private PostService postService;

    /*
     * Create a new post
     */
    @RequestMapping(value = "/posts", method = RequestMethod.POST)
    public String createPost(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)
    public 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 updatePost(@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入口类

src/main/java/com/example/demo/DemoApplication.java

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

SQL脚本

Spring Boot在运行时会检查在resources目录下是否有名为schema.sqldata.sql的两个SQL脚本文件,并且在数据库连接池建立后执行这两个文件。

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‘);

前端页面

前端页面代码在这里就不一一贴出来了。感兴趣的朋友可以下载项目代码来看看。

帖子列表页面

src/main/resources/templates/post-index.html

帖子内容

src/main/resources/templates/post-details.html

通过CDN导入bootstrap和jQuery

src/main/resources/templates/head.html

源代码

源代码:https://github.com/qingwenwei/spring-boot-crud-example

原文地址:https://www.cnblogs.com/weicee/p/8934385.html

时间: 2024-11-12 06:41:56

Spring Boot + MyBatis + Thymeleaf实现简单留言板应用的相关文章

spring boot+mybatis整合

LZ今天自己搭建了下Spring boot+Mybatis,比原来的Spring+SpringMVC+Mybatis简单好多.其实只用Spring boot也可以开发,但是对于多表多条件分页查询,Spring boot就有点力不从心了,所以LZ把Mybatis整合进去,不得不说,现在的框架搭建真的是方便.话不多说,进入正题. 一.java web开发环境搭建 网上有很多教程,参考教程:http://www.cnblogs.com/Leo_wl/p/4752875.html 二.Spring bo

[转] Druid简介(Spring Boot + Mybatis + Druid数据源【自己定制】)

Druid的简介Druid是一个非常优秀的数据库连接池.在功能.性能.扩展性方面,都超过其他数据库连接池,包括DBCP.C3P0.BoneCP.Proxool.JBoss DataSource. Druid已经在阿里巴巴部署了超过600个应用,经过一年多生产环境大规模部署的严苛考验. Druid是一个JDBC组件,它包括三个部分: 基于Filter-Chain模式的插件体系. DruidDataSource 高效可管理的数据库连接池. SQLParser Druid的功能兼容DBCPDruid提

spring boot + mybatis + druid

因为在用到spring boot + mybatis的项目时候,经常发生访问接口卡,服务器项目用了几天就很卡的甚至不能访问的情况,而我们的项目和数据库都是好了,考虑到可能时数据库连接的问题,所以我打算引入数据池,引入数据池的时候找来找去,比较了当前两个最火的数据池,阿里的druid和HikariCP,比来比去选了阿里的druid,虽然spring boot默认不支持druid,而是支持HikariCP,而且HikariCP的性能更好,但是阿里功能多,就是想支持国产 实际配置: 1.首先现在下载一

【spring boot+mybatis】注解使用方式(无xml配置)设置自动驼峰明明转换(),IDEA中xxDao报错could not autowire的解决方法

最近使用spring boot+mybatis,使用IntelliJ IDEA开发,记录一些问题的解决方法. 1.在使用@Mapper注解方式代替XXmapper.xml配置文件,使用@Select等注解配置sql语句的情况下,如何配置数据库字段名到JavaBean实体类属性命的自动驼峰命名转换? 使用spring boot后,越来越喜欢用注解方式进行配置,代替xml配置文件方式.mybatis中也可以完全使用注解,避免使用xml方式配置mapper.(参考  springboot(六):如何优

LocalStorage 本地存储 做一个简单留言板

二话不说,先上代码: 1 <body> 2 <div><textarea id="trCon" cols="30" rows="10"></textarea></div> 3 <div><input type="button" value="发表" onclick="PostCon()"><inpu

spring boot+mybatis+quartz项目的搭建完整版

1. 利用spring boot提供的工具(http://start.spring.io/)自动生成一个标准的spring boot项目架构 2. 因为这里我们是搭建spring boot+mybatis+quartz架构,故在pom.xml文件中配置相关依赖 <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boo

使用IDEA搭建Spring boot+Mybatis工程

简介:Spring boot只使用一个核心配置文件,取消了一系列xml配置,甚至连web.xml都没有,全部使用注解的方式完成WEB层的功能.框架内置Tomcat服务器,运行启动类中的Main函数即可启动. 下面就来搭建Spring boot+Mybatis工程 新建工程 勾上web,其他的不用 Finish 完善一下目录结构: 在pom.xml配置所有相关的依赖: 1 <?xml version="1.0" encoding="UTF-8"?> 2 &

详解spring boot mybatis全注解化

本文重点介绍spring boot mybatis 注解化的实例代码 1.pom.xml //引入mybatis <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.0</version> </dependency> //

【转】spring boot mybatis 读取配置文件

spring boot mybatis 配置整理 一.加载mybatis的配置 1.手写配置,写死在代码里 import java.io.IOException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ibatis.