〇、本模塊內容簡介前端
30=(DB5+前端5+Web Core15+Project5)java
Junit、註解mysql
MySQL、JDBC、JDBCUtils、c3p0、Druid鏈接池及工具類、JDBCTemplatesql
---------------------------------------------------------------------------------------------數據庫
HTML、CSS、JavaScript、BootStrap、Xml、Jsoup、JQuery緩存
----------------------------------------------------------------------------------------------安全
Tomcat、Servlet、Request、Response、Cookie、Session、JSP、EL、JSTL、Maven、Redis、Nginx、Linux服務器
-------------------------------------------------------------------------------------------------------------------------------------------------------架構
基於緩存與異步技術的旅遊網設計app
------------------------------------------
1、基礎加強
一、Junit單元測試
二、註解
元註解 @Documented //註解會抽取到文檔中 @Retention(RUNTIME)//註解被保留的階段:Source/Class/Runtime @Target(TYPE,METHOD,FIELD)//做用位置:類、方法、成員變量
@Inherited //加註解的類的子類會自動繼承父類註解
public @interface 註解名稱(){ 屬性列表,如
public abstaract String show(); }
1 package com.liujinhui.Day1209BaseEnhance.annotation; 2 import java.io.InputStream; 3 import java.lang.reflect.Method; 4 import java.util.Properties; 5 /* 6 假設的框架類 7 改配置文件使程序的擴展性更強,配置文件中使用了全類名,則使用了反射機制 8 * */ 9 @Pro(className = "com.liujinhui.Day1209BaseEnhance.annotation.Demo1",methodName = "show") 10 //要寫全類名 11 public class ReflectTest { 12 /** 13 * @author: Liu Jinhui 14 * @description: 建立任意對象 15 * @date: 2020/12/9 20:42 16 * @return * @param null 17 */ 18 public static void main(String[] args) throws Exception{ 19 //能夠建立任意類的對象,能夠執行任意方法 20 /* 21 前提:不能改變該類的任何代碼,能夠建立任意類的對象,能夠執行任意方法 22 * */ 23 //1.解析註解 24 //1.1獲取該類的字節碼文件對象 25 Class<ReflectTest> reflectTestClass = ReflectTest.class; 26 //2.獲取上面的註解對象 27 //method也有getAnno 28 Pro an = reflectTestClass.getAnnotation(Pro.class); 29 //其實就是在內存中生成了一個該註解接口的子類實現對象 30 /* 31 public class ProIMpl implements Pro{ 32 public String className(){ 33 return "com.liujinhui.Day1209BaseEnhance.annotation.Demo1"; 34 } 35 public String methodName(){ 36 return "show"; 37 } 38 */ 39 //3.調用註解對象中調用的抽象方法,獲取返回值 40 String className = an.className(); 41 String methodName = an.methodName(); 42 System.out.println(className+methodName); 43 //4.加載該類進內存 44 Class cls = Class.forName(className); 45 //5.建立對象 46 Object obj = cls.newInstance(); 47 //6.獲取方法對象 48 Method method = cls.getMethod(methodName); 49 //7.執行方法 50 method.invoke(obj); 51 } 52 }
1 /* 2 描述須要執行的類名和方法名 3 */ 4 @Target({ElementType.TYPE}) 5 @Retention(RetentionPolicy.RUNTIME) 6 public @interface Pro { 7 String className(); 8 String methodName(); 9 }
三、基於註解解析的自定義測試框架
使用技術:字符緩衝輸出流、註解解析
1 package com.liujinhui.Day1209BaseEnhance.annotation.demo; 2 3 import java.lang.annotation.ElementType; 4 import java.lang.annotation.Retention; 5 import java.lang.annotation.RetentionPolicy; 6 import java.lang.annotation.Target; 7 8 @Target(value = {ElementType.METHOD}) 9 @Retention(RetentionPolicy.RUNTIME) 10 @interface Check { 11 }
1 package com.liujinhui.Day1209BaseEnhance.annotation.demo; 2 3 /** 4 * 小明定義的計算器類 5 * 須要測試是否有錯誤 6 */ 7 public class Calculator { 8 //加法 9 @Check 10 public void add(){ 11 System.out.println("1+0="+(1+0)); 12 } 13 //減法 14 @Check 15 public void sub(){ 16 System.out.println("1 - 0 ="+(1 - 0)); 17 } 18 //乘法 19 @Check 20 public void mul(){ 21 System.out.println("1*0="+(1*0)); 22 } 23 //除法 24 @Check 25 public void div(){ 26 System.out.println("1/0="+(1/0)); 27 } 28 //結果 29 public void show(){ 30 System.out.println("永無bug..."); 31 } 32 }
1 package com.liujinhui.Day1209BaseEnhance.annotation.demo; 2 3 import java.io.BufferedWriter; 4 import java.io.FileWriter; 5 import java.io.IOException; 6 import java.lang.reflect.InvocationTargetException; 7 import java.lang.reflect.Method; 8 9 /** 10 * 簡單的測試框架 11 * 當主方法執行後,會自動執行被檢測的全部方法(加了@Check的方法) 12 * 判斷方法是否有異常,並記錄到文件中 13 */ 14 public class TestCheck { 15 public static void main(String[] args) throws IOException { 16 //1.建立計算器對象 17 Calculator c = new Calculator(); 18 //2.獲取字節碼文件對象 19 Class cls = c.getClass(); 20 //3.獲取全部的方法 21 Method[] methods = cls.getMethods(); 22 int number=0;//記錄異常出現的次數 23 BufferedWriter bw=new BufferedWriter(new FileWriter("bug.txt")); 24 for (Method method : methods) { 25 //4.判斷方法上是否有check註解 26 if (method.isAnnotationPresent(Check.class)) { 27 //判斷當前方法上有無指定註解 28 //5.有就執行該方法 29 try { 30 method.invoke(c); 31 } catch (Exception e) { 32 //6.捕獲異常 33 number++; 34 //記錄到文件中 35 bw.write(method.getName() + "方法出異常了"); 36 bw.newLine(); 37 bw.write("異常的名稱:" + e.getCause().getClass().getSimpleName()); 38 bw.newLine(); 39 bw.write("異常的緣由:" + e.getCause().getMessage()); 40 bw.newLine(); 41 bw.write("-----------------------"); 42 } 43 } 44 } 45 bw.write("本次測試共出現"+ number +"次異常"); 46 bw.flush(); 47 bw.close(); 48 } 49 }
2、MySQL基礎
一、概念
二、DB軟件的基本使用
三、SQL語句
3、MySQL約束
一、DQL查詢語句
二、約束
三、數據庫的設計:多表關係
四、數據庫設計範式
五、數據庫的備份還原
4、MySQL多表和事務
一、多表查詢
二、事務
三、DCL
5、JDBC
一、概念:Java Database Connectivity
二、對象詳解
三、JDBC工具類抽取:JDBCUtils
1 package cn.itcast.utils; 2 import java.io.FileReader; 3 import java.io.IOException; 4 import java.net.URL; 5 import java.sql.*; 6 import java.util.Properties; 7 8 /** 9 * JDBC工具類 10 * 一個獲取鏈接的方法 11 * 一個釋放資源的方法 12 */ 13 public class JDBCUtils { 14 private static String url; 15 private static String user; 16 private static String password; 17 private static String driver; 18 /** 19 * 文件的讀取,只須要讀取一次就能夠拿到這些值 20 * 方案:經過靜態代碼塊 21 */ 22 static{ 23 //讀取配置資源文件,獲取值 24 //BufeeredReader。。。麻煩 25 try { 26 //1.建立Properties集合類 27 Properties prop=new Properties(); 28 //2.加載文件,代碼提示 29 //prop.load(new FileReader("src/jdbc.properties")); 30 //找不到資源文件,最笨的方法---能夠寫絕對路徑D:\IdeaProjects\liujinhui\day04_jdbc_20201220\src\jdbc.properties 31 //另外:獲取src路徑下的文件--->ClassLoader 類加載器:能夠 加載字節碼文件進內存,同時能夠獲取src下的資源文件 32 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); 33 //傳的是以src相對的文件路徑 34 //返回統一資源定位符,即文件的絕對路徑 35 URL res= classLoader.getResource("jdbc.properties"); 36 String path = res.getPath(); 37 System.out.println(path); 38 prop.load(new FileReader(path)); 39 //3.獲取數據,賦值 40 url=prop.getProperty("url"); 41 user=prop.getProperty("user"); 42 password=prop.getProperty("password"); 43 driver=prop.getProperty("driver"); 44 //4.註冊驅動 45 Class.forName(driver); 46 } catch (IOException e) { 47 e.printStackTrace(); 48 } catch (ClassNotFoundException e) { 49 e.printStackTrace(); 50 } 51 } 52 //Arrays等都是靜態,方便類直接調用 53 /** 54 * 獲取鏈接的工具方法 55 * @return 鏈接對象 56 */ 57 //String url,String root,String password有參數仍然很麻煩 58 //經過私有變量、配置文件及靜態代碼塊解決 59 public static Connection getConnection() throws SQLException{ 60 return DriverManager.getConnection(url,user,password); 61 } 62 /** 63 * 釋放資源 64 * @param stmt 65 * @param conn 66 */ 67 public static void close(Statement stmt,Connection conn){ 68 if (stmt!=null){ 69 try { 70 stmt.close(); 71 //conn.close();多個語句要放到多個try..catch中 72 } catch (SQLException e) { 73 e.printStackTrace(); 74 } 75 } 76 if (conn!=null){ 77 try { 78 conn.close(); 79 } catch (SQLException e) { 80 e.printStackTrace(); 81 } 82 } 83 } 84 /** 85 * 釋放資源 86 * @param rs 87 * @param stmt 88 * @param conn 89 */ 90 public static void close(ResultSet rs, Statement stmt, Connection conn){ 91 if (stmt!=null){ 92 try { 93 stmt.close(); 94 //conn.close();多個語句要放到多個try..catch中 95 } catch (SQLException e) { 96 e.printStackTrace(); 97 } 98 } 99 if (conn!=null){ 100 try { 101 conn.close(); 102 } catch (SQLException e) { 103 e.printStackTrace(); 104 } 105 } 106 if (rs!=null){ 107 try { 108 rs.close(); 109 } catch (SQLException e) { 110 e.printStackTrace(); 111 } 112 } 113 } 114 }
測試
1 /** 2 * 登陸方法 3 */ 4 public boolean login(String username ,String password){ 5 if (username==null||password==null){ 6 return false; 7 } 8 Connection conn=null; 9 Statement stmt=null; 10 ResultSet rs=null; 11 try { 12 //鏈接數據庫判斷是否登陸成功 13 //1.獲取鏈接,更改數據庫只須要修改配置文件,可擴展性強 14 conn = JDBCUtils.getConnection(); 15 //2.定義 sql 16 String sql="select * from user where username='"+username+"' and password='"+password+"'"; 17 //3.獲取執行SQL的對象 18 stmt = conn.createStatement(); 19 //4.執行查詢 20 rs = stmt.executeQuery(sql); 21 //5.判斷 22 /*if (rs.next()){ 23 return true; 24 }else{ 25 return false; 26 }*/ 27 //直接返回 28 return rs.next(); 29 } catch (SQLException e) { 30 e.printStackTrace(); 31 }finally { 32 JDBCUtils.close(rs,stmt,conn); 33 } 34 return false; 35 } 36 }
四、控制事務
在 catch中回滾事務
package cn.itcast.jdbc; import cn.itcast.utils.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 事務操做 */ public class JDBCDemo11 { public static void main(String[] args) { Connection conn=null; PreparedStatement pstmt1=null; PreparedStatement pstmt2=null; try { //1.獲取鏈接 conn = JDBCUtils.getConnection(); //開啓事務 conn.setAutoCommit(false); //2,定義SQL //2.1 張三-500 //String sql1="update account set balance=balance-500 where id=1"; //2.2 李四+500 //String sql2="update account set balance=balance+500 where id=2"; //通用寫法 String sql1="update account set balance=balance-? where id=?"; String sql2="update account set balance=balance+? where id=?"; //3.獲取執行sql對象 pstmt1 = conn.prepareStatement(sql1); pstmt2= conn.prepareStatement(sql2); //代碼格式化快捷鍵 //4.設置參數 pstmt1.setDouble(1,500); pstmt1.setInt(2,1); pstmt2.setDouble(1,500); pstmt2.setInt(2,2); //5.執行SQL pstmt1.executeUpdate(); //手動製造異常 int i=3/0; pstmt2.executeUpdate(); //提交事務 conn.commit(); //使用大異常 } catch (Exception e) { try { //事務回滾,前提不爲null if (conn!=null){ conn.rollback(); } } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally { JDBCUtils.close(pstmt1,conn); JDBCUtils.close(pstmt2,null); } } }
6、JDBC鏈接池和JDBCTemplate
一、數據庫鏈接池
二、C3P0鏈接池
<c3p0-config> <named-config name="otherc3p0"> <!-- 鏈接參數 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property> <property name="user">root</property> <property name="password">root</property> <!-- 鏈接池參數 --> <property name="initialPoolSize">5</property> <property name="maxPoolSize">8</property> <property name="checkoutTimeout">1000</property> </named-config> </c3p0-config>
三、Druid鏈接池
/** * Druid演示 */ public class DruidDemo { public static void main(String[] args) throws Exception { //1.導入jar包 //2.定義配置文件 //3.加載配置文件 Properties pro=new Properties(); InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties"); pro.load(is); //4.獲取鏈接池對象 DataSource ds = DruidDataSourceFactory.createDataSource(pro); //5.獲取鏈接 Connection conn=ds.getConnection(); System.out.println(conn); } }
package cn.itcast.datasource.utils; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.IOException; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * Druid鏈接池的工具類 */ public class JDBCUtils { //1.定義一個成員變量 DataSource private static DataSource ds; static{ try { //1.加載配置文件 Properties pro=new Properties(); pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties")); //2.獲取DataSource ds = DruidDataSourceFactory.createDataSource(pro); } catch (IOException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } /** * 獲取鏈接 */ public static Connection getConnection() throws SQLException { return ds.getConnection(); } /** * 釋放資源 */ public static void close(Statement stmt,Connection conn){ /*if (stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close();//歸還鏈接 } catch (SQLException e) { e.printStackTrace(); } }*/ //簡化書寫 close(null,stmt,conn); } //方法重載 public static void close(ResultSet rs,Statement stmt, Connection conn){ if (rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close();//歸還鏈接 } catch (SQLException e) { e.printStackTrace(); } } } /** * 獲取鏈接池方法 */ public static DataSource getDataSource(){ return ds; } }
使用鏈接池測試
package cn.itcast.datasource.druid; import cn.itcast.datasource.utils.JDBCUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; /** * 使用新的工具類 */ public class DruidDemo2 { public static void main(String[] args) { /** * 完成添加的操做,給account表添加一條記錄 */ Connection conn=null; PreparedStatement pstmt=null; try { //1.獲取鏈接 conn = JDBCUtils.getConnection(); //2.定義sql String sql="insert into account values(null,?,?)"; //3.獲取pstmt對象 pstmt = conn.prepareStatement(sql); //4.給?賦值 pstmt.setString(1,"王五"); pstmt.setDouble(2,3000); int count = pstmt.executeUpdate(); System.out.println(count); } catch (SQLException e) { e.printStackTrace(); }finally { //6.釋放資源 JDBCUtils.close(pstmt,conn); } } }
四、JDBCTemplate
/** * 查詢全部id爲1的記錄,將其封裝爲map集合 */ @Test public void test4(){ String sql="select * from emp where id=?"; Map<String, Object> map = template.queryForMap(sql, 1001); System.out.println(map); //{id=1001, ename=孫悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20} } /** * 若是有多條記錄 * 注意:此方法queryForMap結果集長度只能爲1 */ @Test public void test5(){ String sql="select * from emp where id= ? or id= ?"; Map<String, Object> map = template.queryForMap(sql, 1001,1002); System.out.println(map); //{id=1001, ename=孫悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20} } /** * 查詢全部記錄,將其封裝爲list集合 */ @Test public void test6(){ String sql="select * from emp"; List<Map<String, Object>> list = template.queryForList(sql); for (Map<String, Object> stringObjectMap : list) { System.out.println(stringObjectMap); } } /** * 查詢全部記錄,將其封裝爲 Emp對象的list集合 */ @Test public void test7(){ String sql="select * from emp"; List<Emp> list = template.query(sql, new RowMapper<Emp>() { @Nullable @Override public Emp mapRow(ResultSet rs, int i) throws SQLException { Emp emp=new Emp(); int id = rs.getInt("id"); String ename = rs.getString("ename"); int job_id = rs.getInt("job_id"); int mgr = rs.getInt("mgr"); Date joindate = rs.getDate("joindate"); double salary = rs.getDouble("salary"); double bonus = rs.getDouble("bonus"); int dept_id = rs.getInt("dept_id"); emp.setId(id); emp.setEname(ename); emp.setJob_id(job_id); emp.setMgr(mgr); emp.setJoindate(joindate); emp.setSalary(salary); emp.setBonus(bonus); emp.setDept_id(dept_id); return emp; } }); for (Emp emp : list) { System.out.println(emp); } } /** * 查詢全部記錄,將其封裝爲 Emp對象的list集合 * template已經提供了實現類 */ @Test public void test8(){ String sql="select * from emp"; List<Emp> list = template.query(sql,new BeanPropertyRowMapper<Emp>(Emp.class)); //提示空值不能轉換爲double,則須要修改javabean爲引用數據類型 for (Emp emp : list) { System.out.println(emp); } } /** * 查詢總的記錄數(count') */@Test public void test9(){ String sql="select count(id) from emp"; Long total = template.queryForObject(sql, Long.class);//用於執行聚合函數 System.out.println(total); } }
7、HTML
一、概述
二、標籤 介紹
8、HTML&CSS
一、表單
二、CSS
9、JavaScript基礎
一、簡介
二、語法
三、對象
10、JavaScript高級
一、入門
二、BOM
三、DOM
四、事件※
11、BootStrap
一、概念
二、響應式佈局
三、案例介紹
12、XML
一、概念
二、約束
三、解析
四、Jsoup
十3、Tomcat&Servlet基礎
一、Web回顧
二、Web服務器軟件
三、Servlet入門
十4、Servlet高級&HTTP&Request
一、Servlet介紹
二、HTTP
三、Request
四、基於BeanUtils的用戶登陸案例
十5、Response
一、Http響應消息
二、Response
三、ServletContext
十6、Cookie&Session
一、會話技術介紹
二、Cookie
三、Session
四、JSP
五、案例:驗證碼判斷
十7、EL&JSTL
一、JSP指令、註釋、內置對象
二、MVC開發模式
三、EL表達式
四、JSTL表達式
五、三層架構
六、案例:用戶信息列表展現
十8、綜合練習
一、界面設計
二、登陸功能
三、添加功能
四、刪除功能
五、修改功能
六、刪除選中
七、分頁查詢
八、複雜條件查詢
十9、Filter&Listener
一、Filter過濾器
二、案例:登陸驗證
三、案例:敏感詞彙
四、Listener監聽器
二10、JQuery基礎
一、 概念
二、選擇器
三、DOM操做
四、案例:隔行變色、表情選擇
二11、JQuery高級
一、動畫
二、遍歷
三、事件綁定
四、案例:廣告的定時顯示與隱藏
二12、Ajax&Json
一、Ajax
二、JSON
三、案例:檢驗用戶名是否存在
二十3、Redis
一、介紹
二、命令操做
三、Redis持久化
四、Jedis操做
五、案例:下拉列表緩存加載省份信息
二十4、Maven基礎
一、介紹
二、具體使用
三、Maven詳細介紹
四、Idea使用Maven
五、基於Maven的Servlet實例
二十5、Web項目旅遊網1
一、項目介紹
二、前臺表單校驗
三、後臺功能:數據庫查詢、郵件激活
四、登陸實現
二十6、Web項目旅遊網2
一、BaseServlet抽取
二、分類數據展現
三、旅遊線路分頁展現
二十7、Web項目旅遊網3
一、旅遊線路名稱查詢
二、旅遊線路詳情展現
二十8、Web項目旅遊網4
一、旅遊線路收藏
二、收藏次數的動態展現
三、補充
二十9、Linux
一、概述
二、安裝
三、經常使用命令
四、其餘功能
三10、Linux&Nginx
一、安裝軟件
二、經常使用軟件的安裝
三、Nginx
四、Nginx靜態網站部署
五、反向代理與負載均衡