1. 程式人生 > >Spring Boot、MyBatis、Thymeleaf 簡單增刪改查

Spring Boot、MyBatis、Thymeleaf 簡單增刪改查

Spring Boot、MyBatis、Thymeleaf 簡單增刪改查

原始碼地址:https://gitee.com/Azure_Sky/SpringStudy.git

一、建立專案

1。新建專案

二、建立資料庫及資料表

資料庫名為thymeleaf、資料表名稱db_article各欄位如下

三、配置資料庫連線資訊,在application.properties檔案中配置資料庫連線資訊

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/thymeleaf?UseUnicode=true&characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=123456
spring.thymeleaf.cache=false

四、在resources下新建mybatis.cfg.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>
    <!--引入外部配置檔案-->
    <properties resource="application.properties"></properties>
    <!--為Java Bean起類別名-->
    <typeAliases>
        <package name="com.example.demo.beans"></package>
    </typeAliases>

    <!--配置mybatis執行環境-->
    <environments default="mybatis">
        <environment id="mybatis">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${spring.datasource.driver-class-name}"></property>
                <property name="url" value="${spring.datasource.url}"></property>
                <property name="username" value="${spring.datasource.username}"></property>
                <property name="password" value="${spring.datasource.password}"></property>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <package name="com/example/demo/mapper"></package>
    </mappers>
</configuration>

五、在java下的com.example.demo下建立如下包

beans存放實體類,controller存放控制器,mapper存放mybatis對映檔案與介面檔案,service存放事務類,tools存放工具類,DemoApplication為啟動類

1.在beans下新建實體類(Article類),程式碼如下:

package com.example.demo.beans;

import java.util.Date;

public class Article {
    private int id;
    private String title;
    private String author;
    private String content;
    private Date createdate;

    //省略set和get方法
}

2.在mapper下新建ArticleMapper介面,內容如下:

package com.example.demo.mapper;

import com.example.demo.beans.Article;

import java.util.List;

public interface ArticleMapper {
    /**
     * 查詢所有的文章資訊
     * @return 所有的文章資訊
     * @throws Exception
     */
    public List<Article> selectAllArticle() throws Exception;


    /**
     * 新增文章
     * @param article 新增的文章資訊
     * @return 新增成功後的文章資訊
     * @throws Exception
     */
    public int addArticle(Article article) throws Exception;

    /**
     * 編輯文章資訊
     * @param article 編輯後的文章資訊
     * @return 成功返回true、否則返回false
     * @throws Exception
     */
    public int editArticle(Article article) throws Exception;

    /**
     * 根據文章id刪除文章資訊
     * @param id 文章id
     * @return 成功返回true,否則返回false
     * @throws Exception
     */
    public int deleteArticle(int id) throws Exception;

    /**
     * 根據文章id取得文章資訊
     * @param id 文章id
     * @return 返回文章資訊
     * @throws Exception
     */
    public Article getArticleById(int id) throws Exception;
}

