J2EE项目系列(二)--博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)

很抱歉,同时写几个系列并且本人在考试月,真的有点忙不过来,也要复习一些考试知识,所以更新得有点慢,但我会坚持更新这些系列的。请大家放心。今天要更的是Maven+SpringMVC+Hibernate的项目并附带分页功能以及一对多查询功能。


文章结构:
1.项目介绍(功能业务逻辑,运用的知识,项目数据库等);
2.项目架构介绍以及部分关键逻辑代码说明(分页以及一对多查询功能的实现(通过PagingAndSortingRepository实现))。
3.源码分享。


本系列:J2EE项目系列

一、 J2EE项目系列(一)–学生管理系统


一、项目介绍(功能业务逻辑,运用的知识,项目数据库等)

(1)功能介绍

1.添加管理账号,包括账号、密码,你的名字(新旧名字)。还有一系列的增删改查。

2.添加博客文章,文章的日期、内容、标题、id。还有一系列的增删改查。

3.实现外键级联属性

4.实现分页查询统计

5.实现一对多查询

6.部分前端代码,基于bootstrap的样式和js.min

(2)运用的知识

使用Intellij进行开发的,spring,hibernate,mysql,maven

1.基本数据库知识MySQL

2.SpringMVC+hibernate

3.(重点)框架的MVC设计模式的应用

4.(重点)分页查询

5.(重点)一对多查询

6.部分前端代码,基于bootstrap的样式和js.min以及一些jstl

7.JpaRepository的使用

(3)项目构建:使用Maven快速构建项目

给出maven代码并讲解
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:mvc="http://www.springframework.org/schema/mvc"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0modelVersion>
    <groupId>com.fuzhugroupId>
    <artifactId>springmvcdemoartifactId>
    <packaging>warpackaging>
    <version>1.0-SNAPSHOTversion>
    <name>springmvcdemo Maven Webappname>
    <url>http://maven.apache.orgurl>
	
	
    <properties>
        <spring.version>4.2.6.RELEASEspring.version>
        <hibernate.version>5.1.0.Finalhibernate.version>
    properties>

    <dependencies>
		
        <dependency>
            <groupId>org.jboss.spec.javax.servletgroupId>
            <artifactId>jboss-servlet-api_3.1_specartifactId>
            <version>1.0.0.Finalversion>
        dependency>
        <dependency>
            <groupId>org.jboss.resteasygroupId>
            <artifactId>tjwsartifactId>
            <version>3.0.10.Finalversion>
            <scope>testscope>
        dependency>
		
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.12version>
            <scope>testscope>
        dependency>
		
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-webmvcartifactId>
            <version>${spring.version}version>
        dependency>
		
        <dependency>
            <groupId>org.springframework.datagroupId>
            <artifactId>spring-data-jpaartifactId>
            <version>1.10.1.RELEASEversion>
        dependency>
	
        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-entitymanagerartifactId>
            <version>${hibernate.version}version>
        dependency>

        <dependency>
            <groupId>org.hibernategroupId>
            <artifactId>hibernate-c3p0artifactId>
            <version>${hibernate.version}version>
        dependency>

        <dependency>
            <groupId>com.mchangegroupId>
            <artifactId>c3p0artifactId>
            <version>0.9.5.2version>
        dependency>

        <dependency>
            <groupId>javax.servletgroupId>
            <artifactId>jstlartifactId>
            <version>1.2version>
        dependency>

        <dependency>
            <groupId>javax.servlet.jspgroupId>
            <artifactId>jsp-apiartifactId>
            <version>2.1version>
            <scope>providedscope>
        dependency>

        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.0.8version>
        dependency>
        <dependency>
            <groupId>junitgroupId>
            <artifactId>junitartifactId>
            <version>4.11version>
        dependency>
        <dependency>
            <groupId>org.mockitogroupId>
            <artifactId>mockito-coreartifactId>
            <version>RELEASEversion>
        dependency>

        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
            <version>1.16.6version>
        dependency>

    dependencies>
    <build>
        <finalName>springmvcdemofinalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.pluginsgroupId>
                <artifactId>maven-compiler-pluginartifactId>
                <configuration>
                    <source>1.8source>
                    <target>1.8target>
                configuration>
            plugin>
        plugins>
    build>
project>

(4)项目分包:MVC架构。对比我的上一篇项目,使用框架的优势就完美体现出来了。极度精简的代码,项目代码设计。

