亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Java > 正文

【手把手】JavaWeb 入門級項目實戰 -- 文章發布系統 (第九節)

2019-11-06 06:15:10
字體:
來源:轉載
供稿:網友

1. 根據靜態頁面完成javaBean設計

在上一節中,我們完成了文章封面的制作,這些都屬于靜態頁面的部分。

從圖片中可以看到,一篇文章的主要信息有:文章標題,文章名稱,作者,還有摘要描述。

在《用大白話聊聊JavaSE -- 如何理解Java Bean(一)》中,我們已經討論關于JavaBean的一些問題。

一般來說,JavaBean分為必要字段和輔助字段,文章標題,文章名稱,作者,還有摘要描述,還有文章內容這些,應該屬于必要字段的范疇。

至于輔助字段,我就不搞那么復雜了,簡單設置幾個吧,比如發布時間,最后更新時間,是否發布,是否刪除。

當然,我們還需要知道這篇文章是誰寫的,所以還要再加一個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 NULLDEFAULT 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='category'>    <div class='title'>編程代碼類</div>    <ul class='items'>        <li class='item'></li>        <li class='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='category'>    <div class='title'>編程代碼類</div>    <ul class='items'>        <li class='item'></li>        <li class='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='category'>    <div class='title'>編程代碼類</div>    <ul class='items'>        <c:forEach items="${articles2}" var="item">            <li class='item'>                <div class='item-banner'>                    <div class='item-header'>${item.header}</div>                    <div class='item-name'>${item.name}</div>                    <div class='item-author'>@${item.author} 著</div>                </div>                <div class='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='item-name' title = "${item.name}">${item.name}</div>

這樣就OK了。

好的,與前臺對接完畢了。

我又弄了幾條測試數據。

假模假式的,稍微有那么點樣子了。

嗯,今天就到這里了,下一節咱們繼續


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲精品福利资源站| 日韩av片免费在线观看| 亚洲欧美制服中文字幕| 九九九久久国产免费| 亚洲老板91色精品久久| 美女撒尿一区二区三区| 日韩在线观看免费高清完整版| 国产主播欧美精品| 色综合视频网站| 国产一区二区三区视频免费| 日韩性xxxx爱| 欧美国产欧美亚洲国产日韩mv天天看完整| 亚洲一区国产精品| 日韩最新av在线| 欧美大片免费观看在线观看网站推荐| 日韩亚洲成人av在线| 91免费看视频.| 国产精品丝袜久久久久久不卡| 色老头一区二区三区在线观看| 亚洲香蕉成视频在线观看| 国产精品1234| 欧美日韩成人精品| 国产成人欧美在线观看| 国产精品99免视看9| 中文字幕国内精品| 精品久久久久久国产91| 久久精视频免费在线久久完整在线看| 中文字幕av一区中文字幕天堂| 欧美激情视频在线免费观看 欧美视频免费一| 亚洲激情 国产| 午夜精品久久久久久99热软件| 久久久在线观看| 国产精品高清网站| 国产成人一区二区三区| 在线一区二区日韩| 久久精品人人爽| 国产精品久久久久久亚洲调教| 91精品国产91久久久久久最新| 欧美日韩成人网| 欧美综合在线第二页| 国产视频精品一区二区三区| 国产精品va在线| 欧美野外猛男的大粗鳮| 成人自拍性视频| 美日韩精品免费观看视频| 久久亚洲影音av资源网| 日韩精品视频在线| 毛片精品免费在线观看| 亚洲免费视频一区二区| 欧美成人免费va影院高清| 久久视频国产精品免费视频在线| 久久久这里只有精品视频| 色偷偷av一区二区三区乱| 久久久久999| 日韩欧美在线观看视频| 国产精品一区二区久久久| 在线视频免费一区二区| 在线观看国产成人av片| 欧美视频在线观看免费| 亚洲午夜久久久久久久| 亚洲成人网在线观看| 欧美日韩亚洲系列| 国产精品看片资源| 亚洲国产精品久久久久久| 亚洲一区二区三区在线视频| 最近2019免费中文字幕视频三| 日本精品免费一区二区三区| 国产精品福利网| 69久久夜色精品国产69乱青草| 日本一区二区不卡| 欧美日韩福利视频| 亚洲精品91美女久久久久久久| 欧美午夜宅男影院在线观看| 狠狠久久五月精品中文字幕| 97久久精品人搡人人玩| 国产福利成人在线| 久久69精品久久久久久久电影好| 中文字幕少妇一区二区三区| 亚洲欧美日韩一区二区在线| 精品久久久久久亚洲国产300| 久久久久中文字幕2018| 国产99久久精品一区二区永久免费| 亚洲国产精品免费| 色偷偷av亚洲男人的天堂| 国产精品大陆在线观看| 欧美激情精品久久久久久免费印度| 欧美xxxwww| 在线成人中文字幕| 色777狠狠综合秋免鲁丝| 色噜噜久久综合伊人一本| 欧美人交a欧美精品| 亚洲男人天堂网| 亚洲高清福利视频| 日韩亚洲成人av在线| 久久久久久久影院| 成人性生交大片免费看视频直播| 高跟丝袜欧美一区| 亚洲日韩中文字幕在线播放| 91在线高清免费观看| 欧洲成人性视频| 精品福利在线看| 欧美中文字幕在线观看| 98精品国产高清在线xxxx天堂| 日韩在线观看免费全| 国产a∨精品一区二区三区不卡| 最新亚洲国产精品| 91精品美女在线| 欧美日韩国产激情| 欧美理论电影在线观看| 97超级碰碰碰| 中文字幕精品国产| 亚洲男人天堂古典| 国产精品美女久久久久av超清| 欧美巨猛xxxx猛交黑人97人| 久久精品国产精品亚洲| 精品久久久久久久大神国产| 国产精品久久久久久亚洲调教| 亚洲free嫩bbb| 国产日韩精品入口| 国产亚洲欧美日韩美女| 日韩欧美在线视频观看| 国产精品久久久一区| 亚洲xxxx妇黄裸体| 久久久久久久国产| 国产精品久久久久久久久免费看| 国产亚洲一区二区在线| 尤物精品国产第一福利三区| yellow中文字幕久久| 欧美高清自拍一区| 国产一区私人高清影院| 欧美巨猛xxxx猛交黑人97人| 日本一区二区在线免费播放| 91成人免费观看网站| 亚洲图片制服诱惑| 精品久久久国产| 狠狠躁夜夜躁人人爽天天天天97| 一区二区三区视频免费| 亚洲午夜久久久久久久| 欧美性猛交xxxx黑人| 日韩不卡中文字幕| 亚洲精品日韩久久久| 国产精品热视频| 欧美日韩一区二区免费在线观看| 国产精品久久久久免费a∨大胸| 久久久精品久久| 亚洲一区二区三区香蕉| 欧美性猛xxx| 国产乱人伦真实精品视频| 欧美激情一区二区三区高清视频| 亚洲精品99久久久久中文字幕| 成人午夜高潮视频| 亚洲女成人图区| 亚洲毛片在线观看| 亚洲午夜精品久久久久久久久久久久| 国产午夜精品麻豆| 日韩视频一区在线| 国产精品电影网站| 日韩福利伦理影院免费| 亚洲国产精品免费| 18性欧美xxxⅹ性满足| 成人久久一区二区三区| 欧美激情中文字幕乱码免费| 欧美日韩高清在线观看| 日韩精品免费在线播放|