在mapper下新建ArticleMapper.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.mapper.ArticleMapper">
    <!--自定義返回結果集-->
    <resultMap id="articleMap" type="Article">
        <id property="id" column="id" javaType="java.lang.Integer"/>
        <result property="title" column="title" javaType="java.lang.String"/>
        <result property="author" column="author" javaType="java.lang.String"/>
        <result property="content" column="content" javaType="java.lang.String"/>
        <result property="createdate" column="createdate" javaType="java.util.Date"/>
    </resultMap>

    <select id="selectAllArticle" resultMap="articleMap">
        select * from tb_article
    </select>

    <insert id="addArticle" parameterType="com.example.demo.beans.Article"
            useGeneratedKeys="true" keyProperty="id">
        insert into tb_article(title,author,content,createdate)
        values(#{title},#{author},#{content},#{createdate})
    </insert>

    <update id="editArticle" parameterType="com.example.demo.beans.Article">
        update tb_article set title=#{title},author=#{author}
        ,content=#{content},createdate=#{createdate} where id=#{id}
    </update>

    <delete id="deleteArticle">
        delete from tb_article where id=#{id}
    </delete>


    <select id="getArticleById" parameterType="int" resultType="com.example.demo.beans.Article">
        select * from tb_article where id=#{id}
    </select>
</mapper>

3.在service下新建ArticleService類,內容如下:

package com.example.demo.service;

import com.example.demo.beans.Article;
import com.example.demo.mapper.ArticleMapper;
import com.example.demo.tools.DBTools;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class ArticleService {
    /**
     * 取得所有文章資訊
     * @return 所有文章資訊集合
     */
    public List<Article> getAllArticles(){
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);
        List<Article> articles=null;
        try {
            articles=mapper.selectAllArticle();
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        }finally{
            session.close();
        }
        return articles;
    }


    /**
     * 發表文章
     * @param article 發表的文章資訊
     * @return 如果發表成功,返回true,否則返回false
     */
    public boolean addArticle(Article article){
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);

        int result=0;
        try {
            result=mapper.addArticle(article);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        }finally{
            session.close();
        }
        if(result>0){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 根據文章ID取得文章內容
     * @param id 文章id
     * @return 文章實體類物件
     */
    public Article getArticleById(int id){
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);

        Article article=null;
        try {
            article=mapper.getArticleById(id);
            session.commit();
        } catch (Exception e) {
            session.rollback();
            e.printStackTrace();
        }finally{
            session.close();
        }
        return article;
    }

    /**
     * 根據Id刪除文章資訊
     * @param id 欲刪除文章的id
     * @return 如果刪除成功,返回true,否則返回false
     */
    public boolean deleteArticleById(int id){
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);

        int result=0;
        try {
            result=mapper.deleteArticle(id);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        }finally{
            session.close();
        }
        return result>0;
    }


    /**
     * 編輯文章資訊
     * @param article 修改後的文章資訊
     * @return 如果編輯成功,返回true,否則返回false
     */
    public boolean editArticle(Article article){
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);

        int result=0;
        try {
            result=mapper.editArticle(article);
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        }finally{
            session.close();
        }

        return result>0;
    }

}

4.在tools下新建DBTools類,用於獲得SqlSession物件,內容如下:

package com.example.demo.tools;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;


import java.io.IOException;
import java.io.Reader;

