《JavaWeb从入门到改行》多重外键关系在java中的处理方案

时间:2022-01-02 15:01:36




问题描述

《JavaWeb从入门到改行》多重外键关系在java中的处理方案

《JavaWeb从入门到改行》多重外键关系在java中的处理方案

如上两图,数据库中各个表之间有很多的外键关系,其中业务关系是一个用户下有该用户的订单,该订单中有多个订单条目,订单条目中是商品 。

@问题 如此的数据关系,如何在java开发中定义各种类 。要显示出商品信息,如何在商品信息中显示出外键关联的分类信息?

本文项目案例

@本文案例中,外键关系定义为类,比如把分类类作为商品类的一个属性 。 除此之外,在dao层中调用ToBookUtils建立商品和分类的关系,然后显示在前台页面中 。 具体代码请看源码

@业务

业务 操作
按用户查询订单,返回订单对象的集合 按用户查找订单,然后向订单中添加订单条目,在添加订单条目之前,建立订单条目与商品的联系
查询多个商品,返回多个商品对象的集合 查询所有商品,建立商品与分类之间的联系
查询一个商品,返回一个商品对象 查询指定商品,建立商品与分类之间的联系

@所用数据库 中 有一个用户,一个订单,这个订单中有两个订单条目,商品以书籍为例,有两本书,两个分类。

项目主要源码 及 源码下载

@主要源码

 <h1><center>三个查询业务</center></h1>
<form action="<c:url value='/OrderServlet'/>" method="post">
<input type="hidden" name="method" value="findByUid">
业务一: 按用户名查询该用户订单,返回所有订单对象 的集合!测试用户id为"1"<br>
请输入用户名: <input type="text" name="uid" value="请输入用户id..测试数据库中只有1"/>
<input type="submit" value ="查询">
</form>
<hr>
业务二: 查询多个商品,返回多个商品对象的集合!,每个商品中显示该商品分类的名字! <br>
<a href="<c:url value='/BookServlet?method=morefindAll'/>">点击查询</a>
<hr>
业务三: 查询一个商品,返回该商品对象!,商品中显示该商品分类的名字! 测试查询id为1的那本天龙八部的书<br>
<a href="<c:url value='/BookServlet?method=onefindByBid&bid=1'/>">点击查询</a>

index.jsp

  <h1><center>全部书的信息,每本书显示分类</center></h1>
<table border="1">
<c:forEach items="${bookList }" var="book">
<tr>
<td>书名 :</td>
<td>${book.bname }</td>
</tr>
<tr>
<td>分类 :</td>
<td>
<c:forEach items="${categoryList }" var="category">
<c:if test="${category.cid eq book.category.cid }">
${category.cname }
</c:if>
</c:forEach>
</td>
</tr>
</c:forEach>
</table>

list_morebook.jsp

 <h1><center>一本书的详细,显示分类名称</center></h1>
<table border="1">
<tr>
<td>书名:</td>
<td>${book.bname }</td>
</tr>
<tr>
<td>分类:</td>
<td>
<%-- 遍历所有分类,商品中的分类属性中的id是否 和 分类中的id一样 。 --%>
<c:forEach items="${categoryList }" var="category">
<c:if test="${category.cid eq book.category.cid }">
${category.cname }
</c:if>
</c:forEach>
</td>
</tr>
</table>

list_onebook.jsp

 <h1><center>显示该用户订单,包括订单中的所有条目</center></h1>
<table border="1">
<c:forEach items="${orderList }" var="order">
<tr>
<td>订单编号 :</td>
<td>${order.oid}</td>
</tr>
<tr>
<td>合计 :</td>
<td>${order.totalPrice }</td>
</tr>
<tr>
<td>订单中的物品 :</td>
<td>
<%-- 遍历该订单所有的订单条目--%>
<c:forEach items="${order.orderItemList }" var="orderItem">
<%--遍历所有的商品,对比是否该订单条目中有哪个商品 --%>
<c:forEach items="${bookList }" var="book">
<c:if test="${orderItem.book.bid eq book.bid }">
<%--如果有这个商品,输出该商品名称--%>
${book.bname }<br>
</c:if>
</c:forEach>
</c:forEach>
</td>
</tr>
</c:forEach>
</table>

list_order.jsp

package cn.kmust.bookstore.dao;