J2EE项目系列(二)--博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)_第1张图片

(5)数据库:

//user表
CREATE TABLE user(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
nickname VARCHAR(45) NOT NULL,
password VARCHAR(45) NOT NULL,
first_name VARCHAR(45),
last_name VARCHAR(45)
);
//blog表
CREATE TABLE blog(
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(100),
content VARCHAR(100),
user_id INT(11) UNSIGNED,
pub_date DATE
);
大家需要使用工具去添加外键,我就这样偷懒了。哈哈
添加外键 user_id--id


测试数据:
INSERT INTO `t2`.`blog` (`title`, `content`, `user_id`, `pub_date`) VALUES ('发发发方法付', '发发发方法付付付', '1', '2016-12-29');
INSERT INTO `t2`.`user` (`nickname`, `password`, `first_name`, `last_name`) VALUES ('fuzhu', '75111', 'fuzh', 'fuzhu');

(6)项目功能截图:

下面是用户表的增删改查

J2EE项目系列(二)--博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)_第2张图片

下面是实现一对多的查询

J2EE项目系列(二)--博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)_第3张图片

下面是博客文章的总表,并实现分页查询

J2EE项目系列(二)--博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)_第4张图片


二、项目架构介绍以及部分关键逻辑代码说明

基本的MVC架构了,model-view-controller

大家学习持久层开发的时候可以使用JpaRepository。本博客也是使用这个。这个是详细文档Spring Data

此分层的结构:(注意篇)项目一些坑以及配置过程(1)user业务逻辑的的接口;(2)blog业务的逻辑接口;(3)分页功能的接口;(4)细讲分页功能(含JpaRepository使用);(5)细讲一对多查询功能(含JpaRepository使用)

(注意篇)项目一些坑以及配置过程

(注意篇)1.项目配置系列,大家可根据这篇去配置我们的项目,暂不吐槽他的命名以及一些做法,但还是很详细and很多可取之处的。项目配置。在此感谢那位博主的付出。

(注意篇)2.即使按照他配置,还是有一些坑的。

<%@ page isELIgnored="false" %>


(注意篇)3.使用JpaRepository开发是有比较多坑的,大家需要先仔细阅读文档Spring Data。我的分页功能和一对多查询功能都是在这里学习的。不过我的是整合成项目,文档的是零散的。

比如jstl的使用,以及注意点,他的那个项目是有些小bug的。

(注意篇)4.注意下面的那个jsp文件里面,在这个标签里面是不支持注释的,用的时候注意把他们删了喔!!

(注意篇)5.大家可能注意到我用到了bootstrep以及js,也许不是单纯后端开发。大家看清楚,这里只是用到他的样式,我们把他删了也是可以的,只不过好看很多而已嘛。

(1)user业务逻辑的的接口

//像我给出的文档中一样,使用JpaRepository接口进行开发持久层
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Integer> {
    @Modifying      // 说明该方法是修改操作
    @Transactional  // 说明该方法是事务性操作
    // 定义查询
    // @Param注解用于提取参数
    @Query("update UserEntity us set us.nickname=:qNickname, us.firstName=:qFirstName, us.lastName=:qLastName, us.password=:qPassword where us.id=:qId")
    public void updateUser(@Param("qNickname") String nickname, @Param("qFirstName") String firstName,
                           @Param("qLastName") String qLastName, @Param("qPassword") String password, @Param("qId") Integer id);
}

(2)blog业务的逻辑接口

public interface BlogRepository extends JpaRepository<BlogEntity,Integer> {
    // 修改博文操作
    @Modifying
    @Transactional
    @Query("update BlogEntity blog set blog.title=:qTitle, blog.userByUserId.id=:qUserId," +
            " blog.content=:qContent, blog.pubDate=:qPubDate where blog.id=:qId")
    void updateBlog(@Param("qTitle") String title, @Param("qUserId") int userId, @Param("qContent") String content,
                    @Param("qPubDate") Date pubDate, @Param("qId") int id);
    //一对多查询方法
    @Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
    List<BlogEntity> findByUserByUserId(int userId);
}

(3)分页功能的接口

//可直接装配使用的。
@Repository
public interface BlogPageDao extends PagingAndSortingRepository {
}

