day13
一、JSTL標(biāo)簽庫(kù)
1.什么是JSTL
- Apache的東西邻耕,依賴(lài)EL
- 使用JSTL需要導(dǎo)入jstl1.2.jar
2.JSTL標(biāo)簽庫(kù)
- core:核心庫(kù)
- fmt:格式化:日期、數(shù)字
- sql:過(guò)時(shí)
- xml:過(guò)時(shí)
3.使用taglib導(dǎo)入標(biāo)簽庫(kù)
- jar包
- 在jsp頁(yè)面中<%@ taglib prefix="前綴" uri="路徑" %>
4.core標(biāo)簽庫(kù)常用標(biāo)簽
1.out和set
<c:out>:輸出
- value:可以是字符串常量苛坚,也可以是EL表達(dá)式
- default:當(dāng)要輸出的內(nèi)容為null時(shí)际邻,會(huì)輸出default指定的值
- escapeXml:默認(rèn)值為true,表示轉(zhuǎn)義精拟!
<c:set>:設(shè)置(創(chuàng)建域的屬性) - var:變量名
- value:變量值,可以是EL表達(dá)式
- scope:域虱歪,默認(rèn)為page蜂绎,可選值:page、request笋鄙、session师枣、application
2.remove
<remove>:刪除變量 - var:變量名
- scope:如果不給出scope,表示刪除所有域中的該名稱(chēng)的變量萧落;如果指定了域践美,那么刪除該域的變量
3.url
4.if
<c:if test="布爾類(lèi)型">。找岖。陨倡。</c:if>,當(dāng)test為真是许布,執(zhí)行標(biāo)簽體內(nèi)容兴革!
5.choose
6.forEach
5.fmt標(biāo)簽庫(kù)常用標(biāo)簽
二、自定義標(biāo)簽
其中doTag()會(huì)在其他三個(gè)方法之后被tomcat調(diào)用
三蜜唾、MVC設(shè)計(jì)模式
他不是java獨(dú)有杂曲,所有的B/S結(jié)構(gòu)的項(xiàng)目都在使用它!
M:model 模型(自己寫(xiě)代碼)
V:view 試圖(jsp)
C:cotroller 控制器(servlet)
=====================================================================================================================================================================================================================
一袁余、servlet
1.概念
2.servlet執(zhí)行原理
二擎勘、AJAX
1.概念:ASynchronous JavaScript And XML 異步的JavaScript和XML
2.實(shí)現(xiàn)方式
(1)原生的JS實(shí)現(xiàn)方式(了解)
(2)JQeury實(shí)現(xiàn)方式
- $.ajax()
- $.get()
- $.post()
三、JDBC
1.概念:Java DataBase Connectivity Java數(shù)據(jù)庫(kù)連接泌霍;Java語(yǔ)言操作數(shù)據(jù)庫(kù)
- JDBC本質(zhì):其實(shí)是官方(sun公司)定義的一套操作所有關(guān)系型數(shù)據(jù)庫(kù)的規(guī)則货抄,即接口述召。各個(gè)數(shù)據(jù)庫(kù)廠商去實(shí)現(xiàn)這套接口,提供數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar包蟹地。我們可以使用這套接口(JDBC)編程积暖,真正執(zhí)行的代碼是驅(qū)動(dòng)jar包中的實(shí)現(xiàn)類(lèi)。
2.快速入門(mén):
步驟:
1.導(dǎo)入驅(qū)動(dòng)jar包
2.注冊(cè)驅(qū)動(dòng)
3.獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection
4.定義sql
5.獲取執(zhí)行sql語(yǔ)句的對(duì)象 Statement
6.執(zhí)行sql怪与,接受返回結(jié)果
7.處理結(jié)果
8.釋放資源
//1.導(dǎo)入驅(qū)動(dòng)包
//mysql-connector-java-8.0.16.jar
//2.注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver");
//3.獲取數(shù)據(jù)庫(kù)連接對(duì)象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mwj?
serverTimezone=UTC", "root", "1234");
//4.定義sql語(yǔ)句
String sql = "update mwj1 set age = '17' where name = '123'";
//5.獲取執(zhí)行sql的對(duì)象Statement
Statement stmt = conn.createStatement();
//6.執(zhí)行sql
int count = stmt.executeUpdate(sql);
//7.處理結(jié)果
System.out.println(count);
//8.釋放資源
stmt.close();
conn.close();
3.詳解各個(gè)對(duì)象:
1.DriverManager:驅(qū)動(dòng)管理對(duì)象
功能:
(1)注冊(cè)驅(qū)動(dòng):告訴程序改使用哪一個(gè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)jar
注意:mysql5之后的驅(qū)動(dòng)jar包可以省略注冊(cè)驅(qū)動(dòng)的步驟夺刑。
(2)獲取數(shù)據(jù)庫(kù)連接
- 方法:static Connection getConnection(String url,String user,String password)
- 參數(shù):
(1)url:指定連接的路徑
語(yǔ)法:jdbc:mysql://ip地址(域名):端口號(hào)/數(shù)據(jù)庫(kù)名稱(chēng)
例子:jdbc:mysql://localhost:3306/mwj
細(xì)節(jié):如果連接的是本機(jī)mysql服務(wù)器,并且mysql服務(wù)默認(rèn)端口是3306分别,則url可簡(jiǎn)寫(xiě)為:jdbc:mysql:///數(shù)據(jù)庫(kù)名稱(chēng)
(2)user:用戶(hù)名
(3)password:密碼
2.Connection:數(shù)據(jù)庫(kù)連接對(duì)象 - 功能:
(1)獲取執(zhí)行sql的對(duì)象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
(2)管理事務(wù):
開(kāi)啟事務(wù):serAutoCommit(boolean autoCommit):調(diào)用該方法設(shè)置參數(shù)為false遍愿,即開(kāi)啟事務(wù)
提交事務(wù):commit()
回滾事務(wù):rollback()
3.Statement:執(zhí)行sql的對(duì)象
(1)執(zhí)行sql - boolean execute(String sql):可以執(zhí)行任意的sql
- int executeUpdate(String sql):執(zhí)行DML(insert、uodate耘斩、delete)語(yǔ)句沼填、 DDL(create,alter,drop)語(yǔ)句
返回值:影響的行數(shù),可以通過(guò)這個(gè)影響的行數(shù)判斷DML語(yǔ)句是否執(zhí)行成功 括授; 返回值>0的則執(zhí)行成功坞笙,反之,則失敗 - ResultSet executeQuery(String sql):執(zhí)行DQL(select)語(yǔ)句
(2)練習(xí):
//向mwj表添加一條數(shù)據(jù)
public class JdbcDemo2 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try {
//1.注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver");
//2.定義sql
String sql = "insert into mwj1 values('苗文杰',20)";
//3.獲取Connection對(duì)象
conn = DriverManager.getConnection("jdbc:mysql:///mwj?
serverTimezone=UTC", "root", "1234");
//4.獲取執(zhí)行sql的對(duì)象Statement
stmt = conn.createStatement();
//5.執(zhí)行sql
int count = stmt.executeUpdate(sql);//影響的行數(shù)
//6.處理結(jié)果
System.out.println(count);
if(count>0){
System.out.println("添加成功");
}
else {
System.out.println("添加失敗");
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
//7.釋放資源
//避免空指針
if (stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if( conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
4.ResultSet:結(jié)果集對(duì)象荚虚,封裝查詢(xún)結(jié)果
- next():游標(biāo)向下移動(dòng)一行
- getXxx(參數(shù)):獲取數(shù)據(jù)
(1)int:代表列的編號(hào)薛夜,從1開(kāi)始 如:getString(1)
(2)String:代表列名稱(chēng)。 如:getDouble("balance")
使用步驟:
1.游標(biāo)向下移動(dòng)一行
2.判斷是否有數(shù)據(jù)
3.獲取數(shù)據(jù)
循環(huán)判斷游標(biāo)是否是最后一行末尾
while (rs.next()){
//循環(huán)判斷結(jié)果集是否有下一行
//獲取數(shù)據(jù)
int name = rs.getInt(1);
String age = rs.getNString("age");
System.out.println(name + "----" + age);
}
練習(xí):
定義一個(gè)方法版述,查詢(xún)o_classes表的數(shù)據(jù)將其封裝為對(duì)象梯澜,然后裝載集合,返回渴析。
1.定義Emp類(lèi)
2.定義方法public List<Emp> findAll(){}
3.實(shí)現(xiàn)方法select * from emp;
public class JdbcDeom6 {
public static void main(String[] args) {
List<Emp> list = new JdbcDeom6().findAll();
System.out.println(list);
System.out.println(list.size());
}
/*
* 查詢(xún)所有emp對(duì)象
* */
public List<Emp> findAll(){
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
List<Emp> list = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql:///oj?
serverTimezone=UTC", "root", "1234");
String sql = "select * from o_classes";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//遍歷結(jié)果集晚伙,封裝對(duì)象,裝載集合
Emp emp = null;
list = new ArrayList<Emp>();
while (rs.next()){
//獲取數(shù)據(jù)
int id = rs.getInt("id");
String name = rs.getString("name");
String teacher_id = rs.getString("teacher_id");
String code = rs.getString("code");
Date code_end_time = rs.getDate("code_end_time");
Date time = rs.getDate("time");
//創(chuàng)建emp對(duì)象并賦值
emp = new Emp();
emp.setId(id);
emp.setName(name);
emp.setTeacher_id(teacher_id);
emp.setCode(code);
emp.setCode_end_time(code_end_time);
emp.setDate(time);
//裝載集合
list.add(emp);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
finally {
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();
}
}
}
return list;
}
}
5.PreparedStatement:執(zhí)行sql的對(duì)象
1.SQL注入問(wèn)題:在拼接sql時(shí)檬某,有一些sql的特殊關(guān)鍵字參與字符串的拼接撬腾。會(huì)造成安全性問(wèn)題
2.解決sql注入問(wèn)題:使用PreparedStatement對(duì)象來(lái)解決
3.預(yù)編譯的sql:參數(shù)使用?作為占位符
4.步驟:
(1).導(dǎo)入驅(qū)動(dòng)jar包
(2).注冊(cè)驅(qū)動(dòng)
(3).獲取數(shù)據(jù)庫(kù)連接對(duì)象 Connection
(4).定義sql
注意:sql的參數(shù)使用恢恼?作為占位符。如:select * from user where username= ? and password = ?;
(5).獲取執(zhí)行sql語(yǔ)句的對(duì)象 PreparedStatement Connection.prepareStatement(String sql)
(6).給胰默?賦值:
方法:setXxx(參數(shù)1场斑,參數(shù)2)
參數(shù)1:?的位置編號(hào)從1開(kāi)始
參數(shù)2:牵署?的值
(7).執(zhí)行sql漏隐,接受返回結(jié)果
(8).處理結(jié)果
(9).釋放資源
5.注意:后期都會(huì)使用PreparedStatement來(lái)完成增刪改差的所有操作
抽取JDBC工具類(lèi):JdbcUtils
目的:簡(jiǎn)化書(shū)寫(xiě)
分析:
1.注冊(cè)驅(qū)動(dòng)也抽取
2.抽取一個(gè)方法獲取連接對(duì)象
- 需求:不想傳遞參數(shù)(麻煩),還得保證工具類(lèi)的通用性奴迅。
- 解決:配置文件
jdbc.Properties
url=jdbc:mysql:///oj?serverTimezone=UTC
user=root
password=1234
driver= com.mysql.cj.jdbc.Driver
3.抽取一個(gè)方法釋放資源
//jdbc.Properties
url=jdbc:mysql:///oj?serverTimezone=UTC
user=root
password=1234
driver= com.mysql.cj.jdbc.Driver
//JdbcUtils
public class JdbcUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/*
* 文件的讀取青责,只需要讀取一次即可拿到這些值使用靜態(tài)代碼塊
* */
static {
try {
//讀取資源文件挺据,獲取值
//1.創(chuàng)建Properties集合類(lèi)
Properties pro = new Properties();
//獲取src路徑下文件的方式 ClassLoader 類(lèi)加載器
ClassLoader classLoader = JdbcUtils.class.getClassLoader();
URL res = ClassLoader.getSystemResource("jdbc.Properties");
String path = res.getPath();
System.out.println(path);
//2.加載文件
// pro.load(new FileReader("src/jdbc.Properties"));
pro.load(new FileReader(path));
//3.獲取數(shù)據(jù),賦值
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//4.注冊(cè)驅(qū)動(dòng)
Class.forName(driver);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
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();
}
}
}
public static void close(ResultSet rs,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();
}
}if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
//JdbcDemo6
public class JdbcDeom6 {
public static void main(String[] args) {
List<Emp> list = new JdbcDeom6().findAll2();
System.out.println(list);
System.out.println(list.size());
}
public List<Emp> findAll2() {
Statement stmt = null;
ResultSet rs = null;
Connection conn = null;
List<Emp> list = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from o_classes";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//遍歷結(jié)果集脖隶,封裝對(duì)象扁耐,裝載集合
Emp emp = null;
list = new ArrayList<Emp>();
while (rs.next()) {
//獲取數(shù)據(jù)
int id = rs.getInt("id");
String name = rs.getString("name");
String teacher_id = rs.getString("teacher_id");
String code = rs.getString("code");
Date code_end_time = rs.getDate("code_end_time");
Date time = rs.getDate("time");
//創(chuàng)建emp對(duì)象并賦值
emp = new Emp();
emp.setId(id);
emp.setName(name);
emp.setTeacher_id(teacher_id);
emp.setCode(code);
emp.setCode_end_time(code_end_time);
emp.setDate(time);
//裝載集合
list.add(emp);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcUtils.close(rs,stmt,conn);
}
return list;
}
}
練習(xí):
需求:
1.通過(guò)鍵盤(pán)錄入用戶(hù)名和密碼
2.判斷用戶(hù)是否登錄成功
- select * from user where username=' "+username+" ' and password=' "+password+" ' "
- 如果這個(gè)sql有查詢(xún)結(jié)果,則成功产阱,反之婉称,則失敗
步驟:
1創(chuàng)建數(shù)據(jù)庫(kù)表 user
CREATE TABLE USER(
id int PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(32),
PASSWORD VARCHAR(32)
);
SELECT * FROM USER;
INSERT INTO USER VALUES(NULL,'zhangsan','123');
INSERT INTO USER VALUES(NULL,'lisi','345');
public class JdbcDemo7 {
public static void main(String[] args) {
//1.鍵盤(pán)錄入,輸入用戶(hù)名和密碼
Scanner sc = new Scanner(System.in);
System.out.println("請(qǐng)輸入用戶(hù)名");
String username = sc.nextLine();
System.out.println("請(qǐng)輸入密碼");
String password = sc.nextLine();
//2.調(diào)用方法
boolean flag = new JdbcDemo7().login(username, password);
//3.判斷結(jié)果构蹬。輸出不同語(yǔ)句
if(flag){
System.out.println("登錄成功");
}else {
System.out.println("用戶(hù)名或密碼錯(cuò)誤王暗!");
}
}
/*
* 登錄方法
* */
public boolean login(String username,String password){
if(username == null || password == null){
return false;
}
//連接數(shù)據(jù)庫(kù)判斷是否登錄成功
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
conn = JdbcUtils.getConnection();
String sql = "select * from user where username='"+username+"' and
password='"+password+"'";
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
//判斷
return rs.next();//如果有下一行,則返回true
} catch (SQLException e) {
e.printStackTrace();
}
finally {
JdbcUtils.close(rs,stmt,conn);
}
return false;
}
}
JDBC控制事務(wù)
1.事務(wù):一個(gè)包含多個(gè)步驟的業(yè)務(wù)操作庄敛。如果這個(gè)業(yè)務(wù)操作被事務(wù)管理俗壹,則著多個(gè)步驟要么同時(shí)成功,要么同時(shí)失敗藻烤。
2.操作:
(1)開(kāi)啟事務(wù)
(2)提交事務(wù)
(3)回滾事務(wù)
3.使用Connection對(duì)象來(lái)管理事務(wù)
- 開(kāi)啟事務(wù):setAutoCommit(boolean autoCommit):調(diào)用該方法設(shè)置參數(shù)為false绷雏,即開(kāi)啟事務(wù)
在執(zhí)行sql之前開(kāi)啟事務(wù)
- 提交事務(wù):commit()
當(dāng)所有sql都執(zhí)行完提交事務(wù)
- 回滾事務(wù):rollback()
在catch中回滾事務(wù)