public class DBTools {
    private static SqlSessionFactory sessionFactory;
    static{
        try {
            Reader reader= Resources.getResourceAsReader("mybatis.cfg.xml");
            sessionFactory=new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSession(){
        return sessionFactory.openSession();
    }
}

5.在controller下新建ArticleController控制器,程式碼如下:

package com.example.demo.controller;

import com.example.demo.beans.Article;
import com.example.demo.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.Date;
import java.util.List;

@Controller
public class ArticleController {
    @Autowired
    private ArticleService articleService;

    /**
     * 顯示所有的文章資訊
     * @param model 傳遞給View的資料
     * @return View檢視
     */
    @RequestMapping("/article")
    public String showArtiles(Model model){
        List<Article> articles=articleService.getAllArticles();
        model.addAttribute("articles",articles);
        return "/article/index";
    }



    /**
     * 呼叫發表文章檢視
     * @return 發表文章檢視頁面
     */
    @RequestMapping(value="/createArticle",method = RequestMethod.GET)
    public String create(){
        return "/article/create";
    }

    /**
     * 發表文章邏輯,將文章資訊儲存到資料庫中
      * @param article 發表文章檢視傳遞過來的文章資訊
     * @return 所有文章列表頁
     */
    @RequestMapping(value = "/saveArticle",method = RequestMethod.POST)
    public String create(Article article){
        article.setCreatedate(new Date());
        if(articleService.addArticle(article)){
            return "redirect:/article";//跳轉到文章列表頁
        }else{
            return "/article/create";
        }
    }


    /**
     * 文章詳細內容頁
     * @param id 文章的ID
     * @return 返回文章的詳細內容
     */
    @RequestMapping(value = "/details/{id}",method = RequestMethod.GET)
    public String details(@PathVariable("id") int id, Model model){
        Article article=articleService.getArticleById(id);
        model.addAttribute("article",article);
        return "/article/details";
    }

    /**
     * 刪除文章
     * @param id 欲刪除文章的id
     * @return 如果刪除成功,返回到文章列表頁,不成功也返回到文章列表頁
     */
    @RequestMapping(value="/delete/{id}",method = RequestMethod.GET)
    public String deleteArticle(@PathVariable("id") int id){
        if(articleService.deleteArticleById(id)){
            return "redirect:/article";//跳轉到文章列表頁
        }
        return "redirect:/article";
    }

    /**
     * 編輯文章資訊
     * @param id 欲編輯文章的id
     * @param model 欲編輯文章的資訊,用於在檢視中進行顯示
     * @return 編輯文章的視圖表單
     */
    @RequestMapping(value="/edit/{id}",method = RequestMethod.GET)
    public String edit(@PathVariable("id") int id,Model model){
        Article article=articleService.getArticleById(id);
        model.addAttribute("article",article);
        return "/article/edit";
    }

    /**
     * 編輯文章邏輯 將修改後的文章資訊更新到資料庫
     * @param article
     * @return
     */
    @RequestMapping(value = "/updateArticle",method = RequestMethod.POST)
    public String edit(Article article,Model model){
        if(articleService.editArticle(article)){
            return "redirect:/article";//跳轉到文章列表頁
        }
        model.addAttribute("article",article);
        return "/article/edit";
    }

    @RequestMapping("/")
    @ResponseBody
    public String hello(){
        return "Hello thymeleaf";
    }

    @RequestMapping("/test")
    public String testLayout(){
        return "/test";
    }
}

六、建立檢視層`

resources下下目錄結構如下:

1.引入BootStrap、jQuery

在static下新建bootstrap,將下載到的bootstrap檔案下的css、fonts、js目錄複製到bootstrap目錄下,將jQuery檔案複製到js目錄下,

2.在templates下建立article和common兩個目錄

article目錄用於存放article的所有檢視    

common用於存放佈局頁面

3.在common下建立佈局頁,內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${title}">Title</title>

    <!--引入BootsStrap樣式-->
    <link rel="stylesheet" type="text/css"
          th:href="@{/bootstrap/css/bootstrap.css}">

    <!--引入自定義樣式-->
    <link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/main.css}">

    <!--引入js檔案-->
    <script th:src="@{/bootstrap/js/jquery.min.js}"></script>
    <script th:src="@{/bootstrap/js/bootstrap.js}"></script>

</head>
<body>
<!--最外層容器-->
<div id="wrap" class="container">
    <!--頁面頭部-->
    <header>
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <!-- Brand and toggle get grouped for better mobile display -->
                <div class="navbar-header">
                    <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                        <span class="sr-only">Toggle navigation</span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                        <span class="icon-bar"></span>
                    </button>
                    <a class="navbar-brand" href="#">Brand</a>
                </div>

                <!-- Collect the nav links, forms, and other content for toggling -->
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class="nav navbar-nav">
                        <li class="active">
                            <a href="#" th:href="@{/}">首頁</a>
                        </li>
                        <li><a href="#" th:href="@{/test}">測試</a></li>
                        <li><a href="#" th:href="@{/article}">技術文章</a></li>
                    </ul>
                    <form class="navbar-form navbar-right">
                        <div class="form-group">
                            <input type="text" class="form-control" placeholder="請輸入文章名">
                        </div>
                        <button type="submit" class="btn btn-default">Search</button>
                    </form>
                </div><!-- /.navbar-collapse -->
            </div><!-- /.container-fluid -->
        </nav>
    </header>
    <!-- 頁面主體部分-->
    <div id="main_content" th:include="::main_content">

    </div>
    <!--頁面底部-->
    <footer class="row">
        <div class="col-md-12">
            <ul>
                <li><a href="#">GitHub倉庫地址</a></li>
                <li><a th:href="@{http://www.my.oschina.net/u/3537796/blog}">部落格</a></li>
                <li><a th:href="@{http://www.bootcss.com}">BootStrap</a></li>
                <li><a th:href="@{http://www.w3school.com.cn/jquery}">jQueryfttk</a></li>
            </ul>
        </div>
        <div class="col-md-12">
            <p>
                CopyRight:BlueMonkey 地址:中國河南
            </p>
        </div>
    </footer>
</div>
</body>
</html>

4.在article目錄下,新建index.html檔案,內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      th:replace="common/layout(title='測試佈局')">

<div th:fragment="main_content">
    <table class="table table-hover">
        <tr>
            <td>編號</td>
            <td>標題</td>
            <td>發表日期</td>
            <td></td>
        </tr>
        <tr th:each="article:${articles}">
            <td th:text="${article.getId()}"></td>
            <td th:text="${article.getTitle()}"></td>
            <td th:text="${article.getCreatedate()}"></td>
            <td>
                <a th:href="@{'/edit/'+${article.getId()}}">編輯文章</a>
                <a th:href="@{'/details/'+${article.getId()}}">文章內容</a>
                <a th:href="@{'/delete/'+${article.getId()}}" onclick="alert('確定要刪除文章嗎?')">刪除文章</a>
            </td>
        </tr>
    </table>
</div>
</html>

5.在article下新建details.html檔案,內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      th:replace="common/layout(title='測試佈局')">

<div th:fragment="main_content">
    <article class="text-center">
        <h3 th:text="${article.getTitle()}"></h3>
        <h4 th:text="${article.getAuthor()}"></h4>
        <p th:text="${article.getContent()}" class="text-left"></p>
        <h4 th:text="${article.getCreatedate()}" class="text-right"></h4>
    </article>
</div>
</html>

6.在article下新建create.html檔案,內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
    th:replace="common/layout(title='發表文章')">
    <!--發表文章資訊表單-->
    <div th:fragment="main_content">
        <form action="/saveArticle" method="post">
            文章標題:<input type="text" name="title"><br/><br/>
            作者名稱:<input type="text" name="author"><br/><br/>
            文章內容:<input type="text" name="content"><br/><br/>
            <input type="submit" value="確定">
        </form>

    </div>
</html>

7.在article目錄下,新建edit.html檔案,內容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      th:replace="common/layout(title='編輯文章')">
<!--發表文章資訊表單-->
<div th:fragment="main_content">
    <form action="/updateArticle" method="post">
        <input type="hidden" name="id" th:value="${article.getId()}">
        <input type="hidden" name="createdate" th:value="${article.getCreatedate()}">
        文章標題:<input type="text" name="title" th:value="${article.getTitle()}"><br/><br/>
        作者名稱:<input type="text" name="author" th:value="${article.getAuthor()}"><br/><br/>
        文章內容:<input type="text" name="content" th:value="${article.getContent()}"><br/><br/>
        <input type="submit" value="確定">
    </form>
</div>
</html>

七、執行結果

八、補充搜尋文章

1.修改mapper下的ArticleMapper介面,新增如下程式碼

/**
     * 根據文章標題查詢文章資訊
     * @param title
     * @return 查詢到的文章資訊
     * @throws Exception
     */
    public List<Article> getArticleByTitle(String title) throws Exception;

2.修改ArticleMapper.xml檔案,新增如下配置

<select id="getArticleByTitle" parameterType="String" resultMap="articleMap">
        select * from tb_article where title like "%"#{title}"%"
    </select>

3.修改service下的ArticleService

/**
     * 查詢文章,根據標題模糊查詢
     * @param title 文章標題
     * @return 如果有返回相應的文章資訊,無則返回null
     */
    public List<Article> searchArticleByTitle(String title){
        List<Article> articles=null;
        SqlSession session=DBTools.getSession();
        ArticleMapper mapper=session.getMapper(ArticleMapper.class);

        try {
            articles=mapper.getArticleByTitle(title);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            session.close();
        }
        return articles;
    }

4.修改controller下的ArticleController類,

/**
     * 查詢文章,根據標題模糊
     * @param title 標題
     * @param model 返回資料
     * @return 如果不為空返回資料,為空返回錯誤頁
     */
    @RequestMapping(value = "/searchArticle",method = RequestMethod.POST)
    public String searchArticle(String title,Model model){
        List<Article> articles=articleService.searchArticleByTitle(title);
        if(!articles.isEmpty()){
            model.addAttribute("articles",articles);
            return "/article/searchResult";
        }else{
            model.addAttribute("info","沒有你要查詢的結果");
            return "/common/error";
        }
    }

5.在resources下templates下的article下,新建searchResult.html檔案,

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      th:replace="common/layout(title='測試佈局')">

<div th:fragment="main_content">
    <table class="table table-hover">
        <tr>
            <td>編號</td>
            <td>標題</td>
            <td>發表日期</td>
            <td></td>
        </tr>
        <tr th:each="article:${articles}">
            <td th:text="${article.getId()}"></td>
            <td th:text="${article.getTitle()}"></td>
            <td th:text="${article.getCreatedate()}"></td>
        </tr>
    </table>
</div>
</html>

6.在common下新建error.html

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org"
      th:replace="common/layout(title='測試佈局')">

<div th:fragment="main_content">
    <h3 th:text="${info}">錯誤訊息</h3>
</div>
</html>