DAO模式:
Data Access Object(数据存取对象)
位于业务逻辑和持久化数据之间
实现对持久化数据的访问
DAO起着转换器的作用,把实体类转换为数据库中的记录
DAO模式的组成部分:
DAO接口;DAO实现类;实体类;数据库连接和关闭工具类
properties配置文件:
Java中的配置文件常为properties文件:
- 后缀为.properties
- 格式是“键=值”格式
- 使用“#”来注释
示例:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.connection.url=jdbc:mysql://127.0.0.1:3306/kgcnews
jdbc.connection.username=root
jdbc.connection.password=08170327
读取配置文件:
Java中提供了Properties类来读取配置文件:
方法名 | 说明 |
String getProperty(String key) | 用指定的键在此属性列表中搜索属性。通过参数key得到其所对应的值 |
Object setProperty(String key,String value) | 调用Hashtable的方法put。通过调用基类的put()方法来设置键-值对 |
void load(InputStream inStream) | 从输入流中读取属性列表 (键和元素对)。通过对指定文件进行装载获取该文件中所有键-值对 |
void clear() | 清除所装载的键-值对,该方法由基类Hashtable提供 |
使用实体类传递数据:
数据访问代码和业务逻辑代码之间通过实体类来传输数据
实体类特征:
- 属性一般使用private修饰
- 提供public修饰的getter/setter方法
- 实体类提供无参构造方法,根据业务提供有参构造
- 实现java.io.Serializable接口,支持序列化机制
Service的使用:
Service其实就是一个接口,负责业务逻辑的
删除某个新闻类别(需要调用两个Dao的方法,配合工作):
查询某个新闻分类下是否有新闻
若有,则提示无法删除
若无,删除该分类
NewsCategoryDao ---> 删除新闻分类deleteCategory (NewsCategory category);
public class NewsCategory {
private int id;
private String name;
private Date createDate;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
}
NewsCategoryDaoImpl实现 deleteCategory(NewsCategory category){ delete from… }
public class NewsCategoryDaoImpl extends BaseDao implements NewsCategoryDao {
//删除某个新闻类别
public boolean deleteNewsCategory(NewsCategory newsCategory) {
boolean flag = false;
String sql = "delete from news_category where id = ?";
Object[] params = {newsCategory.getId()};
int i = this.executeUpdate(sql, params);
if(i>0){
System.out.println("删除新闻类别成功!");
flag = true;
}
this.closeResource();
return flag;
}
}
NewsDao ---> 查询某个新闻分类下是否有新闻getNewsCountByCategory (NewsCategory category);
public interface NewsDao {
//通过数据源获取连接,进行数据库操作,查询新闻
public void getNewsListByDs();
//增加新闻信息
public void addNews(News news);
//删除特定新闻方法
public void deleteNews(News news);
//修改特定新闻方法
public void updateNews(News news);
//查询全部新闻信息
public void getNewsList();
//查询特定标题的新闻信息
public void getNewsByTitle(News news);
//查询摸个新闻分类下是否有新闻
public int getCountByCategory(NewsCategory newsCategory);
}
NewsDaoImpl 实现
SELECT COUNT(1) FROM news_ detail
WHERE categoryid = ?
public class NewsDaoImpl extends BaseDao implements NewsDao {
Connection connection=null;
ResultSet rs = null;
//通过数据源获取连接,进行数据库操作,查询新闻
public void getNewsListByDs(){
}
//查询摸个新闻分类下是否有新闻
public int getCountByCategory(com.jdbc.pojo.NewsCategory newsCategory){
int count = 0;
try {
String sql = "SELECT COUNT(1) FROM news_detail WHERE categoryid = ?";
Object[] params = {newsCategory.getId()};
ResultSet rs = this.executeSQL(sql, params);
while(rs.next()){
count = rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
}
return count;
}
public void addNews(News news){
try{
String sql = "INSERT INTO news_detail(id,categoryid,title,summary,content,author,createdate,modifyDate) VALUES(?,?,?,?,?,?,?,?)";
Object[] params = {news.getId(),news.getCategoryid(),news.getTitle(),news.getSummary(),news.getContent(),news.getAuthor(),news.getCreatedate(),news.getModifyDate()};
int i = this.executeUpdate(sql, params);
if(i>0){
System.out.println("插入新闻成功!");
}
}finally{
this.closeResource();
}
}
//删除特定新闻的方法
public void deleteNews(News news){
try{
String sql = "DELETE FROM news_detail WHERE id=?";
Object[] params = {news.getId()};
int i = this.executeUpdate(sql,params);
if(i>0){
System.out.println("删除新闻成功!");
}
}finally{
this.closeResource();
}
}
//修改特定新闻标题的方法
public void updateNews(News news){
try{
String sql = "UPDATE news_detail SET title =? WHERE id=?";
Object[] params = {news.getTitle(),news.getId()};
int i = this.executeUpdate(sql,params);
if(i>0){
System.out.println("修改新闻成功!");
}
}finally{
this.closeResource();
}
}
//查询全部新闻信息
public void getNewsList(){
try {
String sql = "SELECT id,categoryid,title,summary,content,author,createdate FROM news_detail";
Object[] params = {};
rs = this.executeSQL(sql,params);
while(rs.next()){
int id = rs.getInt("id");
int categoryid = rs.getInt("categoryid");
String newsTitle = rs.getString("title");
String summary = rs.getString("summary");
String content = rs.getString("content");
String author = rs.getString("author");
Timestamp createdate = rs.getTimestamp("createdate");
System.out.println(id+"\t"+categoryid+"\t"+newsTitle+"\t"+summary+"\t"+content+"\t"+author+"\t"+createdate);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeResource();
}
}
//查询特定标题的新闻信息
public void getNewsByTitle(News news){
try {
String sql = "SELECT id,title FROM news_detail where title=?";
Object[] params= {news.getTitle()};
rs = this.executeSQL(sql,params);
while(rs.next()){
int id = rs.getInt("id");
String newsTitle = rs.getString("title");
System.out.println(id+"\t"+newsTitle);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
this.closeResource();
}
}
public static void main(String[] args){
NewsDao dao=new NewsDaoImpl();
// News news = new News();
// news.setId(5);
// news.setCategoryid(12);
// news.setTitle("测试");
// news.setContent("测试content");
// news.setAuthor("测试");
// news.setSummary("测试summary");
// news.setContent("测试content");
// news.setCreatedate(new Date());
// news.setModifyDate(new Date());
// dao.addNews(news);
// News news = new News();
// news.setId(5);
// news.setTitle("新测试");
// dao.updateNews(news);
News news = new News();
news.setId(5);
dao.deleteNews(news);
dao.getNewsList();
}
}
如下代码写在Service中的NewCategoryService
int count = NewsDao.getNewsCountByCategory(category)
if(count==0){
NewsCategoryDao. deleteCategory(category);
System.out.println("无法删除该分类!");
}else{
System.out.println("无法删除该分类!");
}
dao层--数据访问接口层:
- 主要负责和数据操作相关的事情
- 一般一个dao对应操作一张数据表
- 接口:NewsDao
- 接口实现类:NewsDaolmpl
Service层--业务逻辑层
- 主要负责与业务逻辑相关操作,对dao层的封装和调用
- 接口:NewsService
- 接口实现类:NewsServicelmpl
为什么需要分层:
JSP开发时分两层的弊端:
展示逻辑与业务流程混合、或者业务代码与数据访问混合
编码职责不清,修改时互相影响,难以扩展和重用
三层模式的划分:
层与层之间的关系:
表示层依赖于业务逻辑层
业务逻辑层依赖于数据访问层
分层原则:
- 上层依赖其下层,依赖关系不跨层
- 表示层不能直接访问数据访问层
- 上层调用下层的结果,取决于下层的实现
- 下一层不能调用上一层
- 下一层不依赖上一层
- 上层的改变不会影响下一层
- 下层的改变会影响上一层得到的结果
- 在上一层中不能出现下一层的概念:分工明确,各司其职
使用脚本与HTML嵌套,页面代码很乱,可读性差,也不易于维护,能否进行改进?
JSP动作标签:
通过动作标签,程序员可以在JSP页面中把页面的显示功能部分封装起来,使整个页面更简洁和易于维护
<jsp:useBean>
装载一个将在JSP页面中使用的JavaBean,发挥Java组件重用的优势
<jsp:include>
增加新闻信息页面和新闻列表显示页面的左侧和上半部分完全一样,要把页面代码全部重新写一遍或者复制一遍吗?
<jsp:include>
把指定文件插入正在生成的页面中
jsp:include相当于是把一个页面包含进来,这是一个动态包含。
示例:<jsp:include page="adminSidebar.jsp"></jsp:include>
这也是一个include指令,不再是page=?而是file=?,这是一个静态包含。
<%@include%>与<jsp:include>的关系:
- <jsp: include>为动态包含,将被包含页面的结果包含进来。
先处理,再包含
- <%@include%>为静态包含,将被包含页面的内容包含进来。
先包含,再处理
页面跳转:
request.getRequestDispatcher( ).forward( ) 转发
response.sendRedirect( ) 重定向
<jsp:forward>
和request.getRequestDispatcher( ).forward( ):转发;效果是一样的