美文网首页
Java - Part 15

Java - Part 15

作者: 低调的灬攻城狮 | 来源:发表于2020-02-26 00:50 被阅读0次

一、购物车的实现

购物车在数据库中需要单独一张表,字段有id、userId、goodsId、num、createTime。所有用户的购物车数据都在这张表中,对购物车的增删改查也在这张表中。

1、购物车Dao层

购物车Dao层需要实现的操作有添加购物车、根据用户id和商品id查询记录、修改购物车商品的数量、删除购物车、查询某个用户所有的购车车记录

package com.shop.dao;

import com.shop.bean.Cart;
import com.utils.DBUtils;
import com.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

/**
 * 购物车
 */
public class CartDao {
    /**
     * 根据订单id和商品id获取商品信息
     * @param cart
     * @return
     */
    public List<Cart> getCartsInGoodsId(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            cn = JDBCUtils.getConnection();
            int[] goodsIds = cart.getGoodsIds();
            String sql = "select c.id,c.userId, c.goodsId,c.num ,g.price,g.name as goodsName,g.icon, t.name as typeName from cart c " +
                    "left join goods g on g.id = c.goodsId " +
                    "left join types t on t.id = g.typeId " +
                    "where c.userId=? and g.status=1 ";
            if(goodsIds!=null) {
                sql += " and c.goodsId in (";
                for (int i = 0; i <goodsIds.length ; i++) {
                    if(i==goodsIds.length-1) {
                        sql += goodsIds[i]+")";
                    } else {
                        sql += goodsIds[i]+",";
                    }
                }
            }
            ps = cn.prepareStatement(sql);
            ps.setInt(1,cart.getUserId());
            rs = ps.executeQuery();
            List<Cart> list = DBUtils.selectMore(Cart.class,rs);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(rs,ps,cn);
        }
        return null;
    }
    /**
     * 添加购物车记录
     * @param cart
     * @return
     */
    public int saveCart(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("insert into cart values (default ,?,?,?,?)");
            ps.setInt(1,cart.getUserId());
            ps.setInt(2,cart.getGoodsId());
            ps.setInt(3,cart.getNum());
            ps.setLong(4,cart.getCreateTime());
            int num = ps.executeUpdate();
            return num;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.close(ps,cn);
        }
        return 0;
    }

    /**
     * 根据用户id和商品id查询购物车记录的id值
     * @param cart
     * @return
     */
    public int getCartByUserIdAndGoodsId(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("select id from cart where userId=? and goodsId=? ");
            ps.setInt(1,cart.getUserId());
            ps.setInt(2,cart.getGoodsId());
            rs = ps.executeQuery();
            if (rs.next()){
                return rs.getInt(1);
            }
        }catch (Exception e){

        }finally {
            JDBCUtils.close(rs,ps,cn);
        }
        return 0;
    }
    /**
     * 根据用户id和商品id修改购物车记录的数量
     * @param cart
     * @return
     */
    public int editCartNumByUserIdAndId(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("update cart set num=num+? where userId=? and id=?");
            ps.setInt(1,cart.getNum());
            ps.setInt(2,cart.getUserId());
            ps.setInt(3,cart.getId());
            int num = ps.executeUpdate();
            return num;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.close(ps,cn);
        }
        return 0;
    }

    /**
     * 根据用户id和商品id删除购物车记录
     * @param cart
     * @return
     */
    public int deleteCartByUserIdAndId(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("delete from cart where userId=? and id=?");
            ps.setInt(1,cart.getUserId());
            ps.setInt(2,cart.getId());
            int num = ps.executeUpdate();
            return num;
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.close(ps,cn);
        }
        return 0;
    }

    /**
     * 根据用户id查询购物车中的所有记录
     * @param cart
     * @return
     */
    public List<Cart> getCarts(Cart cart){
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("select c.*,g.icon,g.price ,g.name as goodsName ,t.name as typeName from cart c " +
                    "left join goods g on g.id = c.goodsId " +
                    "left join types t on t.id = g.typeId " +
                    "where c.userId=? order by c.createTime DESC");
            ps.setInt(1,cart.getUserId());
            rs = ps.executeQuery();
            List<Cart> list = DBUtils.selectMore(Cart.class,rs);
            return list;
        }catch (Exception e){

        }finally {
            JDBCUtils.close(rs,ps,cn);
        }
        return null;
    }
}

