Blog address: ONESTAR Inn

Source code access method 1:

  • Scan the qr code at the end of the article, pay attention to the public number [programming Daily], background reply [blog], you can get the source code

Source code access method two:

  • Front-end page source address: github.com/oneStarLR/m…

  • Jpa as a persistent layer source address: github.com/oneStarLR/m…

  • Mybatis as a persistent layer source address: github.com/oneStarLR/m…

Welcome to give encouragement to star

This article will be described from the functions, respectively, there are new blog, query, delete, edit modify, search blog function, there will be more multi-table query, SQL will be a little more complex.

First, build the MVC structure

First, build the MVC architecture model, then write the code of each module directly according to the function, and create the following packages, classes and interfaces:

  • BlogDao:
package com.star.dao;

import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;

/ * * *@Description: Blog management persistence layer interface *@Date: Created in 23:45 2020/6/2
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
@Mapper
@Repository
public interface BlogDao {}Copy the code
  • Mapper folder: blogdao.xml:
<?xml version="1.0" encoding="utf-8" ? >

      
<mapper namespace="com.star.dao.BlogDao">

</mapper>
Copy the code
  • BlogService interface under service package:
package com.star.service;

/ * * *@Description: Blog list business layer interface *@Date: Created in 23:46 2020/6/2
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
public interface BlogService {}Copy the code
  • BlogServiceImpl interface implementation class:
package com.star.service.Impl;

import com.star.service.BlogService;
import org.springframework.stereotype.Service;

/ * * *@Description: Blog list business layer interface implementation class *@Date: Created in 23:47 2020/6/2
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
@Service
public class BlogServiceImpl implements BlogService {}Copy the code
  • BlogController:
package com.star.controller.admin;


import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

/ * * *@Description: Blog management controller *@Date: Created in 23:45 2020/6/2
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
@Controller
@RequestMapping("/admin")
public class BlogController {}Copy the code

Now fill in the module code directly according to the function. So far, the directory structure is as follows:

Second, new blog, list query

New blogs, including title, contents, classification, the address of the first figure, blog description, recommend, reprint, admiration, reviews, original Settings, such as after a new release, in the background can show blog list, start off with the blog list query here, and before a repeat of knowledge will no longer mention, new knowledge will be explained, and the main here is multi-table query.

Analysis:

Q: When querying the list of articles, the front page needs to display the category name, but the blog table does not have the category field. How to handle this?

A: Mybatis multi-table query is used here. You can define a special resultMap in Mapper to map many-to-one relationships by establishing entity classes

1. Create a query entity class

Create queryvo package under com.star package, create BlogQuery query list entity class, define variables according to the content to be queried, there are: Primary key (id), title (title), updateTime (updateTime), recommend (published), type (typeId), type (toString) :

package com.star.queryvo;

import com.star.entity.Type;

import java.util.Date;

/ * * *@DescriptionQuery the list of blogs *@Date: Created in 9:31 2020/6/3
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
public class BlogQuery {

    private Long id;
    private String title;
    private Date updateTime;
    private Boolean recommend;
    private Boolean published;
    private Long typeId;
    private Type type;
    
}
Copy the code

2. Add and query the interface of the list persistence layer

Add an interface under BlogDao:

// Save the new blog
int saveBlog(Blog blog);

// Query the article management list
List<BlogQuery> getAllBlogQuery(a);
Copy the code

3. Add and query list mapper:

Add SQL at blogdao.xml

