`
gevin
  • 浏览: 40884 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用Nutz[1.b.38]对关联数据表的一对一/一对多操作

    博客分类:
  • Nutz
 
阅读更多

本文在上一篇《使用Nutz[1.b.38]对数据库表的CRUD操作》的基础上进行扩展,有兴趣的话可以先阅读一下。

 

在完成此demo的过程中,发现DAO中有某些需求目前还无法完成,文章末尾会提到,只能待灰太狼解决了。

 

好了,直接上教程,关于一些环境、数据源和dao对象、web.xml的配置,请移步上一篇查看。

 

 

进入主题:

 

一、此demo涉及两个表DepartmentInfo和UserInfo,SQL如下:

-- ----------------------------

-- Table structure for `departmentinfo`

-- ----------------------------

DROP TABLE IF EXISTS `departmentinfo`;

CREATE TABLE `departmentinfo` (

  `departmentInfoId` int(11) NOT NULL AUTO_INCREMENT,

  `departmentName` varchar(50) DEFAULT NULL,

  PRIMARY KEY (`departmentInfoId`)

) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of departmentinfo

-- ----------------------------

INSERT INTO `departmentinfo` VALUES ('1', 'IT部');

INSERT INTO `departmentinfo` VALUES ('2', '人力资源');

INSERT INTO `departmentinfo` VALUES ('3', '财务部');

INSERT INTO `departmentinfo` VALUES ('4', '市场部');

 

-- ----------------------------

-- Table structure for `userinfo`

-- ----------------------------

DROP TABLE IF EXISTS `userinfo`;

CREATE TABLE `userinfo` (

  `userInfoId` int(11) NOT NULL AUTO_INCREMENT,

  `trueName` varchar(20) DEFAULT NULL,

  `departmentInfoId` int(11) DEFAULT NULL,

  `addDate` datetime DEFAULT NULL,

  `addIp` varchar(15) DEFAULT NULL,

  PRIMARY KEY (`userInfoId`)

) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of userinfo

-- ----------------------------

INSERT INTO `userinfo` VALUES ('1', 'Gevin', '1', '2011-07-25 19:28:50', '127.0.0.1');

INSERT INTO `userinfo` VALUES ('2', 'Wendal', '1', '2011-07-25 19:29:07', '127.0.0.1');

INSERT INTO `userinfo` VALUES ('3', '小宝', '2', '2011-07-25 19:29:55', '127.0.0.1');

INSERT INTO `userinfo` VALUES ('4', '灰太狼', '3', '2011-07-25 19:30:11', '127.0.0.1');

INSERT INTO `userinfo` VALUES ('5', 'E-Hunter', '3', '2011-07-25 19:30:38', '127.0.0.1');

INSERT INTO `userinfo` VALUES ('8', 'k-wait', '4', '2011-07-26 15:54:01', '127.0.0.1');

 

 

二、结构图



 

二、Model类

DepartmentInfo.java

 

package demo.nutz.model;

import java.util.List;

import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.Many;
import org.nutz.dao.entity.annotation.Table;

@Table("DepartmentInfo")
public class DepartmentInfo {

	@Id
	private Integer departmentInfoId;
	private String departmentName;

	// 一对多关联用户信息
	@Many(target = UserInfo.class, field = "departmentInfoId")
	private List<UserInfo> userInfoList;
	
	/*此处省略Getter和Setter*/

}

 

 

UserInfo.java类

 

package demo.nutz.model;

import java.util.Date;

import org.nutz.dao.entity.annotation.Id;
import org.nutz.dao.entity.annotation.One;
import org.nutz.dao.entity.annotation.Table;

@Table("UserInfo")
public class UserInfo {

	@Id
	private Integer userInfoId;
	private String trueName;
	private Integer departmentInfoId;
	private Date addDate;
	private String addIp;

	// 一对一关联部门信息
	@One(target = DepartmentInfo.class, field = "departmentInfoId")
	private DepartmentInfo departmentInfo;
	
	/*此处省略Getter和Setter*/

}

 

 

 

三、模块类

DepartmentInfoAction.java跟上一篇一样,没改动。这里主要讲一下UserInfoAction.java类。

 

package demo.nutz.action;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.nutz.dao.Cnd;
import org.nutz.ioc.loader.annotation.Inject;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.mvc.annotation.At;
import org.nutz.mvc.annotation.Ok;
import org.nutz.mvc.annotation.Param;

import demo.nutz.base.BaseAction;
import demo.nutz.model.DepartmentInfo;
import demo.nutz.model.UserInfo;
import demo.nutz.service.DepartmentInfoService;
import demo.nutz.service.UserInfoService;

/**
 * 用户信息模块
 * 
 * @author gevin(gevinhjy@foxmail.com)
 * 
 */
@IocBean
@At("/userinfo")
public class UserInfoAction extends BaseAction {

	@Inject		// 通过注解@Inject注入对象
	private DepartmentInfoService departmentInfoService;
	
	@Inject		// 通过注解@Inject注入对象
	private UserInfoService userInfoService;

	/**
	 * 跳转到添加页面
	 * 
	 * @return
	 */
	@At("/addUserInfo")
	@Ok("jsp:${obj.msg == null ? '/userinfo/addUserInfo' : '/userinfo/showMessage'}")		// 在@Ok中使用NutzEL表达式
	public Map<String, Object> addUserInfo() {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			// 获取部门列表
			List<DepartmentInfo> diList = this.departmentInfoService.query(Cnd.orderBy().asc("departmentName"), null);
			map.put("departmentInfoList", diList);
			
			return success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}

	/**
	 * 添加成功
	 * 
	 * @param ui
	 * @return
	 */
	@At("/addUserInfoOk")
	@Ok("jsp:/userinfo/showMessage")
	public Map<String, Object> addUserInfoOk(@Param("..") UserInfo ui, HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if (ui==null || ui.getDepartmentInfoId()==null)
				return failure(GET_FAILURE, map);
			
			// 获取部门信息
			DepartmentInfo di = this.departmentInfoService.fetch(ui.getDepartmentInfoId());
			if (di == null)
				return failure(GET_FAILURE, map);
			
			ui.setAddDate(new Date());
			ui.setAddIp(request.getRemoteAddr());
			
			// 添加成功
			if (this.userInfoService.dao().insert(ui) == null)
				return failure(ADD_FAILURE, map);

			return success(ADD_SUCCESS, map);
		} catch (Exception e) {
			e.printStackTrace();
			map.put("msg", "getFailure");
			return map;
		}
	}

	/**
	 * 跳转到修改页面
	 * 
	 * @param userInfoId
	 * @return
	 */
	@At("/editUserInfo")
	@Ok("jsp:${obj.msg == null ? '/userinfo/editUserInfo' : '/userinfo/showMessage'}")
	public Map<String, Object> editUserInfo(@Param("userInfoId") Integer userInfoId) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if (userInfoId == null)
				return failure(GET_FAILURE, map);

			// 获取对象
			UserInfo ui = this.userInfoService.fetch(userInfoId);
			if (ui == null)
				return failure(GET_FAILURE, map);
			map.put("userInfo", ui);
			
			// 获取部门列表
			List<DepartmentInfo> diList = this.departmentInfoService.query(Cnd.orderBy().asc("departmentName"), null);
			map.put("departmentInfoList", diList);
			
			return success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}

	/**
	 * 修改成功
	 * 
	 * @param ui
	 * @return
	 */
	@At("/editUserInfoOk")
	@Ok("jsp:/userinfo/showMessage")
	public Map<String, Object> editUserInfoOk(@Param("..") UserInfo ui) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if (ui == null)
				return failure(GET_FAILURE, map);

			// 获取原有对象
			UserInfo uiOld = this.userInfoService.fetch(ui.getUserInfoId());
			if (uiOld == null)
				return failure(GET_FAILURE, map);
			
			// 设置原对象信息
			ui.setAddDate(uiOld.getAddDate());
			ui.setAddIp(uiOld.getAddIp());
			
			// 修改对象
			if (this.userInfoService.dao().update(ui) == 0)
				return failure(EDIT_FAILURE, map);

			return success(EDIT_SUCCESS, map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}

	/**
	 * 删除成功
	 * 
	 * @param ui
	 * @param request
	 * @return
	 */
	@At("/delUserInfoOk")
	@Ok("jsp:/userinfo/showMessage")
	public Map<String, Object> delUserInfoOk(@Param("..") UserInfo ui, HttpServletRequest request) {
		Map<String, Object> map = new HashMap<String, Object>();
		try {
			if (ui == null)
				return failure(GET_FAILURE, map);

			// 删除对象
			if (this.userInfoService.dao().delete(ui) == 0)
				return failure(DEL_FAILURE, map);

			return success(DEL_SUCCESS, map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}

	/**
	 * 显示列表[主要用来体现一对一的关系]
	 * 
	 * @return
	 */
	@At("/showUserInfoList")
	@Ok("jsp:/userinfo/showUserInfoList")
	public Map<String, Object> showUserInfoList() {
		Map<String, Object> map = new HashMap<String, Object>();
		List<UserInfo> okList = new ArrayList<UserInfo>();	// 存放已关联部门信息对象的用户列表
		try {
			// 获取用户列表
			List<UserInfo> uiList = this.userInfoService.query(Cnd.orderBy().asc("departmentInfoId"), null);
			
			// 循环设置关联部门信息
			for (UserInfo ui : uiList) {
				this.userInfoService.dao().fetchLinks(ui, "departmentInfo");
				okList.add(ui);
			}
			map.put("userInfoList", okList);
			return success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}
	
	/**
	 * 显示列表[主要用来体现一对多的关系]
	 * 
	 * @return
	 */
	@At("/showUserInfoList2")
	@Ok("jsp:/userinfo/showUserInfoList2")
	public Map<String, Object> showUserInfoList2() {
		Map<String, Object> map = new HashMap<String, Object>();
		List<DepartmentInfo> okList = new ArrayList<DepartmentInfo>();	// 定义存放已关联人员信息的部门列表
		try {
			// 获取部门列表
			List<DepartmentInfo> diList = this.departmentInfoService.query(Cnd.orderBy().asc("departmentInfoId"), null);
			
			// 循环设置关联人员信息
			for (DepartmentInfo di : diList) {
				this.departmentInfoService.dao().fetchLinks(di, "userInfoList");
				okList.add(di);
			}
			map.put("departmentInfoList", okList);
			return success(map);
		} catch (Exception e) {
			e.printStackTrace();
			return failure(GET_FAILURE, map);
		}
	}

}

由于Nutz没有提供像Hibernate中的是否延迟加载关联对象的功能,若想获取关联对象的数据,需手工用代码获取。

如UserInfoAction.java中showUserInfoList()方法:

必须先获取到用户列表后,再循环该用户列表,获取用户所属的部门的对象,再将数据设置回UserInfo中。

 

又如showUserInfoList2()方法:

必须先获取到部门列表,再根据departmentInfoId获取该部门的用户列表,再设置到departmentInfo.userInfoList属性中。

 

 

四、JSP文件

showUserInfoList.jsp:体现一对一的关系

 

<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %>
<%@ include file="../include/taglibs.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>员工信息列表</title>
<link href="../css/web.css" rel="stylesheet" type="text/css" />
</head>

<body>
<br />
<table width="500" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="35"><label>
      <input type="button" name="add" id="add" value="添加员工信息" onclick="window.location='addUserInfo.shtml'" />
     <input type="button" name="add" id="add" value="部门信息管理" onclick="window.location='../departmentinfo/showDepartmentInfoList.shtml'" />
    </label></td>
  </tr>
</table>
<table width="500" border="0" align="center" cellpadding="1" cellspacing="1" class="TableOut">
  <tr>
    <td height="30" colspan="4" align="center" class="TableTop">员工信息列表</td>
  </tr>
  <tr class="TableInWhite">
    <td width="68" height="30" align="center">序号</td>
    <td width="167" align="center">部门</td>
    <td width="130" align="center">姓名</td>
    <td width="122" align="center">操作</td>
  </tr>
  <c:forEach var = "ui" items = "${obj.userInfoList}" varStatus="status">
  <tr class="TableInWhite">
    <td height="30" align="center"><c:out value="${status.count}" /></td>
    <td align="center"><c:out value="${ui.departmentInfo.departmentName}" /></td>
    <td align="center"><c:out value="${ui.trueName}" /></td>
    <td align="center">[<a href="editUserInfo.shtml?userInfoId=${ui.userInfoId}">修改</a>]&nbsp;&nbsp;[<a href="delUserInfoOk.shtml?userInfoId=${ui.userInfoId}" onclick="return confirm('是否真的要删除此员工?')">删除</a>]</td>
  </tr>
  </c:forEach>
</table>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="45">此列表主要体现一对一的关系,其中获取部门的代码是{ui.departmentInfo.departmentName}<br />
      若想了解一对多的关系,可以查看另外一种显示方式:<a href="showUserInfoList2.shtml" style="color:#F00">员工信息列表[一对多]</a></td>
  </tr>
</table>
</body>
</html>

其中获取部门名称的代码是${ui.departmentInfo.departmentName}

 

 

 

showUserInfoList2.jsp:体现一对多的关系

 

<%@ page contentType="text/html; charset=utf-8" language="java" import="java.sql.*" errorPage="" %>
<%@ include file="../include/taglibs.jsp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>员工信息列表</title>
<link href="../css/web.css" rel="stylesheet" type="text/css" />
</head>

<body>
<br />
<table width="500" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="35"><label>
      <input type="button" name="add" id="add" value="添加员工信息" onclick="window.location='addUserInfo.shtml'" />
     <input type="button" name="add" id="add" value="部门信息管理" onclick="window.location='../departmentinfo/showDepartmentInfoList.shtml'" />
    </label></td>
  </tr>
</table>
<table width="500" border="0" align="center" cellpadding="1" cellspacing="1" class="TableOut">
  <tr>
    <td height="30" align="center" class="TableTop">员工信息列表</td>
  </tr>
  <c:forEach var = "di" items = "${obj.departmentInfoList}" varStatus="status">
  <tr class="TableInWhite">
    <td height="30" align="left"><span style="font-weight:bold"><c:out value="${di.departmentName}" /></span></td>
  </tr>
  <tr class="TableInWhite">
    <td height="30" align="left" style="padding-left:10px;">
    <c:forEach var = "ui" items = "${di.userInfoList}" varStatus="status">
    <c:out value="${ui.trueName}" />&nbsp;&nbsp;
    </c:forEach>
    </td>
    </tr>
  </c:forEach>
</table>
<table width="500" border="0" align="center" cellpadding="0" cellspacing="0">
  <tr>
    <td height="45">此列表主要体现一对多的关系,其中获取人员列表的代码是{di.userInfoList}<br />
      若想了解一对一的关系,可以查看另外一种显示方式:<a href="showUserInfoList.shtml" style="color:#F00">员工信息列表[一对一]</a></td>
  </tr>
</table>
</body>
</html>

 其中使用

 

 <c:forEach var = "ui" items = "${di.userInfoList}" varStatus="status">
    <c:out value="${ui.trueName}" />&nbsp;&nbsp;
    </c:forEach>

 

来循环列出该部门的所有用户。

 

 

五、重启Tomcat,访问以下地址:

http://127.0.0.1:204/UserManageSystem/userinfo/showUserInfoList.shtml

 

 

效果图如下:

showUserInfoList.jsp

 

 

 

showUserInfoList2.jsp

----------------------------------------------------------------------------------------------------------------------

 

 

OK,第二篇教程搞定了。希望对大家有用。

 

在此demo中,发现了dao中有一个问题目前还没有解决,即Nutz中关联查询的排序问题,假如我在查询用户列表时,无法通过departmentInfo.departmentName字段来排序,即无法使用以下代码获取:

List<UserInfo> uiList = this.userInfoService.query(Cnd.orderBy().asc("departmentInfo.departmentName"), null);

 

此需求已提交给灰太狼,待解决。

 

目前要解决此问题,可以不使用对象关联,而是通过Nutz提供的视图来解决。

 

Nutz中提供的视图功能还是蛮给力的!只不过后期维护的时候,如增加字段、删除字段,要记得更新视图才行。

 

关于Nutz如何使用视图,会在下一篇《在Nutz[1.b.38]中使用视图对关联数据表的操作》讲到。

 

好了,最后把源代码奉上!!!

 

 

 

  • 大小: 43.7 KB
  • 大小: 30.5 KB
  • 大小: 50.2 KB
  • 大小: 40.2 KB
分享到:
评论
2 楼 gevin 2011-12-22  
kaywood 写道
员工信息列表界面,要使用部门名称来模糊查询,并且需要分页,用NUTZ该怎么做?

已跟Nutz管理员沟通过,他表示暂时不打算让Nutz支持关联对象的属性查询或排序。目前要解决此问题,可以通过视图来解决。可参考在Nutz[1.b.38]中使用视图对关联数据表的操作
1 楼 kaywood 2011-11-21  
员工信息列表界面,要使用部门名称来模糊查询,并且需要分页,用NUTZ该怎么做?

相关推荐

    在Nutz[1.b.38]中使用视图对关联数据表的操作

    在Nutz 1.b.38 版本中,视图是处理关联数据表操作的一种高效方式。Nutz 是一个轻量级的Java框架,它提供了丰富的功能来支持数据库操作,包括视图的使用。视图在数据库设计中扮演着重要角色,允许开发者以简化的方式...

    使用Nutz[1.b.38]对数据库表的CRUD操作

    在本教程中,我们将深入探讨如何使用Nutz 1.b.38版本进行数据库表的CRUD操作。 首先,Nutz的核心组件Nutz DAO(Data Access Object)提供了与数据库交互的能力。通过简单的API,开发者可以轻松地实现对数据库的读写...

    nutz-1.b.52.zip

    如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置一个 nutz.jar 就够了 当然你要使用连接池,数据库驱动等功能,还需要自行添置 jar 包。 -------------Nutz 为谁而设计? 如果你觉得 Hibernate 控制比较繁琐,...

    nutz-1.r.62.zip

    1. **MVC模式**:Nutz提供了一个轻量级的MVC(Model-View-Controller)架构,帮助开发者将业务逻辑、数据模型和用户界面分离,提高代码可维护性。 2. **数据库支持**:Nutz内建了强大的ORM(Object-Relational ...

    nutz-1.r.60.jar

    nutz-1.r.60.jar

    Nutz-1.b.38

    同传统的 SSH 相比,它具备如下特点:轻 -- ...这就意味着:如果一个 Web 应用,你在 WEB-INF/lib 下只 需要放置一个 nutz.jar 就够了当然你要使用其它的连接池,数据库驱动,打印PDF支持等功能,还需要自行添置 jar 包

    nutz-1.b.43-jdk5.jar

    nutz-1.b.43-jdk5.jar 资源包

    nutz-1.r.61.r2.jar包

    标题中的"nutz-1.r.61.r2.jar"是一个特定版本的Nutz框架的Java库文件。Nutz是一个开源的Java框架,它旨在简化Web开发,提供一系列实用工具和强大的支持,使得开发者能够更高效地进行业务逻辑处理。这个版本号"1.r.61...

    nutz-1.b.48-manual.pdf 文档

    Nutz框架可以在WEB-INF/lib下仅使用一个nutz.jar来运行一个Web应用,前提是开发者自行添加必要的jar包,如连接池和数据库驱动等。对于那些希望尝试新东西、愿意成为NutzCommitters的开发者,Nutz提供了相应的指南和...

    nutz-1.b.43-jdk6.jar

    nutz-1.b.43-jdk5.jar 资源包

    nutz-1.r.61-发布包

    Nutz 是一个全面的Java开发框架,旨在提供高效、稳定且易于使用的工具和服务。"nutz-1.r.61-发布包"是Nutz框架的一个版本更新,具体为1.r.61版本。这个发布包包含了该版本的文档、源代码、编译后的类库以及相关的...

    nutz-1.b.49.r2.zip

    Nutz是对于Java程序员来说,除SSH之外的另一个选择。当然,它是开源的,并且是完全免费的。同时也是商业友好的(Licensed under the Apache License, Version 2.0)。

    nutz-1.r.62.jar

    nutz-1.r.62.jar 的jar包 可以解决中文乱码,设置字符编码等等

    nutz-1.r.58

    "nutz-1.r.58"是一个特定版本的Nutz框架发布包,包含了该框架的各种组件和文档,便于开发者在项目中使用和学习。 在提供的文件列表中,我们有以下内容: 1. `nutz-1.r.58-javadoc.jar`:这是Nutz框架的API文档,...

    nutz-1.b.49-manual.pdf

    - 如果开发中使用Hibernate觉得过于繁琐,或使用iBatis编写SQL感到不便,Nutz.Dao能提供专门设计的解决方案。 - 对于不习惯使用Spring或不愿意直接写XML配置的用户,Nutz.Ioc提供了简化配置的方案。 - 针对编写...

    nutz-1.r.65.zip

    nutzboot1.65版jar包...............................................................................................希望对你有用

    nutz-1.a.25_jdoc.zip

    2. **Nutz ORM**:Nutz ORM(对象关系映射)模块提供了对数据库操作的便捷支持,可以自动处理SQL语句的生成和执行,支持JDBC、MyBatis等多种数据访问层方案,让数据库操作变得更加简单。 3. **Nutz DAO**:DAO...

    nutz-1.r.57的JDK1.5编译

    在本案例中,我们关注的是"Nutz-1.r.57的JDK1.5编译",这表明我们需要了解如何在较低的JDK版本环境下,编译和使用Nutz框架。 首先,我们要知道Nutz官方推荐使用JDK1.6进行编译,这是因为JDK1.6引入了许多对开发者...

Global site tag (gtag.js) - Google Analytics