2、前端页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/resource/pages/header.jsp"%>
<html>
<head>
    <title>MyCart</title>
    <style>
        img{
            height: 100px;
            width: 100px;
        }
        #sumPrice{
            color: red;
            font-size: 30px;
            font-weight: 600;
        }
        .goods{
            border:1px black solid;
            margin: 10px 0px;
            display: inline-block;
            width: 600px;
            height: 300px;
            font-size: 30px;
        }
        .one,#all {
            width: 30px;
            height: 30px;
            font-size: 50px;
            zoom: 80%;
        }
    </style>
    <link rel="stylesheet" href="/resource/css/MyCss.css">
    <link rel="stylesheet" href="/resource/css/styles.css">
</head>
<body style="background: url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578736051725&di=76768c9735298e1e0422b1930727c243&imgtype=0&src=http%3A%2F%2Fimg.pptjia.com%2Fimage%2F20190112%2F43847e4d1e0b3af9623f502c45148e15.jpg)">
<div>
    <div class="heading">个人购物车</div>
    <form action="/shop/toOrder" class="table">
        <c:forEach items="${list}" var="item">
            <div class="goods">
                <input class="one" type="checkbox" value="${item.goodsId}" name="goodsIds"><br>
                <img src="${item.icon}"><br>
                <span>${item.goodsName}</span><br>
                <span>${item.typeName}</span><br>
                <button type="button" class="btn" onclick="minNum(${item.id})">-</button>
                <span>${item.num}</span>
                <button type="button" class="btn" onclick="addNum(${item.id})">+</button><br>
                <span class="price">${item.price*item.num}¥</span>&ensp;<br>
                <a href="/shop/deleteCart?id=${item.id}">删&ensp;除</a><br><br>
            </div>
        </c:forEach>
        <div>
            <div style="text-align: left;width: 200px;display: inline-block;"><input id="all" type="checkbox"> 全选</div>
            <div style="text-align: right;width: 400px;display: inline-block;" id="sumPrice">总价格:0.00&ensp;¥</div>
            <br><br>
            <input class="btn" type="submit" value="提交订单">
        </div>
    </form>
</div>
</body>
<script>
    //全选框
    $("#all").click(function () {
        var flg = $(this).prop("checked");
        $(".one").each(function () {
            $(this).prop("checked",flg);
        });
        sumPrice(); //每点击一个全选按钮都要重新计算
    });
    //子选择框
    $(".one").each(function () {
        $(this).click(function () {
            var flg = $(this).prop("checked");
            if(flg){
                if($(".one:checked").length==$(".one").length){
                    $("#all").prop("checked",flg);
                }
            }else{
                $("#all").prop("checked",flg);
            }
            sumPrice(); //每点击一次子选框也要重新计算
        });
    });
    //计算出总价格
    function sumPrice(){
        var sum = 0.00;
        $(".price").each(function(){
            //先获取价格区域的父级,然后再找子级的多选框
            var one = $(this).parent().children(".one");
            if(one.prop("checked")){//如果多显框时勾上的,就计算总价格
                var price = $(this).text();
                sum += parseInt(price);
            }
        });
        $("#sumPrice").text("总价格:" + sum + "¥");
    }
    function minNum(id){
        location.href="/shop/editCartNum?num=-1&id="+id;
    }
    function addNum(id){
        location.href="/shop/editCartNum?num=1&id="+id;
    }
</script>
</html>

二、订单实现

订单在数据库中需要单独一张表来存储,一个订单中有多件商品,一件商品可以在多个订单中,所以这两者是多对多的关系。需要第三张表订单-商品映射表来存储订单与商品的关系,还要存储商品的数量。对于订单的操作同样有增删改查,但是此时比较麻烦,因为要同时对三张表进行操作。提单提交完成之后需要清空购物车。

