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



    问题描述

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

    @问题 如此的数据关系,如何在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>
    index.jsp
     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>
    list_morebook.jsp
     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>
    list_onebook.jsp
     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>
    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
     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 }
    CategoryDao
     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 }
    OrderDao
     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 }
    Book
     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 }
    Category
     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 }
    Order
     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 }
    OrderItem
     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 }
    User
     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 }
    ToBookUtils
     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 }
    ToOrder
     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 }
    BookServlet
     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 }
    OrderServlet
     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>
    c3p0-config.xml

    @数据库源码

     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;
    bookstore

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

  • 相关阅读:
    数据库设计
    最近发生的事
    轻松搞定面试中的二叉树题目
    二叉树的遍历方法
    静态库Lib和动态库Dll
    深入理解C/C++数组和指针
    夜间日记
    typedef用法小结
    什么是静态链接库,什么是动态链接库
    线段树
  • 原文地址:https://www.cnblogs.com/zyuqiang/p/7425205.html
Copyright © 2020-2023  润新知