Dao类的设计。
在前面的介绍中,我们在各种action中,好几次提到各种dao类,我们的dao类主要负责数据库的增删查改,我们看看这些dao类是怎么实现的把。
我们先看ArticleDao。
package com.MyBlog.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import com.MyBlog.common.DB;
import com.MyBlog.entity.ArticleBean;
public class ArticleDao {
DB connection =new DB();
ArticleBean articleBean;
/*
* @功能 查询指定类别的文章
* @参数 typeID表示文章类别ID值,type为all时显示所有的记录,为sub时只显示前面的5条记录
* @返回值 List集合
*/
public List queryArticle(int typeID, String type) {
System.out.println("typeID:"+typeID);
System.out.println("type:"+type);
List articleList = new ArrayList();
String sql = "";
// 如果typeID <= 0,不按照类别查询
if(typeID <= 0 ){
if (type == null || type.equals("") || !type.equals("all")) {
// 不按照类别查询,根据发表时间,查询出前面的3条记录
sql = "select * from tb_article order by article_sdTime DESC limit 3";
}
else{
// 不按照类别查询,查询出所有记录
sql = "select * from tb_article order by article_sdTime DESC";
}
}else{
//typeID >0,按照类别进行查询
if (!type.equals("all")) {
// System.out.println("显示该类的前面3条记录");
// 按照类别查询,显示该类的前面3条记录
sql = "select * from tb_article where article_typeID=" + typeID
+ " order by article_sdTime DESC limit 3";
} else {
// 显示该类别所对应的ID 下的所有记录
sql = "select * from tb_article where article_typeID=" + typeID
+ " order by article_sdTime DESC";
}
}
System.out.println(sql);
ResultSet rs = connection.executeQuery(sql);
if (rs != null) {
try {
while (rs.next()) {
// 获取文章信息
articleBean = new ArticleBean();
articleBean.setId(rs.getInt(1));
articleBean.setArticleTypeID(rs.getInt(2));
articleBean.setArticleTitle(rs.getString(3));
articleBean.setArticleContent(rs.getString(4));
articleBean.setArticleSdTime(rs.getString(5));
articleBean.setArticleFrom(rs.getInt(6));
articleBean.setArticleInfo(rs.getString(7));
articleBean.setArticleCount(rs.getInt(8));
articleBean.setMasterID(rs.getInt(9));
// // 查询tb_review数据表统计当前文章的评论数
// sql = "select count(id) from tb_review where review_articleID=" + articleBean.getId();
// ResultSet rsr = connection.executeQuery(sql);
// if (rsr != null) {
// rsr.next();
// articleBean.setReview(rsr.getInt(1));
// rsr.close();
// }
articleList.add(articleBean);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
connection.closed();
}
}
return articleList;
}
/*
* @功能 实现对文章进行增删改的操作
* @参数 oper为一个String类型变量,用来表示要进行的操作,articleBean为ArticleBean类对象
* 用来存储某个文章信息
* @返回值 Boolean值
*/
public boolean operationArticle(String oper, ArticleBean articleBean) {
//生成sql语句
String sql=null;
//发表文章
if(oper.equals("add")){
sql="insert into tb_article(article_typeID,article_title,article_content,"
+"article_sdTime,article_from,article_info,article_count,article_masterID) values("
+ articleBean.getArticleTypeID()+",'"+articleBean.getArticleTitle()+"','"
+ articleBean.getArticleContent()+"','"+articleBean.getArticleSdTime()+"',"
+ articleBean.getArticleFrom()+",'"+articleBean.getArticleInfo()+"',"
+ articleBean.getArticleCount()+","+articleBean.getMasterID()+")";
System.out.println("add article:"+sql);
}
//修改文章
if(oper.equals("modify")){
sql="update tb_article set article_typeID="+articleBean.getArticleTypeID()
+",article_title='"+articleBean.getArticleTitle()
+"',article_content='"+articleBean.getArticleContent()
+"',article_from='"+articleBean.getArticleFrom()
+"',article_info='"+articleBean.getArticleInfo()
+"' where id="+articleBean.getId();
}
//删除文章
if(oper.equals("delete")){
sql="delete from tb_article where id="+articleBean.getId();
}
//累加阅读次数
if(oper.equals("readTimes")){
int article_count=articleBean.getArticleCount()+1;
sql="update tb_article set article_count="+article_count+" where id="+articleBean.getId();
}
//执行sql语句
boolean flag=connection.executeUpdate(sql);
return flag;
}
/*
* @功能 查询指定文章的详细内容
* @参数 id为文章ID值
* @返回值 ArticleBean类对象,封装了文章信息
*/
public ArticleBean queryArticleByID(int id) {
String sql="select * from tb_article where id="+id;
ResultSet rs=connection.executeQuery(sql);
try {
while(rs.next()){
articleBean=new ArticleBean();
articleBean.setId(rs.getInt(1));
articleBean.setArticleTypeID(rs.getInt(2));
articleBean.setArticleTitle(rs.getString(3));
articleBean.setArticleContent(rs.getString(4));
articleBean.setArticleSdTime(rs.getString(5));
articleBean.setArticleFrom(rs.getInt(6));
articleBean.setArticleInfo(rs.getString(7));
articleBean.setArticleCount(rs.getInt(8));
articleBean.setMasterID(rs.getInt(9));
// //查询tb_review数据表统计当前文章的评论数
// sql="select count(id) from tb_review where review_articleID="+articleBean.getId();
// ResultSet rsr=connection.executeQuery(sql);
// if(rsr!=null){
// rsr.next();
// articleBean.setReview(rsr.getInt(1));
// rsr.close();
// }
}
} catch (SQLException e) {
e.printStackTrace();
}
return articleBean;
}
}
这个ArticleDao有两个成员,一个是DB,一个是articleBean,articleBean就不用说了,是一个文章的类,和数据库的文章表相对应。DB是也给连接数据库的类。
我们来看DB类:
package com.MyBlog.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
* 定义DB类,用于数据库的链接
*/
public class DB {
private final String url="jdbc:mysql://localhost:3306/MyBlogDB";
private final String userName="root";
private final String password="";
private Connection con=null;
private Statement stm=null;
/*通过构造方法加载数据库驱动*/
public DB(){
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("加载数据库驱动驱动失败!!!");
e.printStackTrace();
}
}
/*创建数据库连接*/
public void createCon(){
try {
con=DriverManager.getConnection(url,userName,password);
} catch (SQLException e) {
System.out.println("创建数据库连接失败!!");
e.printStackTrace();
}
}
/*获取数据库连接*/
public Connection getCon(){
try {
con=DriverManager.getConnection(url,userName,password);
} catch (SQLException e) {
System.out.println("获取数据库连接失败!!!");
e.printStackTrace();
}
return con;
}
/*获取Statement对象*/
public void getStm(){
createCon();
try {
stm=con.createStatement();
} catch (SQLException e) {
System.out.println("创建Statement对象失败!!!");
e.printStackTrace();
}
}
/*
* 对数据库进行增加、修改、删除操作
* 参数SQL为要执行的sql语句
* 返回boolean的值
*/
public boolean executeUpdate(String sql){
System.out.println("数据库中正在执行的SQL语句:"+sql);
boolean mark=false;
try {
getStm();
int iCount=stm.executeUpdate(sql);
if(iCount>0){
mark=true;
}else{
mark=false;
}
} catch (SQLException e) {
e.printStackTrace();
mark=false;
}
return mark;
}
/*
*查询数据库
*/
public ResultSet executeQuery(String sql){
ResultSet rs=null;
try {
getStm();
rs=stm.executeQuery(sql);
} catch (SQLException e) {
System.out.println("查询数据库数据失败!!!");
e.printStackTrace();
}
return rs;
}
/*
*关闭数据库的操作
*/
public void closed(){
if(stm!=null){
try {
stm.close();
} catch (SQLException e) {
System.out.println("关闭stm对象失败!!!");
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
System.out.println("关闭con对象失败");
e.printStackTrace();
}
}
}
}
我们这个DB类的成员有数据库的url,数据库的用户名,数据库的秘密,还有Connection对象和Statement对象。首先,这个DB通过构造函数加载数据库驱动。createCon函数用于进行数据库连接,我们的数据库连接通过DriverManager完成,并返回一个Connection对象,并赋值给DB的Connection对象成员:con.
con=DriverManager.getConnection(url,userName,password);
或者getCon直接返回一个Connection对象,同时也复制给DB的Connection成员,它和createCon的区别是它会返回这个Connection对象。getStm是获取Statement对象的方法,这个对象的获得是先进行数据库的连接,然后由con的createStatement方法获得。
这几个函数就是对数据库的增删查改用的:
1)DB的成员函数excuteUpdate,执行数据库语句,没有返回值的,我们执行数据库语句是由Statement对象来执行的,Statement对象的excuteUpdate方法就是对数据库进行操作,比如增加,删除,修改等等,若是excuteUpdate函数返回-1,则是操作失败,我们返回false,若是操作成功,我们返回true。
2)DB的成员函数excuteQuery,执行数据库的查询,我们的查询也是由Statement对象来查询的,通过执行Statement对象的excuteQuery函数查询,查询返回ResultSet类型的结果,然后我们这个DB的成员函数excuteQuery函数返回ResultSet类型的结果。
3)最后一个是断开数据库连接的函数,我们通过Statement对象执行close方法来关闭Statement对象,con的close方法端口数据库的连接。
在我们的dao类里面,是要调用DB的方法来和数据库操作的。
我们在dao类里面,范式执行什么操作,我们先要设定好sql语句,我们通过以下判断设置这些操作语句。
我们就拿ArticleDao类来说,比如说我们的查询文章,我们在ArticleDao类里面,queryArticle方法是查询文章的,我们有两个参数,一个是typeID,一个是type,如果typeID是-1的话,不按类别查询,那就没有where的判断,然后type是空的话,那么只查询最近的几篇文章,这得加上limit来限制,或type是非空,则查询所有的记录,不加limit。若typeID>0,则按照类别查询,那么就必须用where判断这个类别是否符合要求,typeID就是指定的那个类别的id,然后type如果是空,那么只查询该类别最近的几条记录,用limit来限制,或type非空,查询该类别的所有记录,不用limit。
通过以上的设定,我们总能得出我们想要的那一条sql语句,然后我们通过DB对象connection的excuteQuery(sql)函数来查询,这个sql就是我们在前面通过各种条件判断设置的sql语句。然后这个函数返回的是ResultSet类型的数据。所以我们还要把这个类型的数据取出来,设置到articleBean里面,我们的rs里面的语句可能有很多条,所以我们用while(rs.next())的循环,不断一条一条地读出来。同时我们在这个while循环里面new一个ArticleBean对象,我们在rs里面读出每一条数据,都设置到ArticleBean对象,然后把这个对象添加的articleList容器里面(List articleList = new ArrayList();argicleList是个List容器),最后我们的articleList就存到了很多个ArticleBean对象,都是从rs里面都出来的,这个articleList就是我们这个函数要返回的结果。就这样我们的查询结果出来了。
然后这个ArticleDao类的queryArticle方法就在我们的ArticleAction里面调用,获得我们想要的结果。
除了查询,我们还有一个函数,就是执行sql增删改的函数,operationArticle,这个函数有两个参数,oper和articleBean对象。Oper指定我们是增是删还是改,还有一个对于文章所独有的就是增加阅读次数。和查询那边一样,我们要执行相应的操作前,先设定好sql语句。
下面是操作的几个类型:
1)如果oper是add,那么是增加,我们就执行insert into 语句,因为我们的数据库的article的表是和articlebean对象是对应的,我们就把这个articlebean内容都添加到这个article表中。
2)然后是oper是modify,那么是修改,修改我们执行的是update语句,我们先通过where限定这个的id必须是和articleBean的id是一样的,然后我们再把这个表里面的数据改成和articleBean一样的数据。
3)Oper是delete的话,这个就比较简单了,我们用where来限定这个id就是articleBean的id,我们就删除这个表里面的这一条数据。
4)还有一个oper是readTimes,这个和修改改是是差不多了,只不过我们是吧这个articleBean里面的文章阅读次数加1,然后通过update语句,只修改article_count即文章阅读次数的值。
就这样,我们的sql语句设定好之后,就由DB类的对象connection的excuteUpdate(sql)函数来执行,执行的结果返回一个boolean值,这个值再由operationArticle返回,然后我们的ArticleAction就可以知道这个操作是否成功了。
5)除了以上的几个,我们还有个快速的查询方法,就是queryArticleById,这个直接通过一个id,查询出这个id的文章所有信息。我们的sql语句就直接设定成:"select * from tb_article where id="+id;,然后同样有connection对象执行excuteQuery(sql)函数,结果是返回ResultSet类型。
然后我们在通过while(rs.next())循环把这个数据取出来,设置到articleBean里面,由于这里我们查询的结果只有一条数据,所以我们也就不用articleList了,这个循环也只是执行一次就退出了循环。然后我们的整个queryArticleById也只返回这个articleBean就可以了,最后我们的ArticleAcion会得到这个结果。
文章的dao类也就这些查询,至于其它的dao类的查询也是按照这一种方式,设定了可对相应的数据库的增删查改的函数,我们的相应的action类,可根据需要调用不同的函数,传递不同的参数,得到自己想要的结果。