从图片中可以看到,一篇文章的紧张信息有:文章标题,文章名称,作者,还有择要描述。

在《用大口语聊聊JavaSE -- 如何理解Java Bean(一)》中,我们已经谈论关于JavaBean的一些问题。

一样平常来说,JavaBean分为必要字段和赞助字段,文章标题,文章名称,作者,还有择要描述,还有文章内容这些,该当属于必要字段的范畴。

indexjspline手把手JavaWeb 入门级项目实战  文章宣布体系 第九节 SQL

至于赞助字段,我就不搞那么繁芜了,大略设置几个吧,比如发布韶光,末了更新韶光,是否发布,是否删除。

当然,我们还须要知道这篇文章是谁写的,以是还要再加一个userid字段,这样的话才能和user表关联起来。

末了,还须要有一个分类字段,一篇文章,肯定是属于某一个类别的,以是这个也须要加上。

嗯,就添加这几个赞助字段吧,我们弄大略一点。

我们在bean包里面新建一个Article类。

设置属性如下:

package bean;import java.util.Date;import annotation.Column;import annotation.Table;@Table(tableName = \"大众t_article\公众)public class Article { @Column(field = \"大众id\"大众 , type = \"大众varchar(100)\"大众 , primaryKey = true) private String id; //主键 @Column(field = \"大众header\"大众 , type = \公众varchar(100)\公众) private String header; //标题 @Column(field = \"大众name\"大众 , type = \"大众varchar(60)\"大众) private String name; //文章名称 @Column(field = \"大众content\公众 , type = \"大众text\"大众) private String content; //文章内容 @Column(field = \公众author\公众 , type = \公众varchar(30)\"大众) private String author; //作者 @Column(field = \"大众description\"大众 , type = \"大众varchar(100)\"大众) private String description; //概要 @Column(field = \"大众is_published\公众 , type = \"大众int(1)\"大众) private Integer isPublished; //是否发布 0 未发布 1 发布 @Column(field = \"大众is_delete\公众 , type = \"大众int(1)\公众) private Integer isDelete; //是否删除 0 未删除 1 已删除 @Column(field = \"大众create_time\公众 , type = \"大众datetime\"大众) private Date createTime;//创建韶光 @Column(field = \公众update_time\"大众 , type = \"大众timestamp\公众 , defaultNull = false) private Date updateTime;//末了更新韶光 @Column(field = \公众user_id\"大众 , type = \公众varchar(100)\"大众 , defaultNull = false) private String userId;//作者id @Column(field = \"大众category_id\"大众 , type = \"大众int(2)\"大众 , defaultNull = false) private Integer categoryId;//分类ID }

然后,别忘了天生get,set以及toString方法。

2. Mysql建表

2.1 文章表

在TestMain方法中再天生一下sql语句。

package test;import bean.Article;import util.TableUtils;public class TestMain { public static void main(String[] args) { String sql = TableUtils.getCreateTableSQl(Article.class); System.out.println(sql); }}

运行

这是天生出来的sql语句

DROP TABLE IF EXISTS t_article;DROP TABLE IF EXISTS t_article;create table t_article( id varchar(100) DEFAULT NULL, header varchar(100) DEFAULT NULL, name varchar(60) DEFAULT NULL, content text DEFAULT NULL, author varchar(30) DEFAULT NULL, description varchar(100) DEFAULT NULL, is_published int(1) DEFAULT NULL, is_delete int(1) DEFAULT NULL, create_time datetime DEFAULT NULL, update_time timestamp NOT NULL, user_id varchar(100) NOT NULL, category_id int(2) NOT NULL,) DEFAULT CHARSET=utf8

由于 update_time 是timestamp类型,也便是韶光戳,那么我们给他一个默认值,默认便是当前韶光。

改成:

update_time timestamp NOT NULL

DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,

在mysql数据库里面运行一下,创造报错了

[Err] 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') DEFAULT CHARSET=utf8' at line 13

哦,原来在属性的末了一行不能有逗号。

看来之前写的方法还有点问题,这边我们先把逗号去掉吧。

再次运行sql语句,OK,成功建表了。

3. 制造测试数据,JUint初探

接下来,我们来虚拟一些数据。

我们在test包下新建一个类,叫做TestInsertOperation,便是测试INSERT操作的意思。

我们用JUint来测试。

JUnit是一个基于Java措辞的单元测试框架,用起来比较方便。
它的源代码很轻巧,而且优雅地利用了多种设计模式,该当来说,这是一个非常精良的框架。

首先在这个TestInsertOperation类中添加一个方法

/ 测试:给文章插入数据 /@Testpublic void insertArticle(){ }

@Test是一个表明,加上它往后,才会被JUint测试框架识别。

把光标放在@Test上面,ctrl + 1

这个东西就跳出来了,点击第一项,JUint的依赖包就被加载进来了。

接下来,在测试方法 insertArticle 中写上测试代码:

String sql = \"大众INSERT INTO t_article(id,header,name,content,author,\公众 + \"大众description,is_published,is_delete,create_time,update_time\公众 + \"大众,user_id,category_id) VALUES (?,?,?,?,?,?,?,?,?,?,?,?) \"大众;String id = UUID.randomUUID().toString(); //主键String header = \公众Java Web实用技能\公众;String name = \"大众如何将MyEclipse项目导入eclipse\"大众;String content = \"大众我们常常会在网高下载一些开源项目,或者从别的地方迁移一些项目进来,但常常会创造导入后各种报错。
这是初学java肯定会碰着的问题,本文对一些常见的处理方案做一个总结。
(本文将MyEclipse项目导入eclipse的过程为例,其他情形也可参考这个流程)\"大众;String author = \"大众Jack\"大众;String description = \"大众办理项目导入的冲突问题...\"大众;int isPublished = 1 ;int isDelete = 0;String create_time = \"大众2016-10-19 10:43:10\"大众;String update_time = \公众2016-10-19 10:43:10\公众;String userId = \"大众319600c3-550a-4f9f-80cf-deebe2376528\"大众;int categoryId = 2;DataBaseUtils.update(sql, id,header,name,content,author,description,isPublished,isDelete,create_time,update_time,userId,categoryId);System.out.println(\公众新增成功!
\公众);

