问题描述
如上两图,数据库中各个表之间有很多的外键关系,其中业务关系是一个用户下有该用户的订单,该订单中有多个订单条目,订单条目中是商品 。
@问题 如此的数据关系,如何在java开发中定义各种类 。要显示出商品信息,如何在商品信息中显示出外键关联的分类信息?
本文项目案例
@本文案例中,外键关系定义为类,比如把分类类作为商品类的一个属性 。 除此之外,在dao层中调用ToBookUtils建立商品和分类的关系,然后显示在前台页面中 。 具体代码请看源码
业务 | 操作 |
按用户查询订单,返回订单对象的集合 | 按用户查找订单,然后向订单中添加订单条目,在添加订单条目之前,建立订单条目与商品的联系 |
查询多个商品,返回多个商品对象的集合 | 查询所有商品,建立商品与分类之间的联系 |
查询一个商品,返回一个商品对象 | 查询指定商品,建立商品与分类之间的联系 |
@所用数据库 中 有一个用户,一个订单,这个订单中有两个订单条目,商品以书籍为例,有两本书,两个分类。
项目主要源码 及 源码下载
@主要源码
1 <h1><center>三个查询业务</center></h1> 2 <form action="<c:url value='/OrderServlet'/>" method="post"> 3 <input type="hidden" name="method" value="findByUid"> 4 业务一: 按用户名查询该用户订单,返回所有订单对象 的集合!测试用户id为"1"<br> 5 请输入用户名: <input type="text" name="uid" value="请输入用户id..测试数据库中只有1"/> 6 <input type="submit" value ="查询"> 7 </form> 8 <hr> 9 业务二: 查询多个商品,返回多个商品对象的集合!,每个商品中显示该商品分类的名字! <br> 10 <a href="<c:url value='/BookServlet?method=morefindAll'/>">点击查询</a> 11 <hr> 12 业务三: 查询一个商品,返回该商品对象!,商品中显示该商品分类的名字! 测试查询id为1的那本天龙八部的书<br> 13 <a href="<c:url value='/BookServlet?method=onefindByBid&bid=1'/>">点击查询</a>
1 <h1><center>全部书的信息,每本书显示分类</center></h1> 2 <table border="1"> 3 <c:forEach items="${bookList }" var="book"> 4 <tr> 5 <td>书名 :</td> 6 <td>${book.bname }</td> 7 </tr> 8 <tr> 9 <td>分类 :</td> 10 <td> 11 <c:forEach items="${categoryList }" var="category"> 12 <c:if test="${category.cid eq book.category.cid }"> 13 ${category.cname } 14 </c:if> 15 </c:forEach> 16 </td> 17 </tr> 18 </c:forEach> 19 </table>
1 <h1><center>一本书的详细,显示分类名称</center></h1> 2 <table border="1"> 3 <tr> 4 <td>书名:</td> 5 <td>${book.bname }</td> 6 </tr> 7 <tr> 8 <td>分类:</td> 9 <td> 10 <%-- 遍历所有分类,商品中的分类属性中的id是否 和 分类中的id一样 。 --%> 11 <c:forEach items="${categoryList }" var="category"> 12 <c:if test="${category.cid eq book.category.cid }"> 13 ${category.cname } 14 </c:if> 15 </c:forEach> 16 </td> 17 </tr> 18 </table>
1 <h1><center>显示该用户订单,包括订单中的所有条目</center></h1> 2 <table border="1"> 3 <c:forEach items="${orderList }" var="order"> 4 <tr> 5 <td>订单编号 :</td> 6 <td>${order.oid}</td> 7 </tr> 8 <tr> 9 <td>合计 :</td> 10 <td>${order.totalPrice }</td> 11 </tr> 12 <tr> 13 <td>订单中的物品 :</td> 14 <td> 15 <%-- 遍历该订单所有的订单条目--%> 16 <c:forEach items="${order.orderItemList }" var="orderItem"> 17 <%--遍历所有的商品,对比是否该订单条目中有哪个商品 --%> 18 <c:forEach items="${bookList }" var="book"> 19 <c:if test="${orderItem.book.bid eq book.bid }"> 20 <%--如果有这个商品,输出该商品名称--%> 21 ${book.bname }<br> 22 </c:if> 23 </c:forEach> 24 </c:forEach> 25 </td> 26 </tr> 27 </c:forEach> 28 </table>
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); } } }
1 package cn.kmust.bookstore.dao; 2 3 import java.sql.SQLException; 4 import java.util.List; 5 6 import org.apache.commons.dbutils.QueryRunner; 7 import org.apache.commons.dbutils.handlers.BeanListHandler; 8 9 import cn.itcast.jdbc.TxQueryRunner; 10 import cn.kmust.bookstore.domain.Category; 11 /** 12 * 分类 持久层 13 * @author ZHAOYUQIANG 14 * 15 */ 16 public class CategoryDao { 17 private QueryRunner qr = new TxQueryRunner(); 18 /** 19 * 查询所有分类 20 * @return 21 */ 22 public List<Category> findAll() { 23 try{ 24 String sql = "select * from tb_category"; 25 return qr.query(sql, new BeanListHandler<Category>(Category.class)); 26 }catch(SQLException e ){ 27 throw new RuntimeException (e); 28 } 29 30 } 31 32 }
1 package cn.kmust.bookstore.dao; 2 3 import java.sql.SQLException; 4 import java.util.List; 5 import java.util.Map; 6 7 import org.apache.commons.dbutils.QueryRunner; 8 import org.apache.commons.dbutils.handlers.BeanListHandler; 9 import org.apache.commons.dbutils.handlers.MapListHandler; 10 11 import cn.itcast.jdbc.TxQueryRunner; 12 import cn.kmust.bookstore.domain.Order; 13 import cn.kmust.bookstore.domain.OrderItem; 14 import cn.kmust.bookstore.utils.ToOrder; 15 /** 16 * 订单持久层 17 * @author ZHAOYUQIANG 18 * 19 */ 20 public class OrderDao { 21 private QueryRunner qr = new TxQueryRunner(); 22 private ToOrder toUtil = new ToOrder(); 23 /** 24 * 按用户id查询所有订单 25 * 订单中需要有订单条目 26 * @param username 27 * @return 28 */ 29 public List<Order> findByUid(String uid) { 30 try{ 31 String sql = "select * from tb_order where uid=?" ; 32 List<Order> orderList = qr.query(sql, 33 new BeanListHandler<Order>(Order.class),uid); 34 /* 35 * 遍历查找出来的每个Order,为每个order加载他的所有orderItem(订单条目) 36 */ 37 for(Order order : orderList){ 38 loadOrderItems(order); 39 } 40 return orderList ; 41 }catch(SQLException e){ 42 throw new RuntimeException(e); 43 } 44 } 45 /** 46 * 为指定的order对象加载它的所有条目 47 * @param order 48 */ 49 private void loadOrderItems(Order order) { 50 try{ 51 /* 52 * 需要查询book表和orderItem表,多表查询 53 */ 54 String sql = "select * from tb_orderItem i,tb_book b where i.bid=b.bid and oid=?"; 55 List<Map<String,Object>> mapList = qr.query(sql, 56 new MapListHandler(),order.getOid()); 57 /* 58 * 建立订单条目与book的关系,得到该订单的条目 59 */ 60 List<OrderItem> orderItemList = toUtil.toOrderItemList(mapList); 61 /* 62 * 订单加载所有条目 63 */ 64 order.setOrderItemList(orderItemList); 65 }catch(SQLException e){ 66 throw new RuntimeException(e); 67 } 68 } 69 70 }
1 package cn.kmust.bookstore.domain; 2 /** 3 * 商品 领域对象 属性名字与数据库字段名字一样 4 * @author ZHAOYUQIANG 5 * 6 */ 7 public class Book { 8 private String bid ; 9 private String bname ; 10 private double price ; 11 private Category category ; //关联cid 12 public String getBid() { 13 return bid; 14 } 15 public void setBid(String bid) { 16 this.bid = bid; 17 } 18 public String getBname() { 19 return bname; 20 } 21 public void setBname(String bname) { 22 this.bname = bname; 23 } 24 public double getPrice() { 25 return price; 26 } 27 public void setPrice(double price) { 28 this.price = price; 29 } 30 public Category getCategory() { 31 return category; 32 } 33 public void setCategory(Category category) { 34 this.category = category; 35 } 36 }
1 package cn.kmust.bookstore.domain; 2 /** 3 * 分类 领域对象 属性名字与数据库字段名字一样 4 * @author ZHAOYUQIANG 5 * 6 */ 7 public class Category { 8 private String cid ; 9 private String cname ; 10 public String getCid() { 11 return cid; 12 } 13 public void setCid(String cid) { 14 this.cid = cid; 15 } 16 public String getCname() { 17 return cname; 18 } 19 public void setCname(String cname) { 20 this.cname = cname; 21 } 22 }
1 package cn.kmust.bookstore.domain; 2 3 import java.util.List; 4 5 /** 6 * 订单 领域对象 属性名字与数据库字段名字一样 7 * @author ZHAOYUQIANG 8 * 9 */ 10 public class Order { 11 private String oid ; 12 private double totalPrice ; 13 private User user ;//关联用户 14 private List<OrderItem> orderItemList ;//单独设置的关联,因为订单中需要添加所有的条目 15 16 public List<OrderItem> getOrderItemList() { 17 return orderItemList; 18 } 19 public void setOrderItemList(List<OrderItem> orderItemList) { 20 this.orderItemList = orderItemList; 21 } 22 public String getOid() { 23 return oid; 24 } 25 public void setOid(String oid) { 26 this.oid = oid; 27 } 28 public double getTotalPrice() { 29 return totalPrice; 30 } 31 public void setTotalPrice(double totalPrice) { 32 this.totalPrice = totalPrice; 33 } 34 public User getUser() { 35 return user; 36 } 37 public void setUser(User user) { 38 this.user = user; 39 } 40 }
1 package cn.kmust.bookstore.domain; 2 /** 3 * 订单条目 领域对象 属性名字与数据库字段名字一样 4 * @author ZHAOYUQIANG 5 * 6 */ 7 public class OrderItem { 8 private String oiid ; 9 private int count ; 10 private double subtotal ; 11 private Order order ;//关联订单 12 private Book book ; //关联商品 13 public String getOiid() { 14 return oiid; 15 } 16 public void setOiid(String oiid) { 17 this.oiid = oiid; 18 } 19 public int getCount() { 20 return count; 21 } 22 public void setCount(int count) { 23 this.count = count; 24 } 25 public double getSubtotal() { 26 return subtotal; 27 } 28 public void setSubtotal(double subtotal) { 29 this.subtotal = subtotal; 30 } 31 public Order getOrder() { 32 return order; 33 } 34 public void setOrder(Order order) { 35 this.order = order; 36 } 37 public Book getBook() { 38 return book; 39 } 40 public void setBook(Book book) { 41 this.book = book; 42 } 43 }
1 package cn.kmust.bookstore.domain; 2 /** 3 * 订单 领域对象 属性名字与数据库字段名字一样 4 * @author ZHAOYUQIANG 5 * 6 */ 7 public class User { 8 private String uid ; 9 private String uname ; 10 public String getUid() { 11 return uid; 12 } 13 public void setUid(String uid) { 14 this.uid = uid; 15 } 16 public String getUname() { 17 return uname; 18 } 19 public void setUname(String uname) { 20 this.uname = uname; 21 } 22 23 24 }
1 package cn.kmust.bookstore.utils; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Map; 6 7 import cn.itcast.commons.CommonUtils; 8 import cn.kmust.bookstore.domain.Book; 9 import cn.kmust.bookstore.domain.Category; 10 /** 11 * 建立商品与分类之间的关系 12 * @author ZHAOYUQIANG 13 * 14 */ 15 public class ToBookUtils { 16 /** 17 * 把mapList中每个Map转换成Book对象,并且每个Book对象调用toBook方法建立与category的关系 18 * 返回集合 19 * @param mapList 20 * @return 21 */ 22 public List<Book> toBookList(List<Map<String,Object>> mapList){ 23 List<Book> bookList = new ArrayList<Book>(); 24 for(Map<String,Object> map : mapList){ 25 Book b = toBook(map); 26 bookList.add(b); 27 } 28 return bookList ; 29 } 30 /** 31 * 把一个map转换成两个对象(book和category),并且建立两个对象之间的关系(把category合并在Book中) 32 * 返回一个对象 33 * @param map 34 * @return 35 */ 36 public Book toBook(Map<String,Object> map){ 37 Category category = CommonUtils.toBean(map, Category.class); 38 Book book = CommonUtils.toBean(map, Book.class); 39 book.setCategory(category); 40 return book ; 41 } 42 43 }
1 package cn.kmust.bookstore.utils; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 import java.util.Map; 6 7 import cn.itcast.commons.CommonUtils; 8 import cn.kmust.bookstore.domain.Book; 9 import cn.kmust.bookstore.domain.OrderItem; 10 11 /** 12 * 建立订单条目(OrderItem)和商品(Book)之间的关系 13 * @author ZHAOYUQIANG 14 * 15 */ 16 public class ToOrder { 17 /** 18 * 把mapList中每个Map转换成OrderItem对象,并且每个OrderItem对象调用toOrderItem方法建立与book的关系 19 * @param mapList 20 * @return 21 */ 22 public List<OrderItem> toOrderItemList(List<Map<String,Object>> mapList){ 23 List<OrderItem> orderItemList = new ArrayList<OrderItem>(); 24 for(Map<String,Object> map : mapList){ 25 OrderItem item = toOrderItem(map); 26 orderItemList.add(item); 27 } 28 return orderItemList; 29 } 30 /** 31 * 把一个map转换成两个对象(OrderItem和book),并且建立两个对象之间的关系(把book合并在OrderItem中) 32 * @param map 33 * @return 34 */ 35 public OrderItem toOrderItem(Map<String,Object> map){ 36 OrderItem orderItem = CommonUtils.toBean(map, OrderItem.class); 37 Book book = CommonUtils.toBean(map, Book.class); 38 orderItem.setBook(book); 39 return orderItem ; 40 } 41 }
1 package cn.kmust.bookstore.web.servlet; 2 3 import java.io.IOException; 4 import java.util.List; 5 6 import javax.servlet.ServletException; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletResponse; 9 10 import cn.itcast.servlet.BaseServlet; 11 import cn.kmust.bookstore.domain.Book; 12 import cn.kmust.bookstore.service.BookService; 13 import cn.kmust.bookstore.service.CategoryService; 14 /** 15 * BookServlet表述层 16 * @author ZHAOYUQIANG 17 * 18 */ 19 public class BookServlet extends BaseServlet { 20 private BookService bookService = new BookService(); 21 private CategoryService categoryService = new CategoryService(); 22 /** 23 * 查询一本图书信息 24 * @param request 25 * @param response 26 * @return 27 * @throws ServletException 28 * @throws IOException 29 */ 30 public String onefindByBid(HttpServletRequest request, HttpServletResponse response) 31 throws ServletException, IOException { 32 Book book = bookService.findByBid(request.getParameter("bid")); 33 request.setAttribute("book", book); 34 request.setAttribute("categoryList", categoryService.findAll()); 35 return "f:/list_onebook.jsp" ; 36 } 37 /** 38 * 查询多本图书 39 * @param request 40 * @param response 41 * @return 42 * @throws ServletException 43 * @throws IOException 44 */ 45 public String morefindAll(HttpServletRequest request, HttpServletResponse response) 46 throws ServletException, IOException { 47 List<Book> bookList = bookService.findAll(); 48 request.setAttribute("bookList", bookList); 49 request.setAttribute("categoryList",categoryService.findAll() ); 50 return "f:/list_morebook.jsp" ; 51 } 52 53 }
1 package cn.kmust.bookstore.web.servlet; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import cn.itcast.servlet.BaseServlet; 10 import cn.kmust.bookstore.service.BookService; 11 import cn.kmust.bookstore.service.OrderService; 12 /** 13 * Order表述层 14 * @author ZHAOYUQIANG 15 * 16 */ 17 public class OrderServlet extends BaseServlet { 18 private OrderService orderService = new OrderService(); 19 private BookService bookService = new BookService(); 20 /** 21 * 按用户查询所有订单 22 * @param request 23 * @param response 24 * @return 25 * @throws ServletException 26 * @throws IOException 27 */ 28 public String findByUid(HttpServletRequest request, HttpServletResponse response) 29 throws ServletException, IOException { 30 String uid = request.getParameter("uid"); 31 request.setAttribute("orderList", orderService.findByUid(uid)); 32 request.setAttribute("bookList", bookService.findAll()); 33 return "f:/list_order.jsp" ; 34 } 35 36 }
1 <?xml version="1.0" encoding="UTF-8"?> 2 <c3p0-config> 3 <default-config> 4 <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_bookstore</property> 5 <property name="driverClass">com.mysql.jdbc.Driver</property> 6 <property name="user">root</property> 7 <property name="password">123456</property> 8 <property name="acquireIncrement">3</property> 9 <property name="initialPoolSize">5</property> 10 <property name="minPoolSize">2</property> 11 <property name="maxPoolSize">8</property> 12 </default-config> 13 </c3p0-config>
@数据库源码
1 /*用户表*/ 2 CREATE TABLE tb_user( 3 uid CHAR(32) PRIMARY KEY, 4 uname VARCHAR(100) NOT NULL 5 ); 6 INSERT INTO tb_user(uid,uname) VALUES ('1','张三'); 7 /*分类表*/ 8 CREATE TABLE tb_category( 9 cid CHAR(32) PRIMARY KEY, 10 cname VARCHAR(100) NOT NULL 11 ); 12 INSERT INTO tb_category(cid,cname) VALUES ('1','武侠'); 13 INSERT INTO tb_category(cid,cname) VALUES ('2','言情'); 14 /*商品图书表*/ 15 CREATE TABLE tb_book( 16 bid CHAR(32) PRIMARY KEY, 17 bname VARCHAR(100) NOT NULL , 18 price DECIMAL(5,1) NOT NULL , 19 cid CHAR(32), /*书籍所属分类*/ 20 FOREIGN KEY(cid) REFERENCES tb_category(cid) /*建立外键关系*/ 21 ); 22 INSERT INTO tb_book VALUES ('1','天龙八部','68.5','1'); 23 INSERT INTO tb_book VALUES ('2','霸道总裁爱上我','39.9','2'); 24 /*订单表*/ 25 CREATE TABLE tb_order( 26 oid CHAR(32) PRIMARY KEY, 27 totalPrice DECIMAL(10,0), /*订单合计*/ 28 uid CHAR(32) , /*订单主人*/ 29 FOREIGN KEY(uid) REFERENCES tb_user(uid) /*建立外键关系*/ 30 ); 31 INSERT INTO tb_order VALUES ('1','176.9','1'); 32 33 /*订单条目*/ 34 CREATE TABLE tb_orderItem( 35 oiid CHAR(32) PRIMARY KEY , 36 `count` INT ,/*商品数量*/ 37 subtotal DECIMAL(10,0),/*小计*/ 38 oid CHAR(32),/*所属订单*/ 39 bid CHAR(32),/*条目中的商品*/ 40 FOREIGN KEY(oid) REFERENCES tb_order(oid), 41 FOREIGN KEY(bid) REFERENCES tb_book(bid) 42 ); 43 INSERT INTO tb_orderItem VALUES ('1','2','137.0','1','1'); 44 INSERT INTO tb_orderItem VALUES ('2','1','39.9','1','2'); 45 46 SELECT * FROM tb_user; 47 SELECT * FROM tb_category; 48 SELECT * FROM tb_book; 49 SELECT * FROM tb_order; 50 SELECT * FROM tb_orderItem;