(4)细讲分页功能(含JpaRepository使用)

	//需要自动装配那几个接口咯
	@Autowired
    BlogRepository blogRepository;
    @Autowired
    UserRepository userRepository;
    @Autowired
    private BlogPageDao districtRepository;
    // 查看所有博文,实现分页查询!!!注意是一个get请求,并且携带参数。
    @RequestMapping(value = "/admin/blogs", method = RequestMethod.GET)
    public String showBlogs(ModelMap modelMap,@RequestParam(value = "pageNonumber", required = false, defaultValue = "0") Integer pageNonumber) {
		 //如果pageNonumber,也就是当前页,要有特殊处理,奇葩的都弄到第一页
        if (pageNonumber== null ||  pageNonumber==-1) {
            pageNonumber= 0;
        }
// pageNonumber是从0开始的,所以我们显示的时候要有特殊处理,这个是从数据库读取出来,不用特别处理
        int pageSize = 5;       //页面包含条数的多少
        // PageRequest接口通常使用的起PageRequest实现类,其中封装了需要分页的信息。
        PageRequest pageRequest = new PageRequest(pageNonumber, pageSize);
        Page<BlogEntity> page = districtRepository.findAll(pageRequest);
        System.out.println("总记录数:" + page.getTotalElements());
        System.out.println("当前第几页:" + page.getNumber());
        System.out.println("总页数" + page.getTotalPages());
        System.out.println("当前页面的list:" + page.getContent());
        System.out.println("当前页面记录数:" + page.getNumberOfElements());

        modelMap.addAttribute("sourceCodeList",page.getContent());  //当前页面的list
        modelMap.addAttribute("totalPageNumber",page.getTotalElements());//总记录数
        modelMap.addAttribute("numberPage",page.getNumber());//当前第几页
        modelMap.addAttribute("totalPages",page.getTotalPages());//总页数

        return "pages/testPage";
    }

下面重点关注分页的几个点:1.传过来要按照map的key对应取值;2.注意sourceCodeList,totalPageNumber,numberPage,totalPages的处理。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html>
<head>
    
    <%@ page isELIgnored="false" %>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>SpringMVC 博客管理title>

    <title>分页pagetitle>
    
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <script src="//cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js">script>
    <script src="//cdn.bootcss.com/respond.js/1.4.2/respond.min.js">script>


    <![endif]-->

head>
<body>
<div layout:fragment="content">
    <a href="/admin/blogs" class="list-group-item active">
        你的博客文章
    a>
    <table class="table table-bordered table-striped">
        <tr>
            <th>IDth>
            <th>标题th>
            <th>作者th>
            <th>发布日期th>
            <th>操作th>
        tr>
        
        <c:forEach items="${sourceCodeList}" var="blog">
            <tr>
                <td>${blog.id}td>
                <td>${blog.title}td>
                <td>${blog.userByUserId.nickname}, ${blog.userByUserId.firstName} ${blog.userByUserId.lastName}td>
                <td><fmt:formatDate value="${blog.pubDate }" pattern="yyyy-MM-dd"/>td>
                <td>
                    <a href="/admin/blogs/show/${blog.id}" type="button" class="btn btn-sm btn-success">详情a>
                    <a href="/admin/blogs/update/${blog.id}" type="button" class="btn btn-sm btn-warning">修改a>
                    <a href="/admin/blogs/delete/${blog.id}" type="button" class="btn btn-sm btn-danger">删除a>
                td>
            tr>
        c:forEach>
        <tr>
        
            <td colspan="6" align="center" bgcolor="#5BA8DE">共${totalPageNumber}条记录 共${totalPages}页
                当前第${numberPage+1}页<br>

                <c:choose>
                 
                    <c:when test="${numberPage!=0}">

                        <a href="${path}/admin/blogs?pageNonumber=${numberPage-1}"><input type="button"
                                                                                          name="previousPage"
                                                                                          value="上一页"/>a>

                    c:when>
                    <c:otherwise>

                        <input type="button" disabled="disabled" name="previousPage" value="上一页"/>

                    c:otherwise>
                c:choose>
                <c:choose>
                
                    <c:when test="${numberPage != totalPages-1}">
                    
                        <a href="${path}/admin/blogs?pageNonumber=${numberPage+1}"><input type="button" name="nextPage"
                                                                                          value="下一页"/>a>
                    c:when>
                    <c:otherwise>

                        <input type="button" disabled="disabled" name="nextPage" value="下一页"/>

                    c:otherwise>
                c:choose>
            td>
        tr>
    table>

