商品訂單的完成
首先在購物車頁根據(jù)當前登陸用戶id查詢數(shù)據(jù)庫中購物車表的該用戶所有購物車記錄,并顯示出來
<form action="/shop/toOrder">
<input name="userId" value="${item.userId}" type="hidden">
<div><input type="checkbox" id="all">全選</div>
<%--為了到訂單頁面只顯示以選擇的商品,所以要把當前每件以選擇的goodsId傳過去,讓訂單頁自己查詢購物車相應商品--%>
? ? ? ? ? ? ? ? <c:forEach items="${list}" var="item">
<div class="goods">
<input type="checkbox" class="one" name="goodsIds" value="${item.goodsId}">
<img src="${item.img}" >
<div>${item.goodsName}</div>
<div>${item.typeName}</div>
<div class="price">${item.price*item.num}</div>
<button type="button" onclick="miNum(${item.goodsId})">-</button>
<span>${item.num}</span>
<button type="button" onclick="addNum(${item.goodsId})">+</button>
<a href="/shop/deleteCart?id=${item.id}">刪除</a>
</div>
</c:forEach>
<div>
<div id="sumPrice">0.00</div>
</div>
<input type="submit" value="提交訂單">
</form>
/toOrder
顯示在form表單中,c:each 循環(huán)展示每個購物記錄。提交按鈕,根據(jù)當前check 復選框綁定的goodsid在數(shù)據(jù)庫中查詢相關購物記錄并顯示訂單。。
//展現(xiàn) 已選擇的商品,總價,地址。
//list顯示
//傳過來goodsIds和隱藏的userId ,查找.
Cart cart=WebUtils.populate(Cart.class,req);
List carts=cartService.getCartsInGoodsIds(cart);
req.setAttribute("carts",carts);
double sumPrice=0.0;
for (Cart cart1 : carts) {
sumPrice+=cart1.getPrice()*cart1.getNum();
}
req.setAttribute("sumPrice",sumPrice);
List addrs=addrService.getAddrs(cart.getUserId());
req.setAttribute("addrs",addrs);
req.getRequestDispatcher("/WEB-INF/pages/toOrder.jsp").forward(req,resp);
toorder.jsp 顯示當前已購物車車中的記錄,和地址。生成初步訂單模型,點擊確定按鈕,調(diào)用web層應用,保存訂單信息和映射表
<form action="/shop/toPay">
<div>
<div id="addr">
請選擇收貨地址
? ? ? ? <select name="addressId">
<c:forEach items="${addrs}" var="address">
<option value="${address.id}">${address.content}</option>
</c:forEach>
</select>
</div>
<div id="head">
<c:forEach items="${carts}" var="item">
<input name="goodsIds" value="${item.goodsId}" type="hidden">
<div class="goods">
<img src="${item.img}">
<span>${item.goodsName}</span>
<span>${item.typeName}</span>
數(shù)量<span>${item.num}</span>
單價<span>${item.price}</span>
價格<span>${item.price*item.num}</span>
</div>
</c:forEach>
</div>
<div id="sumPrice">
訂單價格:${item.sumPrice} <br>
<input type="submit" value="去支付">
</div>
</div>
</form>
插入訂單表信息,包括訂單表,和第三張表,聯(lián)系用戶id和商品詳細信息的表。同時刪除購物車記錄。
OrderBean orderBean=WebUtils.populate(OrderBean.class,req);
User user= (User) req.getSession().getAttribute("user");
orderBean.setUserId(user.getId());
//保存用戶訂單和映射表
boolean flg=orderService.saveOrder(orderBean);
req.getRequestDispatcher("/shop/toCartPage").forward(req,resp);
public boolean saveOrder(OrderBean orderBean){
//? ? orderBean傳過來有addressid,userId,goodsIds
? ? ? ? //需要設置sumPrice,status,createTime
? ? ? ? Cart cart=new Cart();
cart.setGoodsIds(orderBean.getGoodsIds());
cart.setUserId(orderBean.getUserId());
List carts=cartDao.getCartsInGoodsIds(cart);
double sumPrice=0.0;
for (Cart cart1 : carts) {
sumPrice+=cart1.getPrice()*cart1.getNum();
}
orderBean.setSumPrice(sumPrice);
orderBean.setStatus(1);
orderBean.setCreateTime(System.currentTimeMillis());
//保存訂單,返回訂單號
? ? ? ? int orderId=orderDao.SaveOrder(orderBean);
int num=0;
if (orderId>0){//保存訂單成功,并返回訂單id,繼續(xù)保存映射表
? ? ? ? ? int n[]=orderDao.SaveMapping(carts,orderId);
if (n!=null&&n.length>0){//映射表保存之后,刪除購物車信息Cart
? ? ? ? ? ? ? for (Cart cart1 : carts) {
num=cartDao.deleteCartById(cart1);
}
}
return num>0;
}
return false;
}
枚舉類
public enum Week2 {
//定義變量,指向?qū)ο?/p>
MON("星期一") ,TUE("星期二") ,WED("星期三") ,THU("星期四") ,FRI("星期五") ,SAT("星期六") ,SUN("星期日") ;
String name ;
//私有化構造
private Week2(String name){
this.name = name;
}
public String getName() {
return name;
}
}
定義枚舉類要用關鍵字enum
所有枚舉類都是Enum的子類
枚舉類的第一行上必須是枚舉項,最后一個枚舉項后的分號是可以省略的,但是如果枚舉類有其他的東西,這個分號就不能省略。建議不要省略
枚舉類可以有構造器,但必須是private的,它默認的也是private的。
枚舉類也可以有抽象方法,但是枚舉項必須重寫該方法
swicth語句可以使用枚舉
類加載
當程序要使用某個類時,如果該類還未被加載到內(nèi)存中,則系統(tǒng)會通過加載,連接,初始化三步來實現(xiàn)對這個類進行初始化
加載
就是指將.class文件讀入內(nèi)存,并為之創(chuàng)建一個Class對象。任何類被使用時系統(tǒng)都會建立一個Class對象。
連接
驗證 是否有正確的內(nèi)部結構,并和其他類協(xié)調(diào)一致
準備 負責為類的靜態(tài)成員分配內(nèi)存,并設置默認初始化值
解析 將類的二進制數(shù)據(jù)中的符號引用替換為直接引用
初始化 就是我們以前講過的初始化步驟
類加載器的分類
Bootstrap ClassLoader 根類加載器
Extension ClassLoader 擴展類加載器
Sysetm ClassLoader 系統(tǒng)類加載器
AppClassLoader 應用類加載器
類加載器的作用
BootstrapClassLoader 根類加載器
也被稱為引導類加載器,負責Java核心類的加載 、比如System,String等。在JDK中JRE的lib目錄下rt.jar文件中
ExtensionClassLoader 擴展類加載器
負責JRE的擴展目錄中jar包的加載。在JDK中JRE的lib目錄下ext目錄
SysetmClassLoader 系統(tǒng)類加載器
負責在JVM啟動時加載來自java命令的class文件,以及classpath環(huán)境變量所指定的jar包和類路徑
AppClassLoader 加載其他類
負載一些非核心類和程序猿自己寫的類
反射
榨汁機案例
interface Fruit {
public void squeeze();
}
class Apple implements Fruit {
public void squeeze() {
System.out.println("榨出一杯蘋果汁兒");
}
}
class Orange implements Fruit {
public void squeeze() {
System.out.println("榨出一杯桔子汁兒");
}
}
class Juicer {
public void run(Fruit f) {
f.squeeze();
}
}
public static void main(String[] args) throws Exception {
//從本地讀取配置文件
BufferedReader br = new BufferedReader(new FileReader("config.txt"));
? ? //創(chuàng)建輸入流對象,關聯(lián)配置文件
Class<?> clazz = Class.forName(br.readLine()); //讀取配置文件一行內(nèi)容,獲取該類的字節(jié)碼對象
Fruit f = (Fruit) clazz.newInstance(); //通過字節(jié)碼對象創(chuàng)建實例對象
Juicer j = new Juicer();
j.run(f);
}
動態(tài)代理
代理: 本來應該自己做的事情,請了別人來做,被請的人就是代理對象
動態(tài)代理:在程序運行過程中產(chǎn)生的這個對象,而程序運行過程中產(chǎn)生對象其實就是我們剛才反射講解的內(nèi)容,所以,動態(tài)代理其實就是通過反射來生成一個代理對象
代理可以使我們在不破壞源代碼的情況下增加新的功能
原始jdk動態(tài)代理
public static Object get(String str){
//想要實現(xiàn)一個日志系統(tǒng),給所有的方法加上時間測試,假設有100個類,共1000個方法
? ? //第一種方式: 在原始類的原始方法中添加檢測時間的代碼? 缺點 : 原始類中的代碼較多,修改時的安全性得不到保障 耗時耗力 擴展性極差
? ? //第二種方式: 靜態(tài)代理, 不修改任何原始代碼, 重新定義一個類,實現(xiàn)和原始類一樣的接口,重寫一樣的方法
? ? //? ? ? ? ? 在代理類的方法中調(diào)用原始類的方法,并且加上檢測代碼,
? ? //? ? ? ? ? 優(yōu)點 : 安全性較高 提高了擴展性
? ? //? ? ? ? ? 缺點 : 代碼量太大了? 重寫100個類, 重寫1000個方法
? ? //第三種方式: 動態(tài)代理, 創(chuàng)建一套工具, 提供必要的參數(shù), 由這套工具來幫我們生成代理類的對象
? ? //? ? ? ? ? 優(yōu)點 : 節(jié)省代碼量? ? 重寫100次代理方法
? ? //幫助我們自動生成代理類
? ? if(str.equals("com.qianfeng.part04.Demo")){
Demo demo =new Demo();
//提供 原始類的類加載器, 原始類的所有接口, 需要執(zhí)行的代碼
? ? ? ? DemoInterface demoInterface = (DemoInterface) Proxy.newProxyInstance(demo.getClass().getClassLoader(),
demo.getClass().getInterfaces(),new InvocationHandler() {
@Override
? ? ? ? ? ? public Object invoke(Object proxy, Method method, Object[] args)throws Throwable {
long start = System.currentTimeMillis();
Object obj = method.invoke(demo,args);
long end = System.currentTimeMillis();
System.out.println(new Date().toString()+method.getName()+"方法運行耗時:"+(end-start)+"毫秒");
return obj;
}
});
return demoInterface;
}
return null;
}
cglib
定義
非java原生的動態(tài)代理, 效率更高,限制更小
可以代理沒有接口的類
使用
導包??
演示
public static void main(String[] args) {
//導入包 cglib-core? asm ant ant-launcher
//創(chuàng)建運行器
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);
//創(chuàng)建代理對象
Demo d = (Demo)enhancer.create();
d.method();
}