综合 案例

商城案例表设计

通过对商城项目的部分表关系进行分析,完成数据库表的设计

表关系分析

在这里插入图片描述

建库 建表

创建名为store的数据库,对应商城项目

-- 用户表
create table user(
   uid VARCHAR(32) PRIMARY KEY, -- 用户id
	 username VARCHAR(20), -- 用户名
	 password VARCHAR(20),  -- 密码
	 telephone VARCHAR(20),  -- 电话
	 birthday DATE ,   -- 生日
	 sex VARCHAR(10) -- 性别
	 );
	 
insert into user
values
('001','渣渣辉','123456','13511112222','2015-11-04','男'),
('002','药水哥','123456','13533334444','1990-02-01','男'),
('003','大明白','123456','13544445555','2015-11-03','男'),
('004','长海','123456','13566667777','2000-02-01','男'),
('005','乔杉','123456','13588889999','2000-02-01','男');
-- 订单表
CREATE TABLE orders (
  oid varchar(32)   PRIMARY KEY, -- 订单id
  ordertime datetime ,	-- 下单时间 
  total double , -- 总金额
  name varchar(20), -- 收货人姓名
  telephone varchar(20) , -- 电话
  address varchar(30) , -- 地址
  state int(11) ,  -- 订单状态
  uid varchar(32), -- 外键字段 对应用户表id
  CONSTRAINT ofk_0001 FOREIGN KEY (uid) REFERENCES user (uid)
);

-- 插入一条订单数据
INSERT INTO orders 
VALUES('order001','2019-10-11',5500,'乔杉','15512342345','皇家洗浴',0,'001');
-- 商品分类表
CREATE TABLE category (
  cid varchar(32) PRIMARY KEY,
  cname varchar(20)
); 

INSERT INTO category
VALUES ('1','手机数码'),
('2','电脑办公'),
('3','运动鞋服'),
('4','图书音像');
-- 商品表
CREATE TABLE product (
  pid varchar(32)  PRIMARY KEY,	-- 商品id
  pname varchar(50) , -- 商品名称 
  price double, -- 商品价格
  pdesc varchar(255), -- 商品描述
  pflag int(11) , -- 商品状态 1 上架 ,0 下架
  cid varchar(32) , -- 外键对应 分类表id
  KEY sfk_0001 (cid), 
  CONSTRAINT sfk_0001 FOREIGN KEY (cid) REFERENCES category (cid)
);

INSERT INTO product 
VALUES 
('1','小米6',2200,'小米 移动联通电信4G手机 双卡双待',0,'1'),
('2','华为Mate9',2599,'华为 双卡双待 高清大屏',0,'1'),
('3','OPPO11',3000,'移动联通 双4G手机',0,'1'),
('4','华为荣耀',1499,'3GB内存标准版 黑色 移动4G手机',0,'1'),
('5','华硕台式电脑',5000,'爆款直降,满千减百',0,'2'),
('6','MacBook',6688,'128GB 闪存',0,'2'),
('7','ThinkPad',4199,'轻薄系列1)',0,'2'),
('8','联想小新',4499,'14英寸超薄笔记本电脑',0,'2'),
('9','李宁音速6',500,'实战篮球鞋',0,'3'),
('10','AJ11',3300,'乔丹实战系列',0,'3'),
('11','AJ1',5800,'精神小伙系列',0,'3');
-- 订单项表
CREATE TABLE orderitem (
  itemid VARCHAR(32) PRIMARY KEY, -- 订单项ID
  pid VARCHAR(32),  -- 外键 对应商品表 id
  oid VARCHAR(32), -- 外键 对应订单表 id
  KEY fk_0001 (pid),
  KEY fk_0002 (oid),
  CONSTRAINT fk_0001 FOREIGN KEY (pid) REFERENCES product (pid),
  CONSTRAINT fk_0002 FOREIGN KEY (oid) REFERENCES orders (oid)
);

-- 向中间表中插入两条数据
INSERT INTO orderitem VALUES('item001','1','order001');
INSERT INTO orderitem VALUES('item002','11','order001');

表与表之间的关系

在这里插入图片描述

环境搭建

项目结构