package com.shop.dao;

import com.shop.bean.Cart;
import com.shop.bean.Goods;
import com.shop.bean.OrderBean;
import com.utils.DBUtils;
import com.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;

public class OrderDao {
    /**
     * 根据用户id和订单id删除订单信息
     * @param orderBean
     * @return
     */
    public int deleteOrderByOrderIdAndUserId(OrderBean orderBean){
        Connection cn = null;
        PreparedStatement ps = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("delete from orders where id=? and userId=? ");
            ps.setInt(1,orderBean.getId());
            ps.setInt(2,orderBean.getUserId());
            int num = ps.executeUpdate();
            return num;
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps,cn);
        }
        return 0;
    }
    /**
     * 根据订单id删除映射商品信息
     * @param orderId
     * @return
     */
    public int deleteMappingByOrderIdAndUserId(int orderId){
        Connection cn = null;
        PreparedStatement ps = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("delete from order_goods_map where orderId=? ");
            ps.setInt(1,orderId);
        }catch (Exception e){
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps,cn);
        }
        return 0;
    }
    /**
     * 根据订单id查询映射商品的详细信息
     * @param orderId
     * @return
     */
    public List<Goods> getGoodsByOrderId(int orderId){
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("select ogm.num,ogm.price ,g.name,t.name as typeName,g.icon " +
                    "from order_goods_map ogm " +
                    "left join goods g on g.id = ogm.goodsId " +
                    "left join types t on t.id = g.typeId " +
                    "where ogm.orderId=? ");
            ps.setInt(1,orderId);
            rs = ps.executeQuery();
            List<Goods> list = DBUtils.selectMore(Goods.class,rs);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(rs,ps,cn);
        }
        return null;
    }
    /**
     * 根据用户id查询当前用户的所有订单
     * @param userId
     * @return
     */
    public List<OrderBean> getOrdersByUserId(int userId) {
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("select o.id,o.sumPrice,o.status,o.createTime,ad.content " +
                    "from orders o " +
                    "left join address ad on ad.id = o.addressId " +
                    "where o.userId=? ");
            ps.setInt(1,userId);
            rs = ps.executeQuery();
            List<OrderBean> list = DBUtils.selectMore(OrderBean.class,rs);
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps,cn);
        }
        return null;
    }
    /**
     * 保存订单商品映射信息
     * @param carts
     * @param orderId
     * @return
     */
    public int[] saveMapping(List<Cart> carts,int orderId){
        Connection cn = null;
        PreparedStatement ps = null;
        try {
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("insert into order_goods_map values(?,?,?,?)");
            for (Cart cart : carts) {
                ps.setInt(1,orderId);
                ps.setInt(2,cart.getGoodsId());
                ps.setInt(3,cart.getNum());
                ps.setDouble(4,cart.getPrice());
                ps.addBatch();
            }
            int[] num = ps.executeBatch();
            return num;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.close(ps,cn);
        }
        return null;
    }
    /**
     * 保存订单,并且返回订单的id
     * @param orderBean
     * @return
     */
    public int saveOrder(OrderBean orderBean){
        Connection cn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            cn = JDBCUtils.getConnection();
            ps = cn.prepareStatement("insert into orders values(default ,?,?,?,?,?)",PreparedStatement.RETURN_GENERATED_KEYS);
            ps.setInt(1,orderBean.getUserId());
            ps.setInt(2, orderBean.getAddressId());
            ps.setDouble(3, orderBean.getSumPrice());
            ps.setInt(4,orderBean.getStatus());
            ps.setLong(5, orderBean.getCreateTime());
            int num = ps.executeUpdate();
            rs = ps.getGeneratedKeys();
            if (rs.next()){
                return rs.getInt(1);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.close(rs,ps,cn);
        }
        return 0;
    }
}
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/resource/pages/header.jsp"%>
<html>
<head>
    <title>我的订单</title>
    <style>
        div {text-align: center;}
        .order{
            border: 1px solid black;
            text-align: center;
            width: 700px;
            font-size: 30px;
        }
        .goods img{
            height: 100px;
        }
    </style>
    <link rel="stylesheet" href="/resource/css/MyCss.css">