<! -- Add save article -->
<insert id="saveBlog" parameterType="com.star.entity.Blog">
    insert into myblog.t_blog (id,title, content, first_picture, flag,
    views, comment_count, appreciation, share_statement, commentabled, published,
    recommend, create_time, update_time, type_id, user_id, description)
    values (#{id},#{title},#{content},#{firstPicture},#{flag},#{views},#{commentCount},#{appreciation},
    #{shareStatement},#{commentabled},#{published},#{recommend},#{createTime},
    #{updateTime},#{typeId},#{userId},#{description});
</insert>

<! -- Query article management list many-to-one configuration -->
<resultMap id="blog" type="com.star.queryvo.BlogQuery">
    <id property="id" column="id"/>
    <result property="title" column="title"/>
    <result property="updateTime" column="update_time"/>
    <result property="recommend" column="recommend"/>
    <result property="published" column="published"/>
    <result property="typeId" column="type_id"/>
    <association property="type" javaType="com.star.entity.Type">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
    </association>
</resultMap>
<! Select * from 'admin';
<select id="getAllBlogQuery" resultMap="blog">
    select b.id,b.title,b.update_time,b.recommend,b.published,b.type_id,t.id,t.name
    from myblog.t_blog b left outer join
    myblog.t_type t on b.type_id = t.id order by b.update_time desc
</select>
Copy the code

Multi-table query explanation:

  • ResultMap property: Used to map query results, a resultMap is defined that encapsulates BlogQuery
  • Association attribute: For one-to-one and many-to-one relationships, extract the Type entity map from the Association element and represent it with a resultMap element
  • Property property: On which property of the BlogQuery object the result set of the associated query is stored
  • JavaType property: Used to specify the Java data type to which the object belongs

4. Add and query service layer interfaces for lists

Under the BlogService interface add:

// Save the new blog
int saveBlog(Blog blog);

// Query the article management list
List<BlogQuery> getAllBlog(a);
Copy the code

5. Added and queried list service layer interface implementation classes

Add under the BlogServiceImpl interface implementation class:

@Autowired
private BlogDao blogDao;

// Save the new blog
@Override
public int saveBlog(Blog blog) {
    blog.setCreateTime(new Date());
    blog.setUpdateTime(new Date());
    blog.setViews(0);
    blog.setCommentCount(0);
    return blogDao.saveBlog(blog);
}

// Query the article management list
@Override
public List<BlogQuery> getAllBlog(a) {
    return blogDao.getAllBlogQuery();
}
Copy the code

Explanation:

  • You need to initialize the creation time, update time, browse quantity and visit quantity in the new blog
  • Invoke the persistence layer interface to implement related functions

6. Add and query list controllers

Analysis:

Q: how to write the controller, do the page jump directly?

Answer: when doing page jump, we should first think about what data (model) needs to be transferred to the front end, and the light is definitely not good for page jump

Q: Which models need to be passed to a new blog

A: When a blog is added, it will jump to the list of blogs and need to pass the information of the blog object and classification. Therefore, in addition to the blog model, we also need the type-related model

Add controller code to the BlogController class under the admin package:

@Autowired
private BlogService blogService;
@Autowired
private TypeService typeService;

// Jump to new page of blog
@GetMapping("/blogs/input")
public String input(Model model) {
    model.addAttribute("types",typeService.getAllType());
    model.addAttribute("blog".new Blog());
    return "admin/blogs-input";
}

// Add blogs
@PostMapping("/blogs")
public String post(Blog blog, RedirectAttributes attributes, HttpSession session){
    // The blog object needs to be passed when it is added, and the blog object needs to have user
    blog.setUser((User) session.getAttribute("user"));
    // Set the type of the blog
    blog.setType(typeService.getType(blog.getType().getId()));
    // Set the typeId property in blog
    blog.setTypeId(blog.getType().getId());
    // Set the user ID
    blog.setUserId(blog.getUser().getId());

    int b = blogService.saveBlog(blog);
    if(b == 0){
        attributes.addFlashAttribute("message"."New failure");
    }else {
        attributes.addFlashAttribute("message"."New success");
    }
    return "redirect:/admin/blogs";
}

// List of blogs
@RequestMapping("/blogs")
public String blogs(Model model, @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum){

    // Sort by field in reverse order
    String orderBy = "update_time desc";
    PageHelper.startPage(pageNum,10,orderBy);
    List<BlogQuery> list = blogService.getAllBlog();
    PageInfo<BlogQuery> pageInfo = new PageInfo<BlogQuery>(list);
    model.addAttribute("types",typeService.getAllType());
    model.addAttribute("pageInfo",pageInfo);
    return "admin/blogs";

}
Copy the code

7. Front – end interaction

Front-end does not explain, only paste part of the code, only for reference, there is a need to download the source view: github.com/oneStarLR/m…

  • New blog:
<a href="#" th:href="@{/admin/blogs/input}">
  <button type="button" class="ui teal button m-mobile-wide m-margin-top"><i class="pencil icon"></i>new</button>
</a>
Copy the code
  • The new content
<! -- Mark original, reprint, translation -->
<input type="hidden" value="Original" name="flag" th:value="*{flag}" >

<! -- Blog title -->
<input type="text" name="title" placeholder="Title" th:value="*{title}">

<! -- Blog text -->
<div class="" id="md-content" style="z-index: 1 ! important;">
    <textarea placeholder="Blog content" name="content" style="display: none" th:text="*{content}"></textarea>
</div>

<! -- Category Settings -->
<div th:each="type : ${types}" class="item" data-value="1" th:data-value="${type.id}" th:text="${type.name}">My story</div>

<! -- First image Settings -->
<input type="text" name="firstPicture" th:value="*{firstPicture}" placeholder="Header reference address">

<! -- Blog Description -->
<textarea name="description" placeholder="Blog description..." maxlength="200" th:text="*{description}"></textarea>

<! -- Recommended Settings -->
<input type="checkbox" id="recommend" name="recommend" checked th:checked="*{recommend}" class="hidden">

<! -- Reprint statement -->
<input type="checkbox" id="shareStatement" name="shareStatement" th:checked="*{shareStatement}" class="hidden">

<! -- Appreciation Settings -->
<input type="checkbox" id="appreciation" name="appreciation" th:checked="*{appreciation}" class="hidden">

<! -- Comment Settings -->
<input type="checkbox" id="commentabled" name="commentabled" th:checked="*{commentabled}" class="hidden">
Copy the code
  • Save publication:
<button type="button" id="save-btn" class="ui secondary button">save</button>
<button type="button" id="publish-btn" class="ui teal button">release</button>
Copy the code
$('#save-btn').click(function () {$('[name="published"]').val(false);
  $('#blog-form').submit();
});
  
$('#publish-btn').click(function () {$('[name="published"]').val(true);
  $('#blog-form').submit();
});
Copy the code
  • Submit the form
<form id="blog-form" action="#" th:object="${blog}" th:action="*{id}==null ? @{/admin/blogs} : @{/admin/blogs/{id}(id=*{id})}" method="post" class="ui form">
    <input type="hidden" name="published" th:value="*{published}">
    <input type="hidden" name="id" th:value="*{id}">... </form>Copy the code
  • Paging query
<div class="ui inverted divided stackable grid">
    <div class="three wide column" align="center">
      <a class="item" th:href="@{/admin/blogs(pageNum=${pageInfo.hasPreviousPage}? ${pageInfo.prePage}:1)}" th:unless="${pageInfo.isFirstPage}">The previous page</a>
    </div>
    
    <div class="ten wide column" align="center">
      <p>The first<span th:text="${pageInfo.pageNum}"></span>Page,<span th:text="${pageInfo.pages}"></span>Page,<span th:text="${pageInfo.total}"></span>article</p>
    </div>
    
    <div class="three wide column" align="center">
      <a class="item" th:href="@{/admin/blogs(pageNum=${pageInfo.hasNextPage}? ${pageInfo.nextPage}:${pageInfo.pages})}" th:unless="${pageInfo.isLastPage}">The next page</a>
    </div>
</div>
Copy the code

8. Run access

Run the project, visit http://localhost:8080/admin, login and then click the article management, click the new button, new page jump, can the new post, after the release of jump list of blogs, and query the article information.

Third, blog deletion

Analysis:

Q: Blog delete delete, a SQL statement is ok?

A: Delete is relatively simple, to implement the function of direct delete can be done, but take into account that after deleting to jump to the blog list, so also need to redirect to the blog list query

1. Delete the persistence layer interface

In the BlogDao interface add:

// Delete the blog
void deleteBlog(Long id);
Copy the code

2. Delete the mapper

In blogdao.xml add:

<! -- Delete article -->
<delete id="deleteBlog">
    delete from myblog.t_blog where id = #{id}
</delete>
Copy the code

3. Delete the service layer

  • Example Delete a service layer interface

Add to the BlogService interface:

// Delete the blog
void deleteBlog(Long id);
Copy the code
  • Delete the business layer interface implementation

In the BlogServiceImpl class add:

// Delete the blog
@Override
public void deleteBlog(Long id) {
    blogDao.deleteBlog(id);
}
Copy the code

4. Delete the controller

Add to the BlogController class:

// Delete the blog
@GetMapping("/blogs/{id}/delete")
public String delete(@PathVariable Long id, RedirectAttributes attributes) {
    blogService.deleteBlog(id);
    attributes.addFlashAttribute("message"."Deleted successfully");
    return "redirect:/admin/blogs";
}
Copy the code

Explanation:

  • @getMapping (“/blogs/{id}/delete”): Transfer path parameters. {id} is the ID value to be transferred
  • Return “redirect:/admin/blogs” : used to jump between controllers, redirecting to the query blog list

5. Front – end interaction

<a href="#" th:href="@{/admin/blogs/{id}/delete(id=${blog.id})}" onclick="Return Confirm (' Are you sure you want to delete this article? Think again! If you delete it, it's gone! ')" class="ui mini red basic button">delete</a>
Copy the code

6. Run the access

Run the project, visit http://localhost:8080/admin, login and then click the article management, click the delete button, you can delete articles, and have deleted successful tips

4. Blog editing

Analysis:

Q: What do blog editors need to consider?

A: When jumping to the edit page, you need to know which article to edit, pass the id of the blog to the back end, and for the user experience, the data that needs to be modified is passed to the front end and displayed

Q: How do you write it?

A: First, to simplify the query, you can create a separate blog display class: BlogShow class, which queries the information of the blogs to be edited, and use getBlogById(ID) to query the blogs to be edited and modified

1. Create edit and modify article entity classes

Create ShowBlog entity class in Queryvo package (omit get, set, toString methods) :

package com.star.queryvo;

import java.util.Date;

/ * * *@Description: Edit and modify the article entity class *@Date: Created in 15:55 2020/6/6
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
public class ShowBlog {

    private Long id;
    private String flag;
    private String title;
    private String content;
    private Long typeId;
    private String firstPicture;
    private String description;
    private boolean recommend;
    private boolean published;
    private boolean shareStatement;
    private boolean appreciation;
    private boolean commentabled;
    private Date updateTime;
    
}
Copy the code

2. Blog editing persistence layer

In the BlogDao interface add:

// Edit the blog
int updateBlog(ShowBlog showBlog);

// Query the edited article
ShowBlog getBlogById(Long id);
Copy the code

3. The Jungle Book

Add under BlogDao:

<! Select * from 'edit';
<select id="getBlogById" resultType="com.star.queryvo.ShowBlog">
    select b.id,b.flag,b.title,b.content,b.type_id,
    b.first_picture,b.description,b.recommend,b.published,b.share_statement,
    b.appreciation,b.commentabled from myblog.t_blog b  where  b.id = #{id};
</select>

<! -- Edit and modify articles -->
<update id="updateBlog" parameterType="com.star.queryvo.ShowBlog">
    update myblog.t_blog set published = #{published},flag = #{flag} ,
    title = #{title}, content = #{content}, type_id = #{typeId},
    first_picture = #{firstPicture} , description = #{description} , recommend = #{recommend} ,
    share_statement = #{shareStatement}, appreciation = #{appreciation},
    commentabled = #{commentabled} ,update_time = #{updateTime} where id = #{id};
</update>
Copy the code

4. Blogs modify the business layer

  • Business layer interface

Add under BlogService:

// Query the edited article
ShowBlog getBlogById(Long id);

// Edit the article
int updateBlog(ShowBlog showBlog);
Copy the code
  • Interface implementation class:
// Query the edited article
@Override
public ShowBlog getBlogById(Long id) {
    return blogDao.getBlogById(id);
}

// Edit the article
@Override
public int updateBlog(ShowBlog showBlog) {
    showBlog.setUpdateTime(new Date());
    return blogDao.updateBlog(showBlog);
}
Copy the code

5. Blog modify controller

Add to BlogController:

// Jump to edit the article
@GetMapping("/blogs/{id}/input")
public String editInput(@PathVariable Long id, Model model) {
    ShowBlog blogById = blogService.getBlogById(id);
    List<Type> allType = typeService.getAllType();
    model.addAttribute("blog", blogById);
    model.addAttribute("types", allType);
    return "admin/blogs-input";
}

// Edit the article
@PostMapping("/blogs/{id}")
public String editPost(@Valid ShowBlog showBlog, RedirectAttributes attributes) {
    int b = blogService.updateBlog(showBlog);
    if(b == 0){
        attributes.addFlashAttribute("message"."Modification failed");
    }else {
        attributes.addFlashAttribute("message"."Modified successfully");
    }
    return "redirect:/admin/blogs";
}
Copy the code

6. Front – end interaction

<a href="#" th:href="@{/admin/blogs/{id}/input(id=${blog.id})}" class="ui mini teal basic button">The editor</a>
Copy the code

7. Run access

Run the project, visit http://localhost:8080/admin, login and then click the article management, click the edit button, jump to edit blog page, can edit the article

Search the blog management list

Analysis:

Q: What are the considerations when searching the blog management list?

A: The search here is using MySQL fuzzy query, according to the blog title and blog classification query want to search the article, need to create a title and classification attributes of the entity class vo query

Q: How does fuzzy query work

A: You can use the bind tag, which creates a variable using an OGNL expression and binds it to the context

1. Create the search blog Management list entity class

Create SearchBlog entity class in Queryvo package (omit get, set, toString methods) :

package com.star.queryvo;

/ * * *@Description: Search the blog management list *@Date: Created in 14:16 2020/6/8
 * @Author: ONESTAR
 * @QQGroup: 530311074 *@URL: https://onestar.newstar.net.cn/
 */
public class SearchBlog {

    private String title;
    private Long typeId;
    
}
Copy the code

2. Search the blog Management list persistence layer interface

In the BlogDao interface add:

// Search the blog management list
List<BlogQuery> searchByTitleAndType(SearchBlog searchBlog);
Copy the code

3. Search mapper, the blog management list

In the blogdao.xml file add:

<! -- Search blog Management list -->
<select id="searchByTitleAndType" parameterType="com.star.queryvo.SearchBlog" resultMap="blog">
    <bind name="pattern" value="'%' + title + '%'" />
    select b.id,b.title,b.type_id,t.id,t.name from myblog.t_blog b ,myblog.t_type t
    <where>
        <if test="1 = = 1">
            b.type_id = t.id
        </if>
        <if test="typeId ! = null">
            and b.type_id = #{typeId}
        </if>
        <if test="title ! = null">
            and b.title like #{pattern}
        </if>
    </where>
</select>
Copy the code

Explanation:

  • Bind: The bind tag can create a variable using an OGNL expression and bind it to the context
  • Name attribute: is the name of the variable bound to the context
  • Value attribute: OGNL expression

4. Search the blog Management list business layer

  • Business layer interface added under BlogService:
// Search the blog management list
List<BlogQuery> getBlogBySearch(SearchBlog searchBlog);
Copy the code
  • Interface implementation: In the BlogServiceImpl class add:
// Search the blog management list
@Override
public List<BlogQuery> getBlogBySearch(SearchBlog searchBlog) {
    return blogDao.searchByTitleAndType(searchBlog);
}
Copy the code

5. Search the Blog Management List Controller

Add to the BlogController class:

// Search the blog management list
@PostMapping("/blogs/search")
public String search(SearchBlog searchBlog, Model model,
                     @RequestParam(defaultValue = "1",value = "pageNum") Integer pageNum) {
    List<BlogQuery> blogBySearch = blogService.getBlogBySearch(searchBlog);
    PageHelper.startPage(pageNum, 10);
    PageInfo<BlogQuery> pageInfo = new PageInfo<>(blogBySearch);
    model.addAttribute("pageInfo", pageInfo);
    return "admin/blogs :: blogList";
}
Copy the code

6. Front – end interaction

<! -- Search button -->
<button  type="button" id="search-btn" class="ui mini teal basic button"><i class="search icon"></i>search</button>
Copy the code
<! --JS--> $("#search-btn").click(function () {$("[name='page']").val(0);
      loaddata();
    });
Copy the code

7. Run access

Run the project, visit http://localhost:8080/admin, login and then click the article management, classification box in the title box and input to query, click search, and can query the paper want to query

SQL Reference: github.com/gaohan666/b…

At this point, blog management development is complete, the next article will be about friend chain management

Point attention, don’t get lost, welcome to continue to pay attention to this site!