com.app 测试包 用于对DAO代码进行测试
com.dao dao包 数据访问层,包含所有对数据库的相关操作的类
com.entity 实体包 保存根据数据库表 对应创建的JavaBean类
com.utils 工具包
在这里插入图片描述

导入所需jar包

我们只需要导入myjar仓库到项目中就可以了

JavaBean类创建

设计用户与订单

一对多关系分析

  • 在Java一对多的数据关系中,需要遵循一下设计原则:
    1.Java类的名称 = 实体表的名称
    2.Java类的属性 = 实体表的字段
    3.Java类的一个对象 = 表的一行记录
    4.外键关系 = 引用配置
  • 一个用户拥有多个订单, 所以用户是一的一方,订单是多的一方
    在这里插入图片描述

Orders类设计分析

  • 第一种方式
    根据两张表的关系描述 我们可以在订单类中 添加一个UID 成员变量,表示订单属于哪个用户
    private String uid;
    
    但这样设计会存在一些问题,比如我要查询的是订单属于哪个用户的用户名,但是我们只有一个uid
  • 第二种方式
    Java类表示一对多关系,可以在多的一方添加一个成员变量,这个成员变量的类型 就是一的一方的类型
    再在订单表中添加一个User对象,User对象中,保存该订单关联的用户的所有信息
private String uid;
private User user;

设计商品与分类

分类与商品 同样是一对多关系,我们可以在多的一方进行操作 添加一个成员变量 类型时一的一方的类型
在这里插入图片描述

User类

package com.entity;


import java.util.Date;

/**
 * user表
 *  uid VARCHAR(32) PRIMARY KEY, -- 用户id
 * 	 username VARCHAR(20), -- 用户名
 * 	 password VARCHAR(20),  -- 密码
 * 	 telephone VARCHAR(20),  -- 电话
 * 	 birthday DATE ,   -- 生日
 * 	 sex VARCHAR(10) -- 性别
 */
public class User {

    private String uid ;
    private String username;
    private String password ;
    private String telephone ;
    private String birthday ;
    private String sex ;

    public User() {
    }

    public User(String uid, String username, String password, String telephone, String birthday, String sex) {
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.telephone = telephone;
        this.birthday = birthday;
        this.sex = sex;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getBirthday() {

        return birthday;
    }

    public void setBirthday(String birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid='" + uid + '\'' +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", telephone='" + telephone + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                '}';
    }
}


Orders类

package com.entity;


/**
 *
 * 订单表Orders
 * oid varchar(32)   PRIMARY KEY, -- 订单id
 *   ordertime datetime ,	-- 下单时间
 *   total double , -- 总金额
 *   name varchar(20), -- 收货人姓名
 *   telephone varchar(20) , -- 电话
 *   address varchar(30) , -- 地址
 *   state int(11) ,  -- 订单状态
 *   uid varchar(32), -- 外键字段 对应用户表id
 */
public class Orders {

    private String oid ;
    private String ordertime ;
    private double total ;
    private  String name ;
    private  String telephone ;
    private String address ;
    private int state ;
    private String uid ;
    private User user;

    public Orders() {
    }

    public Orders(String oid, String ordertime, double total, String name, String telephone, String address, int state, String uid, User user) {
        this.oid = oid;
        this.ordertime = ordertime;
        this.total = total;
        this.name = name;
        this.telephone = telephone;
        this.address = address;
        this.state = state;
        this.uid = uid;
        this.user = user;
    }

    public String getOid() {
        return oid;
    }

    public void setOid(String oid) {
        this.oid = oid;
    }

    public String getOrdertime() {
        return ordertime;
    }

    public void setOrdertime(String ordertime) {
        this.ordertime = ordertime;
    }

    public double getTotal() {
        return total;
    }