import java.sql.SQLException;
import java.util.List;
import java.util.Map; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.MapHandler;
import org.apache.commons.dbutils.handlers.MapListHandler; import cn.itcast.commons.CommonUtils;
import cn.itcast.jdbc.TxQueryRunner;
import cn.kmust.bookstore.domain.Book;
import cn.kmust.bookstore.domain.Category;
import cn.kmust.bookstore.utils.ToBookUtils;
/**
* 商品 持久层
* @author ZHAOYUQIANG
*
*/
public class BookDao {
private QueryRunner qr = new TxQueryRunner();
private ToBookUtils tbUtil = new ToBookUtils();
/**
* 查询一本书
* @param bid
* @return
*/
public Book findByBid(String bid) {
try{
/*
*
* 在Book对象中保存Category信息,即: 在书中添加所属分类
* 要给Map映射成两个对象,再给这两个对象建立关系
*/
String sql = "select * from tb_book where bid=?";
Map<String,Object> map = qr.query(sql, new MapHandler(),bid);
return tbUtil.toBook(map);
}catch(SQLException e){
throw new RuntimeException(e);
}
}
/**
* 查询所有图书
* @return
*/
public List<Book> findAll() {
try{
String sql = "select * from tb_book";
List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler());
return tbUtil.toBookList(mapList);
}catch(SQLException e){
throw new RuntimeException(e);
}
}
}

BookDao

 package cn.kmust.bookstore.dao;

 import java.sql.SQLException;
import java.util.List; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler; import cn.itcast.jdbc.TxQueryRunner;
import cn.kmust.bookstore.domain.Category;
/**
* 分类 持久层
* @author ZHAOYUQIANG
*
*/
public class CategoryDao {
private QueryRunner qr = new TxQueryRunner();
/**
* 查询所有分类
* @return
*/
public List<Category> findAll() {
try{
String sql = "select * from tb_category";
return qr.query(sql, new BeanListHandler<Category>(Category.class));
}catch(SQLException e ){
throw new RuntimeException (e);
} } }

CategoryDao

 package cn.kmust.bookstore.dao;

 import java.sql.SQLException;
import java.util.List;
import java.util.Map; import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler; import cn.itcast.jdbc.TxQueryRunner;
import cn.kmust.bookstore.domain.Order;
import cn.kmust.bookstore.domain.OrderItem;
import cn.kmust.bookstore.utils.ToOrder;
/**
* 订单持久层
* @author ZHAOYUQIANG
*
*/
public class OrderDao {
private QueryRunner qr = new TxQueryRunner();
private ToOrder toUtil = new ToOrder();
/**
* 按用户id查询所有订单
* 订单中需要有订单条目
* @param username
* @return
*/
public List<Order> findByUid(String uid) {
try{
String sql = "select * from tb_order where uid=?" ;
List<Order> orderList = qr.query(sql,
new BeanListHandler<Order>(Order.class),uid);
/*
* 遍历查找出来的每个Order,为每个order加载他的所有orderItem(订单条目)
*/
for(Order order : orderList){
loadOrderItems(order);
}
return orderList ;
}catch(SQLException e){
throw new RuntimeException(e);
}
}
/**
* 为指定的order对象加载它的所有条目
* @param order
*/
private void loadOrderItems(Order order) {
try{
/*
* 需要查询book表和orderItem表,多表查询
*/
String sql = "select * from tb_orderItem i,tb_book b where i.bid=b.bid and oid=?";
List<Map<String,Object>> mapList = qr.query(sql,
new MapListHandler(),order.getOid());
/*
* 建立订单条目与book的关系,得到该订单的条目
*/
List<OrderItem> orderItemList = toUtil.toOrderItemList(mapList);
/*
* 订单加载所有条目
*/
order.setOrderItemList(orderItemList);
}catch(SQLException e){
throw new RuntimeException(e);
}
} }

OrderDao

 package cn.kmust.bookstore.domain;
/**
* 商品 领域对象 属性名字与数据库字段名字一样
* @author ZHAOYUQIANG
*
*/
public class Book {
private String bid ;
private String bname ;
private double price ;
private Category category ; //关联cid
public String getBid() {
return bid;
}
public void setBid(String bid) {
this.bid = bid;
}
public String getBname() {
return bname;
}
public void setBname(String bname) {
this.bname = bname;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Category getCategory() {
return category;
}
public void setCategory(Category category) {
this.category = category;
}
}

Book