</head>
<body style="background: url(https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1578736051725&di=76768c9735298e1e0422b1930727c243&imgtype=0&src=http%3A%2F%2Fimg.pptjia.com%2Fimage%2F20190112%2F43847e4d1e0b3af9623f502c45148e15.jpg)">
    <div>
        <div class="heading">我的订单</div>
        <c:forEach items="${orders}" var="item">
            <div class="order">
                <div>
                    <span>编&ensp;码:${item.id}</span><br>
                    <span>订单时间:${item.time}</span><br>
                    <span>总&ensp;价:${item.sumPrice}&ensp;¥</span><br>
                    <c:if test="${item.status==1}">
                        <span style="color: #38f000;font-weight: bold;">√&ensp;已支付</span><br>
                    </c:if>
                    <c:if test="${item.status==0}">
                        <span style="color: red;font-weight: bold;">×&ensp;未支付</span><br>
                    </c:if>
                    <span>收货地址:${item.content}</span>
                </div>
                <div>
                    <c:forEach items="${item.goods}" var="goods">
                        <div class="goods">
                            <img src="${goods.icon}"><br>
                            <span>${goods.name}</span><br>
                            <span>${goods.typeName}</span><br>
                            <span>${goods.price}¥&ensp;*&ensp;${goods.num}件</span>
                        </div><br>
                    </c:forEach>
                    <a  href="/shop/deleteOrder?id=${item.id}">删&ensp;除</a>
                </div><br>
            </div>
        </c:forEach>
    </div>
</body>
</html>

三、枚举

枚举可以理解为有限制的多例,在当前类中定义多个实例供别人使用。我们之前学过单例模式,在程序运行期间只允许一个实例存在,如果要允许多个实例存在的话就需要使用多例模式。
1、枚举类的注意事项

  • 定义枚举类都要使用关键字enum
  • 所有枚举类都是Enum的子类
  • 枚举类的第一行上必须是枚举项,最后一个枚举项后的分号是可以省略的,建议不要省略
  • 枚举类可以有构造器,但必须是private,默认就是private
  • 灭聚类也可以有抽象方法,但是枚举项必须重写该方法
  • switch语句可以使用枚举
//枚举: 多例的简化形式
public enum Message {
    //将零散的公共静态常量进行了分装, 将他们约束成一组
    REQUEST_SUCCESS (1,"请求成功"){
        public void method() { }
    },
    REQUEST_FAIL(-1,"请求失败"){
        public void method() { }
    },
    LGOIN_SUCCESS(2,"登陆成功"){
        public void method() { }
    },
    LGOIN_FAIL(-2,"登陆失败"){
        public void method() { }
    };
    private int code ;
    private String message;
    Message(int code, String message) {
        this.code = code;
        this.message = message;
    }
    public int getCode() {
        return code;
    }
    public String getMessage() {
        return message;
    }
    //抽象方法必须在枚举项中重写
    public abstract void method();
}

2、常用方法

  • int ordinal() 获取枚举项的序号
  • int compareTo(E o) 比较两个枚举项
  • String name() 获取枚举枚举项的名称
  • String toString() 获取枚举项的字符串表现形式
  • <T> T valueOf(Class<T> type,String name) 使用字节码和名称获取枚举项
  • values() 它遍历枚举类的所有枚举值非常方便

四、类加载

1、定义
如果程序要使用某个类,系统会通过加载、连接、初始化三步来实现对这个类进行初始化

  • 加载就是将.class文件读入内存,并为之创建一个Class对象
  • 连接:验证、准备、解析
  • 初始化:执行类的静态代码块,为类的静态成员初始化