    public void setTotal(double total) {
        this.total = total;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getState() {
        return state;
    }

    public void setState(int state) {
        this.state = state;
    }

    public String getUid() {
        return uid;
    }

    public void setUid(String uid) {
        this.uid = uid;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Orders{" +
                "oid='" + oid + '\'' +
                ", ordertime='" + ordertime + '\'' +
                ", total=" + total +
                ", name='" + name + '\'' +
                ", telephone='" + telephone + '\'' +
                ", address='" + address + '\'' +
                ", state=" + state +
                ", uid='" + uid + '\'' +
                '}';
    }
}

Category类

package com.entity;

/**
 * 分类表对应的JavaBean
 *cid varchar(32) PRIMARY KEY,
 *   cname varchar(20)
 */
public class Category {

    private String cid ;
    private String cname ;

    public Category() {
    }

    public Category(String cid, String cname) {
        this.cid = cid;
        this.cname = 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;
    }

    @Override
    public String toString() {
        return "Category{" +
                "cid='" + cid + '\'' +
                ", cname='" + cname + '\'' +
                '}';
    }
}

Product类

package com.entity;

/**
 *  product表
 *  pid varchar(32)  PRIMARY KEY,	-- 商品id
 *   pname varchar(50) , -- 商品名称
 *   price double, -- 商品价格
 *   pdesc varchar(255), -- 商品描述
 *   pflag int(11) , -- 商品状态 1 上架 ,0 下架
 *   cid varchar(32) , -- 外键对应 分类表id
 */
public class Product {

    private String pid ;
    private String pname ;
    private double price ;
    private String pdesc ;
    private int pflag ;
    private String cid ;
    private Category category ;

    public Product() {
    }

    public Product(String pid, String pname, double price, String pdesc, int pflag, String cid, Category category) {
        this.pid = pid;
        this.pname = pname;
        this.price = price;
        this.pdesc = pdesc;
        this.pflag = pflag;
        this.cid = cid;
        this.category = category;
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getPdesc() {
        return pdesc;
    }

    public void setPdesc(String pdesc) {
        this.pdesc = pdesc;
    }

    public int getPflag() {
        return pflag;
    }

    public void setPflag(int pflag) {
        this.pflag = pflag;
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    @Override
    public String toString() {
        return "Product{" +
                "pid='" + pid + '\'' +
                ", pname='" + pname + '\'' +
                ", price=" + price +
                ", pdesc='" + pdesc + '\'' +
                ", pflag=" + pflag +
                ", cid='" + cid + '\'' +
                ", category=" + category +
                '}';
    }



}

设计订单项

多对多关系分析

商品与订单是多对多关系,一个订单上可以有多个商品,一个商品可以出现在多个订单中
多对多建表原则 需要一张中间表,中间表中至少有两个字段,作为中间表的外键分别指向另外两张表的主键

在这里插入图片描述
中间表记录了,一个订单中所包含的商品信息

订单项表

package com.entity;


/**
 * orderitem表
 *  itemid VARCHAR(32) PRIMARY KEY, -- 订单项ID
 *   pid VARCHAR(32),  -- 外键 对应商品表 id
 *   oid VARCHAR(32), -- 外键 对应订单表 id
 */
public class OrderItem {
    
    private String itemid ;
    private String pid ;
    private String oid ;
    private Product product ;
    private Orders order ;
    
    
    public OrderItem() {
    }

    public OrderItem(String itemid, String pid, String oid, Product product, Orders order) {
        this.itemid = itemid;
        this.pid = pid;
        this.oid = oid;
        this.product = product;
        this.order = order;
    }

    public String getItemid() {
        return itemid;
    }

    public void setItemid(String itemid) {
        this.itemid = itemid;
    }

    public String getPid() {
        return pid;
    }

    public void setPid(String pid) {
        this.pid = pid;
    }

    public String getOid() {
        return oid;
    }

    public void setOid(String oid) {
        this.oid = oid;
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product product) {
        this.product = product;
    }

    public Orders getOrder() {
        return order;
    }

    public void setOrder(Orders order) {
        this.order = order;
    }

    @Override
    public String toString() {
        return "OrderItem{" +
                "itemid='" + itemid + '\'' +
                ", pid='" + pid + '\'' +
                ", oid='" + oid + '\'' +
                '}';
    }
}

编写DAO类

UserDao

  • 需求一:编写一个注册用户的方法,接收的参数是一个User对象
  • 需求二:编写一个用户登录的方法,接收的参数是用户名和密码 , 返回值是User对象

编写UserDAO

package com.dao;

import com.entity.User;
import com.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.SQLException;

public class UserDao {

//    需求一:编写一个注册用户的方法,接收的参数是一个User对象

    public int register(User user) throws SQLException {

//        获取QueryRunner对象
        QueryRunner qr = new QueryRunner(DruidUtils.dataSource) ;

//        编写SQL
        String sql = "insert into user values(?,?,?,?,?,?)" ;

        Object[] param = {user.getUid(),user.getUsername(),user.getPassword(),user.getTelephone(),user.getBirthday(),user.getSex()};

//        执行插入操作
        int update = qr.update(sql, param);

        return update;
    }

//    需求二:编写一个用户登录的方法,接收的参数是用户名和密码 , 返回值是User对象

    public User login(String username, String password) throws SQLException {

//        获取QueryRunner对象
        QueryRunner qr = new QueryRunner(DruidUtils.dataSource) ;

//        编写SQL
        String sql = "select * from user where username = ? and password = ?" ;

//        执行查询 使用BeanHanler来封装结果集,获取结果集中的第一条数据
        User user = qr.query(sql, new BeanHandler<User>(User.class), username, password);

        return user ;

    }
}


TestUserDAO类

package com.app;

import com.dao.UserDao;
import com.entity.User;
import com.utils.DateUtils;
import com.utils.UUIDUtils;
import org.junit.Test;

import java.sql.SQLException;

public class TestUserDao {

//    测试注册用户
    UserDao userDao = new UserDao();

    @Test
    public void testRegister() throws SQLException {

//        创建user
        User user = new User();
        user.setUid(UUIDUtils.getUUID());
        user.setUsername("武松");
        user.setPassword("123");
        user.setTelephone("13512341234");
        user.setSex("男");
        user.setBirthday(DateUtils.getDateFormart());

//        执行注册
        int register = userDao.register(user);

        if (register > 0){
            System.out.println("注册成功!欢迎您:" + user.getUsername());

        }else {
            System.out.println("注册失败");
        }
    }


//    用户登录测试
    @Test
    public void testLogin() throws SQLException {
//        调用UserDao的Login方法 传入用户名和密码
        User user = userDao.login("武松", "123");

//        判断user是否为空
        if (user != null){
            System.out.println("登录成功!欢迎您:" + user.getUsername());
        }else {
            System.out.println("登录失败,用户名或密码错误!");
        }
    }
}

ProductDao

  • 需求一:根据商品ID获取商品名称 ,商品价格 以及商品所属分类的名称
    参数pid,返回值product对象
  • 需求二:根据分类ID获取商品分类信息
    参数cid,返回值category对象
  • 需求三:查询指定分类ID下的商品个数
    参数cid,返回值int类型 商品个数
  • 需求四:查询指定分类ID下的所有商品信息
    参数分类ID,返回值List集合 集合中保存商品对象

编写ProductDao

package com.dao;

import com.entity.Category;
import com.entity.Product;
import com.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.SQLException;
import java.util.List;

public class ProductDao {

//    需求一:根据商品ID获取商品名称 ,商品价格 以及商品所属分类的名称

    public Product findProductById(String pid) throws SQLException {
//       创建QueryRunner
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource()) ;

//        编写SQL
        String sql = "select * from product where pid = ?" ;

//        执行查询
        Product product = qr.query(sql, new BeanHandler<Product>(Product.class), pid);


//        获取外键的值 对应分类的ID
        String cid = product.getCid();

//        商品对应的 分类信息
        Category category = findCategoryById(cid);

        product.setCategory(category);

        return product ;

    }

//    需求二:根据分类ID,查询分类的详细信息
    public Category findCategoryById(String cid) throws SQLException {

        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource()) ;

        String sql = "select * from category where cid = ?" ;

        Category category = qr.query(sql, new BeanHandler<Category>(Category.class), cid);

        return category ;
    }

//    需求三:查询指定分类ID下的商品个数

    public int getCount(String cid) throws SQLException {
        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource()) ;

        String sql = "select count(*) from product  where cid = ?" ;

//        获取单列数据 使用scalarHandler 来封装
        Long count = qr.query(sql, new ScalarHandler<>(), cid);


//        将long类型的包装类 转换为int类型 并返回
        return count.intValue();
    }


//    需求四:查询指定分类ID下的所有商品信息
    public List<Product> findProductByCid(String cid) throws SQLException {

        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource()) ;

        String sql = "select * from product where cid = ?" ;

        List<Product> list = qr.query(sql, new BeanListHandler<Product>(Product.class), cid);

        return list ;
    }

}

TestProductDao类

package com.app;

import com.dao.ProductDao;
import com.entity.Product;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

public class TestProductDao {

