很抱歉,同時(shí)寫幾個(gè)系列并且本人在考試月,真的有點(diǎn)忙不過(guò)來(lái),也要復(fù)習(xí)一些考試知識(shí),所以更新得有點(diǎn)慢,但我會(huì)堅(jiān)持更新這些系列的。請(qǐng)大家放心。今天要更的是Maven+SpringMVC+Hibernate的項(xiàng)目并附帶分頁(yè)功能以及一對(duì)多查詢功能。
文章結(jié)構(gòu):1.項(xiàng)目介紹(功能業(yè)務(wù)邏輯,運(yùn)用的知識(shí),項(xiàng)目數(shù)據(jù)庫(kù)等);2.項(xiàng)目架構(gòu)介紹以及部分關(guān)鍵邏輯代碼說(shuō)明(分頁(yè)以及一對(duì)多查詢功能的實(shí)現(xiàn)(通過(guò)PagingAndSortingRepository實(shí)現(xiàn)))。3.源碼分享。
本系列:J2EE項(xiàng)目系列
一、 J2EE項(xiàng)目系列(一)--學(xué)生管理系統(tǒng)
一、項(xiàng)目介紹(功能業(yè)務(wù)邏輯,運(yùn)用的知識(shí),項(xiàng)目數(shù)據(jù)庫(kù)等)
(1)功能介紹:
1.添加管理賬號(hào),包括賬號(hào)、密碼,你的名字(新舊名字)。還有一系列的增刪改查。
2.添加博客文章,文章的日期、內(nèi)容、標(biāo)題、id。還有一系列的增刪改查。
3.實(shí)現(xiàn)外鍵級(jí)聯(lián)屬性
4.實(shí)現(xiàn)分頁(yè)查詢統(tǒng)計(jì)
5.實(shí)現(xiàn)一對(duì)多查詢
6.部分前端代碼,基于bootstrap的樣式和js.min
(2)運(yùn)用的知識(shí):
使用Intellij進(jìn)行開(kāi)發(fā)的,spring,hibernate,mysql,maven
1.基本數(shù)據(jù)庫(kù)知識(shí)MySQL
2.SpringMVC+hibernate
3.(重點(diǎn))框架的MVC設(shè)計(jì)模式的應(yīng)用
4.(重點(diǎn))分頁(yè)查詢
5.(重點(diǎn))一對(duì)多查詢
6.部分前端代碼,基于bootstrap的樣式和js.min以及一些jstl
7.JpaRepository的使用
(3)項(xiàng)目構(gòu)建:使用Maven快速構(gòu)建項(xiàng)目
給出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.0</modelVersion>
<groupId>com.fuzhu</groupId>
<artifactId>springmvcdemo</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>springmvcdemo Maven Webapp</name>
<url>http://maven.apache.org</url>
<!--springcore的。雖然我們只寫了一個(gè)依賴,但是它導(dǎo)入了兩個(gè)jar包,也就是說(shuō),導(dǎo)入某個(gè)jar包時(shí),與它密切相關(guān)的jar包也會(huì)同時(shí)被導(dǎo)入進(jìn)來(lái)。-->
<properties>
<spring.version>4.2.6.RELEASE</spring.version>
<hibernate.version>5.1.0.Final</hibernate.version>
</properties>
<dependencies>
<!--servlet的-->
<dependency>
<groupId>org.jboss.spec.javax.servlet</groupId>
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
<version>1.0.0.Final</version>
</dependency>
<dependency>
<groupId>org.jboss.resteasy</groupId>
<artifactId>tjws</artifactId>
<version>3.0.10.Final</version>
<scope>test</scope>
</dependency>
<!--junit單元測(cè)試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--SpringMVC-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!--spring基本包-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.1.RELEASE</version>
</dependency>
<!--hibernate基本包-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.8</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.6</version>
</dependency>
</dependencies>
<build>
<finalName>springmvcdemo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
(4)項(xiàng)目分包:MVC架構(gòu)。對(duì)比我的上一篇項(xiàng)目,使用框架的優(yōu)勢(shì)就完美體現(xiàn)出來(lái)了。極度精簡(jiǎn)的代碼,項(xiàng)目代碼設(shè)計(jì)。
這里寫圖片描述
(5)數(shù)據(jù)庫(kù):
//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
測(cè)試數(shù)據(jù):
INSERT INTO `t2`.`blog` (`title`, `content`, `user_id`, `pub_date`) VALUES ('發(fā)發(fā)發(fā)方法付', '發(fā)發(fā)發(fā)方法付付付', '1', '2016-12-29');
INSERT INTO `t2`.`user` (`nickname`, `password`, `first_name`, `last_name`) VALUES ('fuzhu', '75111', 'fuzh', 'fuzhu');
(6)項(xiàng)目功能截圖:
下面是用戶表的增刪改查
這里寫圖片描述
下面是實(shí)現(xiàn)一對(duì)多的查詢
這里寫圖片描述
下面是博客文章的總表,并實(shí)現(xiàn)分頁(yè)查詢
這里寫圖片描述
二、項(xiàng)目架構(gòu)介紹以及部分關(guān)鍵邏輯代碼說(shuō)明
基本的MVC架構(gòu)了,model-view-controller
大家學(xué)習(xí)持久層開(kāi)發(fā)的時(shí)候可以使用JpaRepository。本博客也是使用這個(gè)。這個(gè)是詳細(xì)文檔Spring Data
此分層的結(jié)構(gòu):(注意篇)項(xiàng)目一些坑以及配置過(guò)程(1)user業(yè)務(wù)邏輯的的接口;(2)blog業(yè)務(wù)的邏輯接口;(3)分頁(yè)功能的接口;(4)細(xì)講分頁(yè)功能(含JpaRepository使用);(5)細(xì)講一對(duì)多查詢功能(含JpaRepository使用)
(注意篇)項(xiàng)目一些坑以及配置過(guò)程
(注意篇)1.項(xiàng)目配置系列,大家可根據(jù)這篇去配置我們的項(xiàng)目,暫不吐槽他的命名以及一些做法,但還是很詳細(xì)and很多可取之處的。項(xiàng)目配置。在此感謝那位博主的付出。
(注意篇)2.即使按照他配置,還是有一些坑的。
<%@ page isELIgnored="false" %>
<!--這句代碼非常重要?。?!必須在jsp中添加,至于加在哪里,大家下載我的項(xiàng)目時(shí)候看jsp文件吧-->
<!--JSTL表達(dá)式語(yǔ)言可以使用標(biāo)記格式方便地訪問(wèn)JSP的隱含對(duì)象和JavaBeans組件,JSTL的核心標(biāo)記提供了流程和循環(huán)控制功能。自制標(biāo)記也有自定義函數(shù)的功能-->
(注意篇)3.使用JpaRepository開(kāi)發(fā)是有比較多坑的,大家需要先仔細(xì)閱讀文檔Spring Data。我的分頁(yè)功能和一對(duì)多查詢功能都是在這里學(xué)習(xí)的。不過(guò)我的是整合成項(xiàng)目,文檔的是零散的。
比如jstl的使用,以及注意點(diǎn),他的那個(gè)項(xiàng)目是有些小bug的。
(注意篇)4.注意下面的那個(gè)jsp文件里面,在<c:choose>這個(gè)標(biāo)簽里面是不支持注釋的,用的時(shí)候注意把他們刪了喔?。?/h3>
(注意篇)5.大家可能注意到我用到了bootstrep以及js,也許不是單純后端開(kāi)發(fā)。大家看清楚,這里只是用到他的樣式,我們把他刪了也是可以的,只不過(guò)好看很多而已嘛。
(1)user業(yè)務(wù)邏輯的的接口
//像我給出的文檔中一樣,使用JpaRepository接口進(jìn)行開(kāi)發(fā)持久層
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Integer> {
@Modifying // 說(shuō)明該方法是修改操作
@Transactional // 說(shuō)明該方法是事務(wù)性操作
// 定義查詢
// @Param注解用于提取參數(shù)
@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業(yè)務(wù)的邏輯接口
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);
//一對(duì)多查詢方法
@Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
List<BlogEntity> findByUserByUserId(int userId);
}
(3)分頁(yè)功能的接口
//可直接裝配使用的。
@Repository
public interface BlogPageDao extends PagingAndSortingRepository<BlogEntity, Long> {
}
(4)細(xì)講分頁(yè)功能(含JpaRepository使用)
//需要自動(dòng)裝配那幾個(gè)接口咯
@Autowired
BlogRepository blogRepository;
@Autowired
UserRepository userRepository;
@Autowired
private BlogPageDao districtRepository;
// 查看所有博文,實(shí)現(xiàn)分頁(yè)查詢?。。∽⒁馐且粋€(gè)get請(qǐng)求,并且攜帶參數(shù)。
@RequestMapping(value = "/admin/blogs", method = RequestMethod.GET)
public String showBlogs(ModelMap modelMap,@RequestParam(value = "pageNonumber", required = false, defaultValue = "0") Integer pageNonumber) {
//如果pageNonumber,也就是當(dāng)前頁(yè),要有特殊處理,奇葩的都弄到第一頁(yè)
if (pageNonumber== null || pageNonumber==-1) {
pageNonumber= 0;
}
// pageNonumber是從0開(kāi)始的,所以我們顯示的時(shí)候要有特殊處理,這個(gè)是從數(shù)據(jù)庫(kù)讀取出來(lái),不用特別處理
int pageSize = 5; //頁(yè)面包含條數(shù)的多少
// PageRequest接口通常使用的起PageRequest實(shí)現(xiàn)類,其中封裝了需要分頁(yè)的信息。
PageRequest pageRequest = new PageRequest(pageNonumber, pageSize);
Page<BlogEntity> page = districtRepository.findAll(pageRequest);
System.out.println("總記錄數(shù):" + page.getTotalElements());
System.out.println("當(dāng)前第幾頁(yè):" + page.getNumber());
System.out.println("總頁(yè)數(shù)" + page.getTotalPages());
System.out.println("當(dāng)前頁(yè)面的list:" + page.getContent());
System.out.println("當(dāng)前頁(yè)面記錄數(shù):" + page.getNumberOfElements());
modelMap.addAttribute("sourceCodeList",page.getContent()); //當(dāng)前頁(yè)面的list
modelMap.addAttribute("totalPageNumber",page.getTotalElements());//總記錄數(shù)
modelMap.addAttribute("numberPage",page.getNumber());//當(dāng)前第幾頁(yè)
modelMap.addAttribute("totalPages",page.getTotalPages());//總頁(yè)數(shù)
return "pages/testPage";
}
下面重點(diǎn)關(guān)注分頁(yè)的幾個(gè)點(diǎn):1.傳過(guò)來(lái)要按照map的key對(duì)應(yīng)取值;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>
<!-- 這個(gè)是重點(diǎn)?。?!jstl使用獲取數(shù)據(jù)的前提-->
<%@ 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">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC 博客管理</title>
<title>分頁(yè)page</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://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>ID</th>
<th>標(biāo)題</th>
<th>作者</th>
<th>發(fā)布日期</th>
<th>操作</th>
</tr>
<!--根據(jù)key得到的那個(gè)sourceCodeList就需要遍歷出來(lái),按照他包含的BlogEntitiy去讀出來(lái)-->
<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>
<!--這里就是處理那幾個(gè)傳過(guò)來(lái)的page數(shù)據(jù)的啦,從而實(shí)現(xiàn)分頁(yè)嘛-->
<td colspan="6" align="center" bgcolor="#5BA8DE">共${totalPageNumber}條記錄 共${totalPages}頁(yè)
當(dāng)前第${numberPage+1}頁(yè)<br>
<c:choose>
<!--這里處理是,numberPage 當(dāng)前頁(yè)不等于0的時(shí)候可以點(diǎn)擊,也就是等于就點(diǎn)擊不了咯-->
<c:when test="${numberPage!=0}">
<!--用了鏈接使用get請(qǐng)求,傳想要去的那個(gè)頁(yè)過(guò)去,其實(shí)就是在當(dāng)前頁(yè)上面做文章-->
<a href="${path}/admin/blogs?pageNonumber=${numberPage-1}"><input type="button"
name="previousPage"
value="上一頁(yè)"/></a>
</c:when>
<c:otherwise>
<input type="button" disabled="disabled" name="previousPage" value="上一頁(yè)"/>
</c:otherwise>
</c:choose>
<c:choose>
<!--這里處理是,numberPage 當(dāng)前頁(yè)不等于總頁(yè)數(shù)減一的時(shí)候可以點(diǎn)擊,也就是等于就點(diǎn)擊不了咯-->
<c:when test="${numberPage != totalPages-1}">
<!--用了鏈接使用get請(qǐng)求,傳想要去的那個(gè)頁(yè)過(guò)去,其實(shí)就是在當(dāng)前頁(yè)上面做文章-->
<a href="${path}/admin/blogs?pageNonumber=${numberPage+1}"><input type="button" name="nextPage"
value="下一頁(yè)"/></a>
</c:when>
<c:otherwise>
<input type="button" disabled="disabled" name="nextPage" value="下一頁(yè)"/>
</c:otherwise>
</c:choose>
</td>
</tr>
</table>
</div>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
這樣就實(shí)現(xiàn)一個(gè)分頁(yè)功能啦?。?!
(5)細(xì)講一對(duì)多查詢功能(含JpaRepository使用):
//使用這個(gè)接口實(shí)現(xiàn)分頁(yè)查詢開(kāi)發(fā)
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);
//一對(duì)多查詢方法。我們要注意這個(gè)接口方法語(yǔ)句的拼接,很重要。
//blog.userByUserId.id 特別是這里,指的是user的id不是別的id
@Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
List<BlogEntity> findByUserByUserId(int userId);
}
//功能:一對(duì)多的查詢,查詢自己的博客文章
@RequestMapping(value = "/admin/users/blogsDetails/{id}",method = RequestMethod.GET)
public String lookBlogs(ModelMap modelMap,@PathVariable("id") Integer userId){
//注意那個(gè)傳過(guò)來(lái)的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";
}
下面是顯示查詢到的博客文章嘛,沒(méi)啥特別的
<%--
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" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 這個(gè)是重點(diǎn)!??!jstl使用獲取數(shù)據(jù)的前提-->
<%@ 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">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC 博客管理</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<![endif]-->
</head>
<body>
<div class="container">
<h1>SpringMVC 博客系統(tǒng)-博客管理</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表為空,請(qǐng)<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>ID</th>
<th>標(biāo)題</th>
<th>作者</th>
<th>發(fā)布日期</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>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
三、對(duì)了,我會(huì)給我的源碼給大家,大家想用就用吧。哈哈。喜歡就給個(gè)star咯,謝謝大家。
Github地址--源碼傳送門
好了,J2EE項(xiàng)目系列(二)--博客管理系統(tǒng)(Maven+SpringMVC+Hibernate以及附加分頁(yè)和一對(duì)多查詢功能)講完了,這是J2EE項(xiàng)目系列(二),這個(gè)系列我會(huì)繼續(xù)寫的,分享經(jīng)驗(yàn)給大家。歡迎在下面指出錯(cuò)誤,共同學(xué)習(xí)!!你的star是對(duì)我最好的支持??!
轉(zhuǎn)載請(qǐng)注明:【JackFrost的博客】
更多內(nèi)容,可以訪問(wèn)JackFrost的博客
//像我給出的文檔中一樣,使用JpaRepository接口進(jìn)行開(kāi)發(fā)持久層
@Repository
public interface UserRepository extends JpaRepository<UserEntity, Integer> {
@Modifying // 說(shuō)明該方法是修改操作
@Transactional // 說(shuō)明該方法是事務(wù)性操作
// 定義查詢
// @Param注解用于提取參數(shù)
@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);
}
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);
//一對(duì)多查詢方法
@Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
List<BlogEntity> findByUserByUserId(int userId);
}
//可直接裝配使用的。
@Repository
public interface BlogPageDao extends PagingAndSortingRepository<BlogEntity, Long> {
}
//需要自動(dòng)裝配那幾個(gè)接口咯
@Autowired
BlogRepository blogRepository;
@Autowired
UserRepository userRepository;
@Autowired
private BlogPageDao districtRepository;
// 查看所有博文,實(shí)現(xiàn)分頁(yè)查詢?。。∽⒁馐且粋€(gè)get請(qǐng)求,并且攜帶參數(shù)。
@RequestMapping(value = "/admin/blogs", method = RequestMethod.GET)
public String showBlogs(ModelMap modelMap,@RequestParam(value = "pageNonumber", required = false, defaultValue = "0") Integer pageNonumber) {
//如果pageNonumber,也就是當(dāng)前頁(yè),要有特殊處理,奇葩的都弄到第一頁(yè)
if (pageNonumber== null || pageNonumber==-1) {
pageNonumber= 0;
}
// pageNonumber是從0開(kāi)始的,所以我們顯示的時(shí)候要有特殊處理,這個(gè)是從數(shù)據(jù)庫(kù)讀取出來(lái),不用特別處理
int pageSize = 5; //頁(yè)面包含條數(shù)的多少
// PageRequest接口通常使用的起PageRequest實(shí)現(xiàn)類,其中封裝了需要分頁(yè)的信息。
PageRequest pageRequest = new PageRequest(pageNonumber, pageSize);
Page<BlogEntity> page = districtRepository.findAll(pageRequest);
System.out.println("總記錄數(shù):" + page.getTotalElements());
System.out.println("當(dāng)前第幾頁(yè):" + page.getNumber());
System.out.println("總頁(yè)數(shù)" + page.getTotalPages());
System.out.println("當(dāng)前頁(yè)面的list:" + page.getContent());
System.out.println("當(dāng)前頁(yè)面記錄數(shù):" + page.getNumberOfElements());
modelMap.addAttribute("sourceCodeList",page.getContent()); //當(dāng)前頁(yè)面的list
modelMap.addAttribute("totalPageNumber",page.getTotalElements());//總記錄數(shù)
modelMap.addAttribute("numberPage",page.getNumber());//當(dāng)前第幾頁(yè)
modelMap.addAttribute("totalPages",page.getTotalPages());//總頁(yè)數(shù)
return "pages/testPage";
}
<%@ 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>
<!-- 這個(gè)是重點(diǎn)?。?!jstl使用獲取數(shù)據(jù)的前提-->
<%@ 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">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC 博客管理</title>
<title>分頁(yè)page</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<script src="http://cdn.bootcss.com/html5shiv/3.7.2/html5shiv.min.js"></script>
<script src="http://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>ID</th>
<th>標(biāo)題</th>
<th>作者</th>
<th>發(fā)布日期</th>
<th>操作</th>
</tr>
<!--根據(jù)key得到的那個(gè)sourceCodeList就需要遍歷出來(lái),按照他包含的BlogEntitiy去讀出來(lái)-->
<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>
<!--這里就是處理那幾個(gè)傳過(guò)來(lái)的page數(shù)據(jù)的啦,從而實(shí)現(xiàn)分頁(yè)嘛-->
<td colspan="6" align="center" bgcolor="#5BA8DE">共${totalPageNumber}條記錄 共${totalPages}頁(yè)
當(dāng)前第${numberPage+1}頁(yè)<br>
<c:choose>
<!--這里處理是,numberPage 當(dāng)前頁(yè)不等于0的時(shí)候可以點(diǎn)擊,也就是等于就點(diǎn)擊不了咯-->
<c:when test="${numberPage!=0}">
<!--用了鏈接使用get請(qǐng)求,傳想要去的那個(gè)頁(yè)過(guò)去,其實(shí)就是在當(dāng)前頁(yè)上面做文章-->
<a href="${path}/admin/blogs?pageNonumber=${numberPage-1}"><input type="button"
name="previousPage"
value="上一頁(yè)"/></a>
</c:when>
<c:otherwise>
<input type="button" disabled="disabled" name="previousPage" value="上一頁(yè)"/>
</c:otherwise>
</c:choose>
<c:choose>
<!--這里處理是,numberPage 當(dāng)前頁(yè)不等于總頁(yè)數(shù)減一的時(shí)候可以點(diǎn)擊,也就是等于就點(diǎn)擊不了咯-->
<c:when test="${numberPage != totalPages-1}">
<!--用了鏈接使用get請(qǐng)求,傳想要去的那個(gè)頁(yè)過(guò)去,其實(shí)就是在當(dāng)前頁(yè)上面做文章-->
<a href="${path}/admin/blogs?pageNonumber=${numberPage+1}"><input type="button" name="nextPage"
value="下一頁(yè)"/></a>
</c:when>
<c:otherwise>
<input type="button" disabled="disabled" name="nextPage" value="下一頁(yè)"/>
</c:otherwise>
</c:choose>
</td>
</tr>
</table>
</div>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>
//使用這個(gè)接口實(shí)現(xiàn)分頁(yè)查詢開(kāi)發(fā)
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);
//一對(duì)多查詢方法。我們要注意這個(gè)接口方法語(yǔ)句的拼接,很重要。
//blog.userByUserId.id 特別是這里,指的是user的id不是別的id
@Query("select blog from BlogEntity blog where blog.userByUserId.id = ?1")
List<BlogEntity> findByUserByUserId(int userId);
}
//功能:一對(duì)多的查詢,查詢自己的博客文章
@RequestMapping(value = "/admin/users/blogsDetails/{id}",method = RequestMethod.GET)
public String lookBlogs(ModelMap modelMap,@PathVariable("id") Integer userId){
//注意那個(gè)傳過(guò)來(lái)的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" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<!-- 這個(gè)是重點(diǎn)!??!jstl使用獲取數(shù)據(jù)的前提-->
<%@ 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">
<!-- 上述3個(gè)meta標(biāo)簽*必須*放在最前面,任何其他內(nèi)容都*必須*跟隨其后! -->
<title>SpringMVC 博客管理</title>
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" >
<![endif]-->
</head>
<body>
<div class="container">
<h1>SpringMVC 博客系統(tǒng)-博客管理</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表為空,請(qǐng)<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>ID</th>
<th>標(biāo)題</th>
<th>作者</th>
<th>發(fā)布日期</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>
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="http://cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="http://cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
</body>
</html>