鼠标双击方法名

按一下F11,开始测试(如果F11不起浸染,那么就右键,Run As, JUnit Test)

测试结果:

OK,没有缺点。

掌握台也没有报错,而且成功打印了 \"大众新增成功!
\"大众 这几个字。

我已经在库里查到这条数据了,现在,用jdbc的办法将刚刚插入的数据查询出来。

在库里看到它的 ID 为 2145ed72-164a-401c-af29-248625a775b8。

好的,现在新写一个方法来获取这条数据:

public void getArticle(){ String sql = \公众select from t_article where id = ?\"大众; Article article = DataBaseUtils.queryForBean(sql, Article.class, \公众2145ed72-164a-401c-af29-248625a775b8\"大众); System.out.println(article);}

测试结果:

Article [ id = 2145ed72-164a-401c-af29-248625a775b8,

header = Java Web实用技能,

name = 如何将MyEclipse项目导入eclipse,

content = 我们常常会在网高下载一些开源项目,或者从别的地方迁移一些项目进来,但常常会创造导入后各种报错。
这是初学java肯定会碰着的问题,本文对一些常见的处理方案做一个总结。
(本文将MyEclipse项目导入eclipse的过程为例,其他情形也可参考这个流程),

author = Jack,

description = 办理项目导入的冲突问题...,

isPublished = 1,

isDelete = 0,

createTime = Wed Oct 19 10:43:10 CST 2016,

updateTime = Wed Oct 19 10:43:10 CST 2016,

userId = 319600c3-550a-4f9f-80cf-deebe2376528,

categoryId = 2 ]

这样就成功了。

2.2 分类表

分类表的话比较大略,为了大略起见,我们就不写JavaBean了,直接在mysql中建表吧。

建表语句:

DROP TABLE IF EXISTS `t_category`;CREATE TABLE `t_category` ( `category_id` int(11) NOT NULL AUTO_INCREMENT, `category_name` varchar(20) CHARACTER SET utf8 DEFAULT NULL, PRIMARY KEY (`category_id`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

ID是自增长的。

制造数据:

INSERT INTO `t_category` VALUES ('1', '连载小说');INSERT INTO `t_category` VALUES ('2', '编程代码类');INSERT INTO `t_category` VALUES ('3', '生活感悟');

insert 操作可以直接在mysql中进行操作,也可以用jdbc来操作。

jdbc操作的代码如下

/ 插入分类数据 /@Testpublic void insertCategory(){ DataBaseUtils.update(\公众insert into t_category set category_name = ?\"大众, \公众连载小说\公众); DataBaseUtils.update(\公众insert into t_category set category_name = ?\"大众, \"大众编程代码类\"大众); DataBaseUtils.update(\公众insert into t_category set category_name = ?\公众, \"大众生活感悟\公众);}

测试一下就行了。

好的,插入完毕后,我们新建一个测试方法来查询一下。

/ 获取分类列表 /@Testpublic void getCategoryList(){ String sql = \"大众select from t_category where 1 = 1\"大众; List list = DataBaseUtils.queryForList(sql); System.out.println(list);}

结果:

[ {category_name=连载小说, category_id=1},

{category_name=编程代码类, category_id=2},

{category_name=生活感悟, category_id=3} ]

嗯,OK了。

4. service层开拓

上面的测试代码紧张是dao部分的,但由于本项目省去了dao层,以是,有什么操作的话,我们直接在service层办理掉算了。

新建一个 ArticleService 类

首页的文章列表:

从静态页面中,我们可以看到,文章被分为几个不同的种别,比如连载小说,便是一个单一的种别,我们该当是通过种别去加载相应的文章。

在数据库表中,连载小说的分类ID为1,那么我们如果想要查询出该分类下的文章,就会写出这样的sql语句:

select from t_article where category_id = 1;

我们先不管到底怎么和首页对接的,先把后台逻辑写好再说。

在 ArticleService 类中定义一个查询方法

/ 通过种别获取文章列表 @param categoryId @param start @param end /public List<Map<String,Object>> getArticlesByCategoryId(Integer categoryId,Integer start,Integer end){ String sql = \"大众select id,header,name,author,\公众 + \"大众description from t_article where 1 = 1 \"大众 + \公众 and is_delete = 0\公众 + \"大众 and is_published = 1\"大众 + \"大众 and category_id = ?\公众 + \公众 order by update_time desc limit ?,?\"大众; return DataBaseUtils.queryForList(sql, categoryId,start,end);}

测试代码:

ArticleService ArticleService = new ArticleService();List list = ArticleService.getArticlesByCategoryId(2,0,10);System.out.println(list);

我测试了一下,该当没问题。
sql查询的话,我做了一个大略的排序,便是根据末了更新韶光倒序排序。

相信你也已经看出来了,由于我们已经有了 DataBaseUtils 这个工具类,以是大大减少了我们的java代码。

不然的话,我们还须要手动去获取连接,然后天生 PreparedStatement 的实例,一大堆 try catch ,末了还要关闭连接。

有了 DataBaseUtils ,这些重复的代码就可以省略了。

在这个 getArticlesByCategoryId 方法中,我故意没有把文章内容查询出来。

缘故原由很大略,由于文章内容不须要展示在首页,我便是查询出来也没用。

我把id查出来了,这样的话,当用户通过点击文章封面,进入详情页的时候,就可以获取文章id,有了这个id,我们是不是就可以去数据库把文章内容给查出来了呢?

以是,我们肯定还须要一个方法,便是通过文章id查询出文章内容的方法。

代码:

/ 通过文章id获取文章内容 @param id @return /public List<Map<String,Object>> getContentByArticleId(String id){ String sql = \公众select content from t_article where id = ?\公众; return DataBaseUtils.queryForList(sql,id);}

测试了一下,也是没问题的哈。

5. 与前台页面对接

好的,后台已经写好了,我们现在和前台对接一下。

打开index.jsp

找到编程代码类:

<div class='a8f44e5a64bb9589 category'> <div class='4e5a64bb9589829f title'>编程代码类</div> <ul class='64bb9589829f3938 items'> <li class='9589829f3938e80a item'></li> <li class='829f3938e80ae435 item'></li> <div style='clear:both'></div> </ul></div>

现在,我们要把它变成动态的。

首先,在index.jsp页面顶部的地方,导入必要的包。

<%@ page language=\"大众java\"大众 import=\"大众java.util.\公众 pageEncoding=\"大众UTF-8\"大众%><%@ page language=\公众java\"大众 import=\"大众service.ArticleService\"大众 pageEncoding=\"大众UTF-8\"大众%>

然后,新建一个 ArticleService 的实例。

<% ArticleService articleService = new ArticleService(); %>

接下来,在 编程代码类 的div上方获取 list 数据。

<% //查询出编程代码类的干系文章 List<Map<String,Object>> articles2 = articleService.getArticlesByCategoryId(2, 0, 6); pageContext.setAttribute(\"大众articles2\公众, articles2);%>${articles2}<div class='3938e80ae435e885 category'> <div class='e80ae435e88500b8 title'>编程代码类</div> <ul class='e435e88500b8ac1b items'> <li class='e88500b8ac1b651e item'></li> <li class='00b8ac1b651e003f item'></li> <div style='clear:both'></div> </ul></div>

pageContext是JSP九大隐式工具的一员,顾名思义,它的浸染域便是当前页面。

${articles2}表示在html代码中显示articles2的详细信息,把稳,这个信息是Java代码获取的。

我们只要刷新一下页面,这些代码逻辑就会被实行。

好的,我们刷新一下。

报错了。

没紧要,看看它说什么。

缺点信息:

message /index.jsp (line: 2, column: 1) Page directive must not have multiple occurrences of pageencoding

哦,它说我们must not have,一定不能有。

一定不能有什么呢?连续往下看。

multiple occurrences of pageencoding(多个pageencoding涌现)

哦,一定不能涌现多个 pageencoding 。

我们来看看页面。

<%@ page language=\公众java\"大众 contentType=\"大众text/html; charset=UTF-8\"大众 pageEncoding=\公众UTF-8\"大众%><%@ page language=\公众java\"大众 import=\"大众java.util.\"大众 pageEncoding=\"大众UTF-8\公众%><%@ page language=\"大众java\"大众 import=\"大众service.ArticleService\"大众 pageEncoding=\"大众UTF-8\"大众%>

嗯,我们真的定义了多个pageEncoding。

好的,我们删掉多余的pageEncoding。

<%@ page language=\公众java\"大众 contentType=\公众text/html; charset=UTF-8\公众 pageEncoding=\"大众UTF-8\公众%><%@ page language=\公众java\"大众 import=\"大众java.util.\公众%><%@ page language=\"大众java\公众 import=\"大众service.ArticleService\公众%>

再来一次,刷新页面。

效果出来了。

${articles2}变成了:

[{id=2145ed72-164a-401c-af29-248625a775b8, author=Jack, description=办理项目导入的冲突问题..., name=如何将MyEclipse项目导入eclipse, header=Java Web实用技能}]

然后,我们须要用JSTL标签库中的一个叫做 c:forEach 标签。

它的浸染是循环遍历,我们直接上代码吧。

<% //查询出编程代码类的干系文章 List<Map<String,Object>> articles2 = articleService.getArticlesByCategoryId(2, 0, 6); pageContext.setAttribute(\"大众articles2\"大众, articles2);%><div class='ac1b651e003f6f0a category'> <div class='651e003f6f0adc4e title'>编程代码类</div> <ul class='003f6f0adc4eab03 items'> <c:forEach items=\公众${articles2}\公众 var=\"大众item\"大众> <li class='6f0adc4eab0380cd item'> <div class='394ca8f44e5a64bb item-banner'> <div class='a8f44e5a64bb9589 item-header'>${item.header}</div> <div class='4e5a64bb9589829f item-name'>${item.name}</div> <div class='64bb9589829f3938 item-author'>@${item.author} 著</div> </div> <div class='9589829f3938e80a item-description'>${item.description}</div> </li> </c:forEach> <div style='clear:both'></div> </ul></div>

我们用了一个forEach标签,将${articles2}进行了遍历。
由于${articles2}是一个list,所以是可以遍历的。

var=\"大众item\"大众 是遍历出来的每一个工具。

效果:

由于字数太多,加上行高的关系,全体封面被挤下来了。

嗯,我手动来调一下css样式吧。

让文章名称逼迫不换行,溢出部分用 ... 显示

.item-name { font-size: 22px; line-height: 74px; white-space:nowrap; overflow:hidden; text-overflow: ellipsis; }

鼠标划上去的时候,显示一个 tip 提示

<div class='829f3938e80ae435 item-name' title = \"大众${item.name}\"大众>${item.name}</div>

这样就OK了。

好的,与前台对接完毕了。

我又弄了几条测试数据。

假模假式的,轻微有那么点样子了。

嗯,本日就到这里了,下一节咱们连续。