美文网首页
第十五篇学习总结

第十五篇学习总结

作者: 拼搏男孩 | 来源:发表于2020-02-01 11:25 被阅读0次

第十五篇学习总结

一、购物车的实现

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

1、购物车Dao层

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

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

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

/**
 * 购物车
 */
public class CartDao {

    /**
     * 添加一条购物车记录
     * @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) {
            e.printStackTrace();

        }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.img,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) {
            e.printStackTrace();

        }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>我的购物车</title>
    <style>
        .goods{
            border:1px black solid;
            margin: 10px 0px;
        }
        .goods img{
            height: 100px;
        }
        #sumPrice{
            color: red;
            font-size: 30px;
            font-weight: 600;
        }
    </style>
</head>

<body>

<div>
    <div>
        <input id="all" type="checkbox"> 全选
    </div>

    <c:forEach items="${list}" var="item">
        <div class="goods">
            <input class="one" type="checkbox">
            <img src="${item.img}">
            <span>${item.goodsName}</span>
            <span>${item.typeName}</span>
            <span class="price">${item.price*item.num}</span>
            <button onclick="miNum(${item.id})">-</button><span>${item.num}</span><button onclick="addNum(${item.id})">+</button>
            <a href="/shop/deleteCart?id=${item.id}">删除</a>
        </div>
    </c:forEach>
    <div>
        <div id="sumPrice">0.00</div>
    </div>
</div>

</body>
<script>
    //使用js实现全选与反选,总价格是由js计算出来然后通过修改html来显示的
    $("#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 miNum(id){
        location.href="/shop/editCartNum?num=-1&id="+id;
    }
    //增加
    function addNum(id){
        location.href="/shop/editCartNum?num=1&id="+id;
    }


</script>
</html>

二、订单实现

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

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

import javax.management.Query;
import javax.xml.transform.Result;
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());

            return ps.executeUpdate();
        } 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_mapping where orderId=?");

            ps.setInt(1, orderId);

            return ps.executeUpdate();
        } 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.img " +
                    "from order_goods_mapping 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(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_mapping 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(ps,cn);
        }
        return 0;

    }
}

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ include file="/resource/pages/header.jsp"%>
<html>
<head>
    <title>我的订单</title>
    <style>
        .order{
            border: 1px solid black;
        }
        .goods img{
            height: 100px;
        }
    </style>
</head>
<body>

    <c:forEach items="${orders}" var="item">
        <div class="order">
            <div>
                <span>编码 : ${item.id}</span>
                <span>${item.time}</span>
                <span>${item.sumPrice}</span>
                <c:if test="${item.status==1}">
                    <span>已支付</span>
                </c:if>
                <c:if test="${item.status==0}">
                    <span>未支付</span>
                </c:if>
                <a  href="/shop/deleteOrder?id=${item.id}">删除</a>
                <br>
                <span>${item.content}</span>
            </div>
            <div>
                <c:forEach items="${item.goods}" var="goods">
                    <div class="goods">
                        <img src="${goods.img}">
                        <span>${goods.name}</span>
                        <span>${goods.typeName}</span>
                        <span>${goods.price} * ${goods.num}</span>
                    </div>
                </c:forEach>
            </div>
        </div>
    </c:forEach>

</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();
}

相关文章

  • 第十五篇学习总结

    第十五篇学习总结 一、购物车的实现 购物车在数据库中需要单独一张表,字段有id、userId、goodsId、nu...

  • 学习总结第十五篇 5.21

    内容总结: 1、冒泡排序 2、函数 返回值类型 函数名(参数列表){ 函数体 } 函数名: A、尽量见名知意 B、...

  • 世界是有生命的

    ----《通向财富自由之路》学习总结第十五篇 最近因为工作调度的事情,有了一段空闲的日子,有比较多的时间来回望自己...

  • 学习,改变,进步

    感赏日记第十五篇6月26日 不知不觉已进群学习十五天了,总结一下自己还是比较认真的在学习课程,虽然还没学完一遍,但...

  • 日精进:2023-02-03

    1、日记一篇300字 2、八段锦24分钟 3、《论语》第十五篇 4、日更1300字,月度总结

  • 彭放|感悟《论语》的人文情怀之【15.1】——孔子不赞同卫灵公战

    第十五篇 卫灵公第十五 从今天开始进入“卫灵公第十五”的学习。本篇包括42章,以人格品质锻铸、为人处世原则,在困厄...

  • 015

    第十五篇

  • 第十五篇反思总结

    这个周末都没有写反思,因为自己除了星期六早上之外都没怎么学习。 今天深深感觉到了没有计划的窘迫之处。

  • 2016.2.8 论语学习(30)为政篇第十五则

    2016.2.8 论语学习(30)为政篇第十五则 【2.15原文】 子曰:“学而不思则罔,思而不学则殆。” 【傅佩...

  • 论语学习第十五篇

    1.15 子贡曰:“贫而无谄①,富而无骄,何如②?”子曰:“可也。未若贫而乐③,富而好礼者也。”子贡曰:《诗》云,...

网友评论

      本文标题:第十五篇学习总结

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