div>


<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js">script>


<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js">script>
body>
html>

这样就实现一个分页功能啦!!!

(5)细讲一对多查询功能(含JpaRepository使用):

//使用这个接口实现分页查询开发
public interface BlogRepository extends JpaRepository<BlogEntity,Integer> {
    // 修改博文操作
    @Modifying
    @Transactional
    @Query("update BlogEntity blog set blog.title=:qTitle, blog.userByUserId.id=:qUserId," +
            " blog.content=:qContent, blog.pubDate=:qPubDate where blog.id=:qId")
    void updateBlog(@Param("qTitle") String title, @Param("qUserId") int userId, @Param("qContent") String content,
                    @Param("qPubDate") Date pubDate, @Param("qId") int id);
    //一对多查询方法。我们要注意这个接口方法语句的拼接,很重要。
    //blog.userByUserId.id 特别是这里,指的是user的id不是别的id
    @Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
    List<BlogEntity> findByUserByUserId(int userId);
}

//功能:一对多的查询,查询自己的博客文章
    @RequestMapping(value = "/admin/users/blogsDetails/{id}",method = RequestMethod.GET)
    public String lookBlogs(ModelMap modelMap,@PathVariable("id") Integer userId){
    //注意那个传过来的id
        List<BlogEntity>blogEntityList = blogRepository.findByUserByUserId(userId);
        for (BlogEntity blog :blogEntityList){
            System.out.println("博客的啊啊啊啊啊啊"+blog.getId());
            System.out.println(blog.getContent());
            System.out.println(blog.getPubDate());
        }
        modelMap.addAttribute("blogList", blogEntityList);
        return "admin/blogs";
    }

下面是显示查询到的博客文章嘛,没啥特别的

<%--
  Created by IntelliJ IDEA.
  User: 符柱成
  Date: 2016/12/29
  Time: 21:26
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>

<html lang="zh-CN">
<head>
    
    <%@ page isELIgnored="false" %>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <title>SpringMVC 博客管理title>

    
    <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <![endif]-->
head>
<body>
<div class="container">
    <h1>SpringMVC 博客系统-博客管理h1>
    <hr/>

    <h3>所有博客 <a href="/admin/blogs/add" type="button" class="btn btn-primary btn-sm">添加a>h3>

    
    <c:if test="${empty blogList}">
        <div class="alert alert-warning" role="alert">
            <span class="glyphicon glyphicon-info-sign" aria-hidden="true">span>Blog表为空,请<a href="/admin/blogs/add"
                                                                                              type="button"
                                                                                              class="btn btn-primary btn-sm">添加a>
        div>
    c:if>

    
    <c:if test="${!empty blogList}">
        <table class="table table-bordered table-striped">
            <tr>
                <th>IDth>
                <th>标题th>
                <th>作者th>
                <th>发布日期th>
                <th>操作th>
            tr>

            <c:forEach items="${blogList}" var="blog">
                <tr>
                    <td>${blog.id}td>
                    <td>${blog.title}td>
                    <td>${blog.userByUserId.nickname}, ${blog.userByUserId.firstName} ${blog.userByUserId.lastName}td>
                    <td><fmt:formatDate value="${blog.pubDate }" pattern="yyyy-MM-dd"/>td>
                    <td>
                        <a href="/admin/blogs/show/${blog.id}" type="button" class="btn btn-sm btn-success">详情a>
                        <a href="/admin/blogs/update/${blog.id}" type="button" class="btn btn-sm btn-warning">修改a>
                        <a href="/admin/blogs/delete/${blog.id}" type="button" class="btn btn-sm btn-danger">删除a>
                    td>
                tr>
            c:forEach>
        table>
    c:if>
div>



<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js">script>


<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js">script>
body>
html>

三、源码分享

我会给我的源码给大家,大家想用就用吧。哈哈。喜欢就给个star咯,谢谢大家。

Github地址–源码传送门

结语

J2EE项目系列(二)–博客管理系统(Maven+SpringMVC+Hibernate以及附加分页和一对多查询功能)讲完了,这是J2EE项目系列(二),这个系列我会继续写的,分享经验给大家。欢迎在下面指出错误,共同学习!!你的star是对我最好的支持!!

转载请注明:【JackFrost的博客】

更多内容,可以访问JackFrost的博客

你可能感兴趣的:(JavaWeb工程项目系列)