 package cn.kmust.bookstore.domain;
/**
* 分类 领域对象 属性名字与数据库字段名字一样
* @author ZHAOYUQIANG
*
*/
public class Category {
private String cid ;
private String cname ;
public String getCid() {
return cid;
}
public void setCid(String cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
}

Category

 package cn.kmust.bookstore.domain;

 import java.util.List;

 /**
* 订单 领域对象 属性名字与数据库字段名字一样
* @author ZHAOYUQIANG
*
*/
public class Order {
private String oid ;
private double totalPrice ;
private User user ;//关联用户
private List<OrderItem> orderItemList ;//单独设置的关联,因为订单中需要添加所有的条目 public List<OrderItem> getOrderItemList() {
return orderItemList;
}
public void setOrderItemList(List<OrderItem> orderItemList) {
this.orderItemList = orderItemList;
}
public String getOid() {
return oid;
}
public void setOid(String oid) {
this.oid = oid;
}
public double getTotalPrice() {
return totalPrice;
}
public void setTotalPrice(double totalPrice) {
this.totalPrice = totalPrice;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

Order

 package cn.kmust.bookstore.domain;
/**
* 订单条目 领域对象 属性名字与数据库字段名字一样
* @author ZHAOYUQIANG
*
*/
public class OrderItem {
private String oiid ;
private int count ;
private double subtotal ;
private Order order ;//关联订单
private Book book ; //关联商品
public String getOiid() {
return oiid;
}
public void setOiid(String oiid) {
this.oiid = oiid;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
public double getSubtotal() {
return subtotal;
}
public void setSubtotal(double subtotal) {
this.subtotal = subtotal;
}
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
public Book getBook() {
return book;
}
public void setBook(Book book) {
this.book = book;
}
}

OrderItem

 package cn.kmust.bookstore.domain;
/**
* 订单 领域对象 属性名字与数据库字段名字一样
* @author ZHAOYUQIANG
*
*/
public class User {
private String uid ;
private String uname ;
public String getUid() {
return uid;
}
public void setUid(String uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
} }

User

 package cn.kmust.bookstore.utils;

 import java.util.ArrayList;
import java.util.List;
import java.util.Map; import cn.itcast.commons.CommonUtils;
import cn.kmust.bookstore.domain.Book;
import cn.kmust.bookstore.domain.Category;
/**
* 建立商品与分类之间的关系
* @author ZHAOYUQIANG
*
*/
public class ToBookUtils {
/**
* 把mapList中每个Map转换成Book对象,并且每个Book对象调用toBook方法建立与category的关系
* 返回集合
* @param mapList
* @return
*/
public List<Book> toBookList(List<Map<String,Object>> mapList){
List<Book> bookList = new ArrayList<Book>();
for(Map<String,Object> map : mapList){
Book b = toBook(map);
bookList.add(b);
}
return bookList ;
}
/**
* 把一个map转换成两个对象(book和category),并且建立两个对象之间的关系(把category合并在Book中)
* 返回一个对象
* @param map
* @return
*/
public Book toBook(Map<String,Object> map){
Category category = CommonUtils.toBean(map, Category.class);
Book book = CommonUtils.toBean(map, Book.class);
book.setCategory(category);
return book ;
} }

ToBookUtils

 package cn.kmust.bookstore.utils;

 import java.util.ArrayList;
import java.util.List;
import java.util.Map; import cn.itcast.commons.CommonUtils;
import cn.kmust.bookstore.domain.Book;
import cn.kmust.bookstore.domain.OrderItem; /**
* 建立订单条目(OrderItem)和商品(Book)之间的关系
* @author ZHAOYUQIANG
*
*/
public class ToOrder {
/**
* 把mapList中每个Map转换成OrderItem对象,并且每个OrderItem对象调用toOrderItem方法建立与book的关系
* @param mapList
* @return
*/
public List<OrderItem> toOrderItemList(List<Map<String,Object>> mapList){
List<OrderItem> orderItemList = new ArrayList<OrderItem>();
for(Map<String,Object> map : mapList){
OrderItem item = toOrderItem(map);
orderItemList.add(item);
}
return orderItemList;
}
/**
* 把一个map转换成两个对象(OrderItem和book),并且建立两个对象之间的关系(把book合并在OrderItem中)
* @param map
* @return
*/
public OrderItem toOrderItem(Map<String,Object> map){
OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class);
Book book = CommonUtils.toBean(map, Book.class);
orderItem.setBook(book);
return orderItem ;
}
}

ToOrder

 package cn.kmust.bookstore.web.servlet;

 import java.io.IOException;
import java.util.List; import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.itcast.servlet.BaseServlet;
import cn.kmust.bookstore.domain.Book;
import cn.kmust.bookstore.service.BookService;
import cn.kmust.bookstore.service.CategoryService;
/**
* BookServlet表述层
* @author ZHAOYUQIANG
*
*/
public class BookServlet extends BaseServlet {
private BookService bookService = new BookService();
private CategoryService categoryService = new CategoryService();
/**
* 查询一本图书信息
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String onefindByBid(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Book book = bookService.findByBid(request.getParameter("bid"));
request.setAttribute("book", book);
request.setAttribute("categoryList", categoryService.findAll());
return "f:/list_onebook.jsp" ;
}
/**
* 查询多本图书
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String morefindAll(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
List<Book> bookList = bookService.findAll();
request.setAttribute("bookList", bookList);
request.setAttribute("categoryList",categoryService.findAll() );
return "f:/list_morebook.jsp" ;
} }

BookServlet

 package cn.kmust.bookstore.web.servlet;

 import java.io.IOException;

 import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import cn.itcast.servlet.BaseServlet;
import cn.kmust.bookstore.service.BookService;
import cn.kmust.bookstore.service.OrderService;
/**
* Order表述层
* @author ZHAOYUQIANG
*
*/
public class OrderServlet extends BaseServlet {
private OrderService orderService = new OrderService();
private BookService bookService = new BookService();
/**
* 按用户查询所有订单
* @param request
* @param response
* @return
* @throws ServletException
* @throws IOException
*/
public String findByUid(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String uid = request.getParameter("uid");
request.setAttribute("orderList", orderService.findByUid(uid));
request.setAttribute("bookList", bookService.findAll());
return "f:/list_order.jsp" ;
} }

OrderServlet

 <?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db_bookstore</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="acquireIncrement">3</property>
<property name="initialPoolSize">5</property>
<property name="minPoolSize">2</property>
<property name="maxPoolSize">8</property>
</default-config>
</c3p0-config>

c3p0-config.xml

@数据库源码

 /*用户表*/
CREATE TABLE tb_user(
uid CHAR(32) PRIMARY KEY,
uname VARCHAR(100) NOT NULL
);
INSERT INTO tb_user(uid,uname) VALUES ('','张三');
/*分类表*/
CREATE TABLE tb_category(
cid CHAR(32) PRIMARY KEY,
cname VARCHAR(100) NOT NULL
);
INSERT INTO tb_category(cid,cname) VALUES ('','武侠');
INSERT INTO tb_category(cid,cname) VALUES ('','言情');
/*商品图书表*/
CREATE TABLE tb_book(
bid CHAR(32) PRIMARY KEY,
bname VARCHAR(100) NOT NULL ,
price DECIMAL(5,1) NOT NULL ,
cid CHAR(32), /*书籍所属分类*/
FOREIGN KEY(cid) REFERENCES tb_category(cid) /*建立外键关系*/
);
INSERT INTO tb_book VALUES ('','天龙八部','68.5','');
INSERT INTO tb_book VALUES ('','霸道总裁爱上我','39.9','');
/*订单表*/
CREATE TABLE tb_order(
oid CHAR(32) PRIMARY KEY,
totalPrice DECIMAL(10,0), /*订单合计*/
uid CHAR(32) , /*订单主人*/
FOREIGN KEY(uid) REFERENCES tb_user(uid) /*建立外键关系*/
);
INSERT INTO tb_order VALUES ('','176.9',''); /*订单条目*/
CREATE TABLE tb_orderItem(
oiid CHAR(32) PRIMARY KEY ,
`count` INT ,/*商品数量*/
subtotal DECIMAL(10,0),/*小计*/
oid CHAR(32),/*所属订单*/
bid CHAR(32),/*条目中的商品*/
FOREIGN KEY(oid) REFERENCES tb_order(oid),
FOREIGN KEY(bid) REFERENCES tb_book(bid)
);
INSERT INTO tb_orderItem VALUES ('','','137.0','','');
INSERT INTO tb_orderItem VALUES ('','','39.9','',''); SELECT * FROM tb_user;
SELECT * FROM tb_category;
SELECT * FROM tb_book;
SELECT * FROM tb_order;
SELECT * FROM tb_orderItem;

bookstore

@下载 https://files.cnblogs.com/files/zyuqiang/bookstore.rar