多对一关系主要应用在添加,修改,列表上,删除功能用不到多对一关系。(实际开发中多对一的应用较多)
例:这里多加入一张新闻类型表,完成新闻的分类功能。
在新闻表中多加入一个分类的字段,表示该新闻属于某一类。
新闻类型是 一, 新闻是 多。
实现的效果:
建立数据库表:
CREATE TABLE news_type (
tid number(8) primary key ,
tname varchar2(50) not null
);
INSERT INTO news_type VALUES (1,'经济');
INSERT INTO news_type VALUES (2,'军事');
INSERT INTO news_type VALUES (3,'娱乐');
INSERT INTO news_type VALUES (4,'游戏');
INSERT INTO news_type VALUES (5,'广告');
CREATE TABLE news (
id number(8) primary key ,
title varchar2(50) not null,
content varchar2(500) not null,
pub_date date not null,
type_id number(8) not null,
foreign key (type_id) references news_type (tid) on delete cascade
);
commit;
下面生成映射,完成一对多关系配置,这里上篇博客详细介绍了。
数据库操作与之前没有变化,因此可以继续使用之前的代码。
一、先来看添加功能
由于多了一个选择新闻分类的操作,因此在进入添加页前,需要先查询出所有的分类信息,也就是要先在后台完成NewsType的查询全部的功能。
实际开发中,每个功能模块会对应一个Action,同时对应一个Service,而并不是一个DAO对应一个Service。Service主要处理的是业务逻辑,是根据当前功能,组合调用DAO来完成数据操作。
public List<NewsType> insertPre() {
List<NewsType> all = null;
try {
all = DAOFactory.getINewsTypeDAOInstance().findAll();
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateSessionFactory.closeSession();
}
return all;
}
修改超连接,不能直接进入insert.jsp了,必须先进入Action查询出全部分类,再进入jsp完成下拉列表的显示。
<a href="news!insertPre.action">添加新闻</a>
在Action中加入insertPre的方法,并完成查询
// 取得所有的新闻分类列表
private List<NewsType> allType;
public String insertPre() throws Exception {
allType = ServiceFactory.getINewsServiceInstance().insertPre();
return "insert";
}
配置struts:
<result name="insert">/pages/news/news_insert.jsp</result>
页面上循环列表,显示出下拉列表数据。
<center>
<form action="news!insert.action" method="post">
新闻标题:
<input type="text" name="news.title" />
<br />
新闻内容:
<input type="text" name="news.content" />
<br />
发布日期:
<input type="text" name="news.pubDate" />
<br />
所属分类:
<select name="news.newsType.tid">
<option value="0">-请选择分类-</option>
<c:forEach var="t" items="${allType}">
<option value="${t.tid}">${t.tname }</option>
</c:forEach>
</select>
<br/>
<input type="submit" value="添加" />
</form>
</center>
一样会出现懒汉式异常,需要在映射文件中加入lazy=”false”,这里的懒汉式异常,可能会包的是数据无法识别NumberFormatException。
<many-to-one name="newsType" lazy="false" class="org.liky.pojo.NewsType" fetch="select">
<column name="TYPE_ID" precision="8" scale="0" not-null="true" />
</many-to-one>
二、处理修改功能
进入修改页时,不只要查询新闻的数据,还要查询所有新闻分类的信息,以便实现下拉列表。
因此Service方法需要修改。
public Map<String, Object> updatePre(int id) {
Map<String, Object> map = new HashMap<String, Object>();
try {
map.put("news", DAOFactory.getINewsDAOInstance().findById(id));
map.put("allType", DAOFactory.getINewsTypeDAOInstance().findAll());
} catch (Exception e) {
e.printStackTrace();
} finally {
HibernateSessionFactory.closeSession();
}
return map;
}
在Action中完成调用。
public String updatePre() throws Exception {
Map<String, Object> map = ServiceFactory.getINewsServiceInstance()
.updatePre(news.getId());
news = (News) map.get("news");
allType = (List<NewsType>) map.get("allType");
return "update";
}
页面上显示
<form action="news!update.action" method="post">
新闻标题:
<input type="text" name="news.title" value="${news.title }"/>
<br />
新闻内容:
<input type="text" name="news.content" value="${news.content }"/>
<br />
发布日期:
<input type="text" name="news.pubDate" value="${news.pubDate }"/>
<br />
所属分类:
<select name="news.newsType.tid">
<option value="0">-请选择分类-</option>
<c:forEach var="t" items="${allType}">
<option value="${t.tid }" ${t.tid==news.newsType.tid?"selected":"" }>
${t.tname }</option>
</c:forEach>
</select>
<br/>
<input type="hidden" name="news.id" value="${news.id }"/>
<input type="submit" value="修改" />
</form>
附:通过简单的事例说明清楚Hibernate在处理一对多,多对一中的方式方法,有哪些区别。一对多应用通常表现在动态的级联关系上(js也能做到,但是却是静态的);
多对一关系通常在插入,修改,查询时,作为一列属性加入到数据库中的。