2、加载的时机
只有当类真正被使用时,类才会被加载

  • 创建类的实例
  • 访问类的静态变量,或者为静态变量赋值
  • 调用类的静态方法
  • 使用反射方式强制创建某个类或接口对象的java.lang.Class对象
  • 加载某个类的子类
  • 直接使用java.exe命令来运行某个主类

3、类加载器
类加载器负责将.class文件加载到内存中,并为之生成对应的Class对象

  • 3.1 类加载器的作用

    • BootstrapClassLoader 根类加载器
      • 也被称为引导类加载器,负责Java核心类的加载
      • 比如System,String等。在JDK中JRE的lib目录下rt.jar文件中
    • ExtensionClassLoader 扩展类加载器
      • 负责JRE的扩展目录中jar包的加载。
      • 在JDK中JRE的lib目录下ext目录
    • SysetmClassLoader 系统类加载器
      • 负责在JVM启动时加载来自java命令的class文件,以及classpath环境变量所指定的jar包和类路径
    • AppClassLoader 加载其他类
    • 负载一些非核心类和程序猿自己写的类
  • 3.2 双亲委派模型
    类加载器总是先让父类加载器去加载,如果父类加载器加载不了,一直到跟类加载器,如果父类加载器加载不了,则会让子类加载器加载。这样做的好处有两个:安全性,避免用户自己编写的类动态替换Java的一些核心类;同时也避免了类的重复加载。

五、反射

Java的反射是通过一个类的字节码获取这个类的所有信息,还可以进行操作
1、获取字节码的三种方式

  • 对象.getClass()
  • 类名.class
  • Class.forName("类名")

2、反射获取构造函数

  • Class类的newInstance()方法是使用该类无参的构造函数创建对象,如果要使用有参构造,可以调用Class类的getConstructor(String.class,int.class)方法获取一个指定的构造函数然后再调用Constructor类的newInstance("张三",20)方法创建对象

3、反射获取成员变量

  • Class.getField(String)方法可以获取类中的指定字段(可见的)
  • 如果是私有的可以用getDeclaredField("name")方法获取
  • 通过get(obj) 和set(obj, "李四")方法可以获取和设置指定对象上该字段的值, obj指的是这个类的对象
  • 如果是私有的需要先调用setAccessible(true)设置访问权限放开

4、反射获取成员方法

  • Class.getMethod(String, Class...) 和 Class.getDeclaredMethod(String, Class...)方法可以获取类中的指定方法
  • 调用invoke(Object, Object...)可以调用对象的这个方法

六、动态代理

动态代理让我们在不破坏代码的情况下增加新的功能,常用于Java项目检测代码运行效率。
1、Java中动态代理
利用对象的类的字节码接口,写出一个新的类到本地区,通过编译器直接编译成.class文件,再通过类加载器加载进来。但是这样做有一个缺点,就是代理的对象必须实现接口。

  • 在Java中java.lang.reflect包下提供了一个Proxy类和一个InvocationHandler接口,通过使用这个类和接口就可以生成动态代理对象
  • public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
  • 最终会调用InvocationHandler的方法InvocationHandler Object invoke(Object proxy,Method method,Object[] args)

2、cglib
非Java原生的动态代理,效率更高,限制更小,并且可以代理没有接口的类,它的原理是生成一个原始类的子类对象

  • 要想使用cglib必须要导入四个包:ant、ant-launcher、asm、cglib。
public static void main(String[] args) {
    //创建运行器
    MethodInterceptor mi = new MethodInterceptor() {
        @Override
        public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
            System.out.println("运行前");
            arg3.invokeSuper(arg0, arg2);
            System.out.println("运行后");
            return null;
        }
    };
    //获取代理类
    Enhancer enhancer = new Enhancer();
    //设置父类
    enhancer.setSuperclass(Demo.class);
    //运行任务
    enhancer.setCallback(mi);
    //创建代理对象
    Demo d = (Demo)enhancer.create();
    d.method();
}

相关文章

网友评论

      本文标题:Java - Part 15

      本文链接:https://www.haomeiwen.com/subject/zsmqxhtx.html