    ProductDao productDao = new ProductDao() ;
//    测试根据商品ID获取商品名称 ,商品价格 以及商品所属分类的名称

    @Test
    public void testFindProductById() throws SQLException {

        Product product = productDao.findProductById("1");

        System.out.println(product.getPname() + "  " + product.getPrice() + "  " + product.getCategory().getCname());
    }


//    测试 查询指定分类Id 下的商品个数
    @Test
    public void testgetCount() throws SQLException {

//        查询分类ID为3的分类 有几个商品

        int count = productDao.getCount("3") ;

        System.out.println("分类ID为3的商品个数是:" + count);
    }


//    测试 查询指定分类Id下的所有商品信息
    @Test
    public void testfindProductByCid() throws SQLException {

//        查询分类 Id为2 的所有商品信息
        List<Product> list = productDao.findProductByCid("2");

        for (Product product : list){
            System.out.println(product);
        }
    }

}

OrdersDao

多对一分析

OrderItem表与Orders表的关系是 多对一
在这里插入图片描述
订单项表中多条数据 可能属于同一个订单的
使用Java类描述多对一关系时 ,可以在一的一方添加一个集合 集合中保存的就是多的一方的数据

创建OrdersDao

  • 需求1:获取uid为001的用户的所有订单信息
    参数uid,返回值List<Orders>订单集合
  • 需求2:获取订单编号为:order001的订单中的所有商品信息
    参数oid,返回值List<Product>商品集合
package com.dao;

import com.entity.OrderItem;
import com.entity.Orders;
import com.entity.Product;
import com.utils.DruidUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class OrdersDao {

    //需求1: 获取 uid为 001 的用户的所有订单信息
    public List<Orders> findAllOrders(String uid) throws SQLException {

        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

        String sql = "select * from orders where uid = ?";

        //一个用户所有的订单信息
        List<Orders> ordersList = qr.query(sql, new BeanListHandler<Orders>(Orders.class), uid);

        return ordersList;
    }

    //需求2: 获取订单编号为 order001的订单中的所有商品信息
    public List<Product> findOrderById(String oid) throws SQLException {

        QueryRunner qr = new QueryRunner(DruidUtils.getDataSource());

        //1.查询订单项表 获取订单项表中 订单ID为order001的数据
        String sql = "SELECT pid FROM orderitem WHERE oid = ? ";

        //2.查询的结果是 多条订单项数据
        List<OrderItem> list = qr.query(sql, new BeanListHandler<OrderItem>(OrderItem.class), oid);

        //3.创建集合保存商品信息
        List<Product> productList = new ArrayList<>();

        ProductDao productDao = new ProductDao();

        //4.遍历订单项集合 获取Pid
        for (OrderItem orderItem : list) {

            //4.1从orderitem中获取 pid
            String pid = orderItem.getPid();

            //4.2 调用productDao
            Product product = productDao.findProductById(pid);

            //4.3 保存到集合
            productList.add(product);
        }

        //返回 订单中对应的商品信息
        return productList;
    }


}

TestOrdersDao 类

package com.app;

import com.dao.OrdersDao;
import com.entity.Orders;
import com.entity.Product;
import org.junit.Test;
import java.sql.SQLException;
import java.util.List;

public class TestOrdersDao {

    OrdersDao ordersDao = new OrdersDao();
    @Test
    public void testFindAllOrders() throws SQLException {

        List<Orders> allOrders = ordersDao.findAllOrders("001");

        for (Orders orders : allOrders){
            System.out.println(orders);
        }
    }

//    测试 获取订单编号为order001的订单中的所有商品信息
    @Test
    public void testFindOrderById() throws SQLException {

        List<Product> order001 = ordersDao.findOrderById("order001");

        for (Product product : order001){

            System.out.println(product);
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值