MySQL 相關(guān)
1. 什么是JDBC? 優(yōu)勢? 功能?
JDBC (Java Database Connectivity) 是Java數(shù)據(jù)庫連接的意思, 是用來執(zhí)行SQL語句的 JAVA API
優(yōu)勢是跨平臺, 跨應(yīng)用; 實(shí)現(xiàn)同一種API訪問不同平臺不同數(shù)據(jù)庫系統(tǒng)
功能就是連接數(shù)據(jù)庫, 執(zhí)行SQL語句
2. JDBC 驅(qū)動(dòng)程序是什么? 幾種? 使用哪一種?
數(shù)據(jù)庫驅(qū)動(dòng)程序就是JDBC和數(shù)據(jù)庫之間的轉(zhuǎn)換層, 將JDBC調(diào)用映射成數(shù)據(jù)庫調(diào)用
有 JDBC-ODBC, 直接將JDBC API 映射成數(shù)據(jù)庫特定的客戶端 API, 支持三層結(jié)構(gòu)的 JDBC 訪問方式, 純JAVA直接與客戶端交互4種
正常使用
第四種
3. Win 10 安裝MySQL步驟?
下載MySQL安裝壓縮包
下載 vcredist_x86.exe 并安裝
在MySQL安裝包目錄新建 my.ini 并正確編寫
將 MySQL 添加到環(huán)境變量并在 path 種添加MySQL環(huán)境變量
CMD 執(zhí)行 mysqld -install 獲取密碼并更改密碼
重啟MySQL服務(wù) service MySQL restart
4. DBMS? MySQL數(shù)據(jù)庫類型? MySQL引擎?
DBMS 是 Database management System 數(shù)據(jù)庫管理系統(tǒng)的簡稱
MySQL 數(shù)據(jù)關(guān)系型數(shù)據(jù)庫, 所使用的引擎是 InnoDB
5. 標(biāo)準(zhǔn)SQL語句的類型?
查詢語句: 由 select 關(guān)鍵字完成
DML(Data Manipulation Language) 數(shù)據(jù)操作語言: 主要由 insert, update, delete 關(guān)鍵字完成
DDL(Data Definition Language) 數(shù)據(jù)定義語言: 主要由 create, alter, drop, truncate 關(guān)鍵字完成
DCL(Data Control Language) 數(shù)據(jù)控制語言: 主要由 grant(授予), revoke(撤銷) 關(guān)鍵字完成
事務(wù)控制語句: 主要由 commit, rollback, savepoint 關(guān)鍵字組成
6. 創(chuàng)建數(shù)據(jù)庫?
CREATE DATABASE test CHARSET=UTF8;
7. 創(chuàng)建表語法?
CREATE TABLE test_img (
id int(10) not null PRIMARY KEY AUTO_INCREMENT,
title varchar(20) not null,
post_date datetime,
photo mediumblob
);
8. 子查詢建表?
CREATE TABLE new_test_img
as
SELECT * FROM test_img;
9. 增加/修改表結(jié)構(gòu)?
ALTER TABLE test
ADD (
test_date date default '2019-12-31'
);
ALTER TABLE test
MODIFY name varchar(30) not null;
10. 刪除數(shù)據(jù)表某一列語法?
ALTER TABLE test
drop word;
11. 重命名數(shù)據(jù)表?
ALTER TABLE test
RENAME TO user;
12. 重命名數(shù)據(jù)表中的某列?
ALTER TABLE user
CHANGE test_date age DATE NOT NULL DEFAULT '1990-01-01';
13. 刪除數(shù)據(jù)庫語法?
DROP TABLE new_user;
14. 刪除數(shù)據(jù)表數(shù)據(jù), 保留語法結(jié)構(gòu)?
TRUNCATE user;
15. NOT NULL 只能作為列級約束例子?
CREATE TABLE category (
id INT NOT NULL AUTO_INSCREMENT PRIMARY KEY,
category varchar(50) NOT NULL);
16. UNIQUE 唯一約束, 表級, 列級語法?
-- 列級唯一約束
CREATE TABLE user1 (
id INT(10) NOT NULL UNIQUE,
username varchar(50) NOT NULL DEFAULT 'admin'
);
-- 表級唯一約束
CREATE TABLE user2 (
id INT(10) NOT NULL,
username varchar(50) NOT NULL DEFAULT 'admin',
-- 表級約束
UNIQUE (id));
-- 表級唯一約束, 且指定約束名
CREATE TABLE user3 (
id INT(10) NOT NULL,
username varchar(50) NOT NULL DEFAULT 'admin',
CONSTRAINT user3_unique UNIQUE (id, username)
);
17. 刪除, 修改唯一約束?
-- 修改唯一約束
ALTER TABLE user3
MODIFY id INT(10) NOT NULL UNIQUE;
-- 刪除約束
-- 可以通過 SHOW CREAE TABLE user3; 語句來查看唯一約束的約束名
ALTER TABLE user3
DROP INDEX user3_unique;
18. PRIMARY KEY 主鍵約束是什么?
主鍵約束相當(dāng)于非空約束和唯一約束的組合, 每張表只能有一個(gè)主鍵約束
主鍵約束有表級以及列級約束之分, 也可以指定組合作為主鍵約束
19. 列級主鍵約束, 表級主鍵約束?
-- 列級約束
CREATE TABLE test1 (
id INT(10) PRIMARY KEY AUTO_INCREMENT,
test_name VARCHAR(50) NOT NULL
);
-- 表級約束
CREATE TABLE test2 (
id INT(10) AUTO_INCREMENT,
test_name VARCHAR(50),
CONSTRAINT test_pk PRIMARY KEY(id)
);
20. 刪除主鍵約束?
ALTER TABLE test2
DROP PRIMARY KEY;
21. 什么是外鍵約束 FOREIGN KEY?
外鍵約束是一種參照關(guān)系, 即一張表的兩個(gè)字段或兩張表的兩個(gè)字段之間的參照關(guān)系
參照關(guān)系: 子表外鍵列的值必須在主表被參照列的值范圍之內(nèi), 或者為空
從表外鍵參照的只能是主表主鍵列或者唯一列, 同一表可以有多個(gè)外鍵
22. 創(chuàng)建外鍵約束的例子?
-- 例子1: 實(shí)例 建立blog數(shù)據(jù)庫
create database blog charset=utf8;
-- 建立 User 表
-- 如果想刪除主表(user)記錄時(shí), 從表(blog)記錄也會(huì)隨之刪除, 則需要在建立外鍵約束后添加 on delete cascade
-- 或者添加 on delete set null (第一種:主表刪除后,從表記錄也全部級聯(lián)刪除; 第二種: 主表刪除后, 參照該主表
-- 記錄的外鍵設(shè)為null)
create table user (
user_id int not null primary key auto_increment,
user_name varchar(255) not null unique,
create_date datetime not null,
is_admin boolean defaule false
);
--
-- 建立 category 表
create table category (
category_id int not null auto_increment primary key,
category_name varchar(255) not null unique
);
--
-- 建立 blog 主表 使用表級約束語法
create table blog (
title varchar(255) not null,
blog_user varchar(255),
blog_category varchar(255),
blog_body text,
-- 表級約束
foreign key (blog_user) references user(user_name) on delete cascade,
foreign key (blog_category) references category(category_name) on delete set null
);
23. 索引是什么? 自動(dòng)創(chuàng)建索引? 手動(dòng)創(chuàng)建索引?
索引是存放在模式(schema)中的一個(gè)數(shù)據(jù)庫對象, 作用是加速對表的查詢
自動(dòng)創(chuàng)建索引: 當(dāng)定義了唯一約束, 主鍵約束, 外鍵約束時(shí), 系統(tǒng)自動(dòng)為該數(shù)據(jù)列創(chuàng)建對應(yīng)的索引
手動(dòng)創(chuàng)建索引: 通過 create index 語法來手動(dòng)創(chuàng)建索引
24. 創(chuàng)建索引, 刪除索引?
-- 創(chuàng)建單獨(dú)列的索引
create index emp_last_name_idx
on employees(last_name);
--
-- 同時(shí)對多列創(chuàng)建索引
create index emp_last_name_idx2
on employees(first_name, last_name);
--
-- 刪除索引
drop index emp_last_name_idx2
on employees;
25. 什么是視圖?
- 視圖是一個(gè)或多個(gè)數(shù)據(jù)表中數(shù)據(jù)的邏輯顯示, 視圖不存儲(chǔ)數(shù)據(jù), 也不是數(shù)據(jù)表
26. 創(chuàng)建刪除視圖?
-- 創(chuàng)建一個(gè)視圖
create view blog_all
as
select * from blog;
--
-- 刪除上面創(chuàng)建的視圖名
drop view blog_all;
27. insert into 數(shù)據(jù)表插入語句?
-- 同時(shí)插入多條語句
insert into user values
(0, 'python', '2018-08-08'),
(0, 'java', '2019-09-01'),
(0, 'CSS', '2019-05-01');
28. update 語句修改表?
- update 語句用于修改表數(shù)據(jù), 可一次修改一條或多條或多列記錄, 可以通過 WHERE 來限定修改那些記錄
-- 語法
update table_name
set column1 = value1[, column2 = value2]...
[WHERE condition];
-- 例子
update user
set name = 'Java' where id = 2;
29. delete from 語句刪除指定表的記錄?
- delete from 語句用于刪除指定數(shù)據(jù)表的記錄, delete from 總是整行刪除記錄, 也可以通過 WHERE 來限定刪除條件
-- 語法:
delete from table_name
[WHERE condition];
--
-- 例子:
-- 刪除student_table2表中的全部記錄
delete from student_table2;
-- 通過 where 來限定刪除條件
delete from student_table2
where teacher_id > 2;
JDBC 相關(guān)
1. 簡述 JDBC4.2 常用接口和類---DriverManger類?
DriverManager 類主要是用于管理JDBC驅(qū)動(dòng)的服務(wù)類, 主要功能就是獲取 Connection 對象
用法:
Connection conn = DriverManager.getConnection(String url, String user, String password)
2. 簡述 JDBC4.2 常用接口和類---Connection接口及接口的主要方法?
Connection 代表了數(shù)據(jù)庫的連接對象, 每個(gè)Connection代表一個(gè)物理連接會(huì)話, 想訪問數(shù)據(jù)庫, 必須先獲得數(shù)據(jù)庫連接
-
Connection 常用的方法:
Statement createStatement() throws SQLException()
; 獲得一個(gè)Statement對象PreparedStasement preparedStatement(String sql) throws SQLException
獲得一個(gè)預(yù)編譯的 PreparedStasement 對象, 可以傳入帶有參數(shù)的SQL語句CallableStatement prepareCall(String sql) throws SQLException
返回 CallableStatement 對象
3. 簡述 Statement 接口?
用于執(zhí)行SQL語句的工具接口, 該對象可執(zhí)行DDL, DCL, DML 以及 SQL查詢語句, 執(zhí)行SQL查詢語句時(shí)返回查詢到的結(jié)果集
-
Statement 常用方法:
ResultSet executeQuery(String sql) throws SQLException
; 用于執(zhí)行查詢語句, 并返回查詢結(jié)果對應(yīng)的 ResultSet 對象, 該方法只能用于執(zhí)行查詢語句int executeUpdate(String sql) throws SQLException
; 該方法用于執(zhí)行DML語句, 并返回執(zhí)行后受影響的行數(shù); 也可用于執(zhí)行DDL語句, 執(zhí)行DDL語句返回0boolean execute(String sql) throws SQLException
; 該方法可執(zhí)行任何SQL語句, 如果執(zhí)行后的第一個(gè)結(jié)果為 ResultSet 對象, 則返回 true; 如果執(zhí)行后第一個(gè)結(jié)果為受影響的行數(shù)或沒有任何結(jié)果, 則返回falseexecuteLargeUpdate()
4. 簡述 PreparedStatement 接口?
預(yù)編譯的 Statement 對象, 它允許數(shù)據(jù)庫預(yù)編譯SQL語句(這些SQL語句通常都帶有參數(shù)), 以后每次只改變SQL命令參數(shù), 避免數(shù)據(jù)庫每次都要編譯SQL語句
PreparedStatement 同樣有 executeUpdate(), executeQuery() 以及
5. 簡述 ResultSet 結(jié)果集?
ResultSet 結(jié)果集是 Statement 接口的查詢方法 executeQuery(String sql) 以及 execute(String sql) 查詢語句執(zhí)行后的返回對象; 該對象包含執(zhí)行查詢語句的結(jié)果, ResultSet 可以通過列索引或列名獲得列數(shù)據(jù)
當(dāng)通過移動(dòng)指針到指定行之后, ResultSet 可通過 getXxx(int columnIndex) 或 getXxx(String columnLabel) 方法來獲取當(dāng)前行, 指定列的值, 前者根據(jù)索引來獲取值, 后者通過列名來獲取值
-
移動(dòng)指針的方法:
boolean absolute(int row)
將結(jié)果集的記錄指針移動(dòng)到第row行, 如果 row 為負(fù)數(shù), 則移動(dòng)到倒數(shù)第 row 行void beforeFirst()
定位到第一行之前void afterLast()
定位到最后一行之后boolean previous()
定位到前一行boolean next()
定位到后一行boolean first()
定位到行首boolean last()
定位到行尾
6. 簡述 JDBC 編程步驟(以MySQL為例)?
-
第一步: 通過 Class.forName(dirverclass) 靜態(tài)方法來加載數(shù)據(jù)庫驅(qū)動(dòng)
Class.forName("com.mysql.cj.jdbc.Driver")
; -
第二步: 通過 DriverManager.getConnection(url, user, password) 方法獲取數(shù)據(jù)庫連接
String url = "jdbc:mysql://localhost:3306/blog?useSSL=false&serverTimezone=UTC"
;
String user = "root"
;
String password = "password"
;
Connection conn = DriverManager.getConnection(url, user, password)
; -
第三步: 通過Connection對象創(chuàng)建 Statement 對象
Statement stmt = conn.createStatement()
; 創(chuàng)建基本的Statement對象
PreparedStatement pstmt = conn.PreparedStatement(Sql)
; 創(chuàng)建預(yù)編譯的 PreparedStatement 對象 -
第四步: 通過 Statement 或 PreparedStatement 對象調(diào)用 execute() 或 executeUpdate() 或 executeQuery() 方法執(zhí)行SQL語句
stmt.execute()
可執(zhí)行任何SQL語句, 但是比較麻煩
stmt.executeUpdate()
執(zhí)行DML(返回int類型的受影響的行數(shù)),DDL語句(返回int類型的0)
stmt.exeuteQuery()
只能執(zhí)行查詢語句, 返回的是 ResultSet 類型的結(jié)果集 -
第五步: 操作 ResultSet 結(jié)果集
next(), previous(), first(), last(), beforeFirst(), afterLast()
這些事移動(dòng)指針的方法
getString(), getInt()
這些是獲取移動(dòng)到指定行列的數(shù)據(jù)的方法 -
第六步: 反向關(guān)閉資源
反向關(guān)閉 ResultSet, Statement, Connection 等資源
7. 使用 JDBC 進(jìn)行MySQL數(shù)據(jù)庫增刪改查的例子?
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* JDBCUtil.java
* 用來獲取 Connection 類型的數(shù)據(jù)庫連接
*/
public class JDBCUtil {
final static String driver = "com.mysql.cj.jdbc.Driver";
final static String url = "jdbc:mysql://localhost:3306/blog?useSSL=false&serverTimezone=UTC";
final static String user = "root";
final static String password = "password";
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
System.out.println("數(shù)據(jù)庫驅(qū)動(dòng)加載失敗");
e.printStackTrace();
}
}
public static Connection getConn() throws SQLException{
return DriverManager.getConnection(url, user, password);
}
public static void closeConn(Connection conn) {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
System.out.println("Connection close failed!");
e.printStackTrace();
}
}
}
}
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSetMetaData;
public class CRUDUtil {
/**
* MySQL數(shù)據(jù)庫CRUD
* 執(zhí)行 DML 或 DDL 語句
*/
public static void exeuteDDLOrDDM(String sql) throws Exception {
try (
Connection conn = JDBCUtil.getConn();
Statement stmt = conn.createStatement()) {
int result = stmt.executeUpdate(sql);
if (result != 0) {
System.out.println("執(zhí)行DML語句后, 有[" + result + "]條記錄受影響" + "\n");
} else {
System.out.println("已執(zhí)行DDL語句, 并成功返回[" + result + "]" + "\n");
}
}
}
/**
* MySQL數(shù)據(jù)庫CRUD
* 執(zhí)行 查詢 語句
*/
public static void executeSelect(String sql) throws Exception {
try (
Connection conn = JDBCUtil.getConn();
Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getString(1) + "\t"
+ rs.getString(2) + "\t"
+ rs.getString(3) + "\t");
}
}
}
/**
* MySQL數(shù)據(jù)庫CRUD
* 可執(zhí)行 任何 SQL語句
*/
public static void executeSQL(String sql) throws SQLException {
try (
Connection conn = JDBCUtil.getConn();
Statement stmt = conn.createStatement()) {
boolean hasResultSet = stmt.execute(sql);
if (hasResultSet) {
try (
ResultSet rs = stmt.getResultSet()) {
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()) {
for (int i = 0; i < columnCount; i++) {
System.out.print(rs.getString(i + 1) + "\t");
}
System.out.print("\n");
}
}
} else {
System.out.println("該SQL語句影響的記錄有["
+ stmt.getUpdateCount() + "]條");
}
}
}
}
public class JDBCDemo {
/**
* MySQL SQL語句類型:
* DML : insert, update, delete
* DDL : create, alter, drop, truncate
* DCL : grant, revoke
* 查詢語句 : select
*
* Statement用于執(zhí)行SQL語句的方法:
* ResultSet executeQuary(String sql)方法只能執(zhí)行查詢語句
* int executeUpdate(String sql) 方法可執(zhí)行DML或DDL語句
* boolean execute(String sql) 可執(zhí)行任何SQL語句
*/
// DDL
static String sql1 = "create table demo "
+ "(d_id int primary key auto_increment,"
+ "d_name varchar(255),"
+ "d_body text);";
static String sql8 = "truncate demo";
static String sql9 = "alter table demo add photo mediumblob";
// DML
static String sql2 = "insert into demo values(0,'jeff','desc jeff .....',null)";
static String sql3 = "insert into demo values(0,'cony','desc cony .....',null)";
static String sql4 = "insert into demo values(0,'hurry','desc hurry .....',null)";
// select
static String sql5 = "select * from demo";
static String sql10 = "desc demo";
// DML
static String sql6 = "update demo set d_name='JULIA', d_body='desc julia.....' where d_id=4";
static String sql7 = "delete from demo where d_id=4";
public static void main(String[] args) throws Exception {
// CRUDUtil.exeuteDDLOrDDM(sql9);
// CRUDUtil.executeSelect(sql5);
CRUDUtil.executeSQL(sql5);
}
}
8. 離線 RowSet 接口簡述?
RowSet 接口繼承了 ResultSet 接口, RowSet 接口包含了 JdbcRowSet, CachedRowSet, FilteredRowSet, JoinRowSet 和 WebRowSet 常用子接口; 其中 JdbcRowSet需要保持與數(shù)據(jù)庫的連接之外, 其余4個(gè)子接口都是離線的RowSet, 無須保持與數(shù)據(jù)庫的連接
離線 RowSet 會(huì)直接將底層數(shù)據(jù)讀入內(nèi)存中, 封裝成 RowSet 對象, 而 RowSet 對象則完全可以當(dāng)成 java Bean 來使用
對離線的 RowSet, 程序在創(chuàng)建 RowSet 時(shí)已把數(shù)據(jù)從底層數(shù)據(jù)庫加載到內(nèi)存,從而降低數(shù)據(jù)庫服務(wù)器的負(fù)載, 提高性能
CachedRowSet 是所有離線 RowSet 的父接口
9. RowSet 接口常用方法?
setUrl(String url)
設(shè)置該RowSet要訪問的數(shù)據(jù)庫的RULsetUserName(String Name)
設(shè)置該RowSet要訪問的數(shù)據(jù)庫的用戶名setPassword(String password)
設(shè)置該RowSet要訪問的數(shù)據(jù)庫的密碼setCommand(String sql)
設(shè)置使用該sql語句的查詢結(jié)果來裝填該RowSetexecute()
執(zhí)行查詢語句populate(ResultSet rs)
讓該RowSet直接包裝給定的ResultSet對象
10. RowSetProvider 類 和 RowSetFactory 接口?
Java 7 新增了 RowSetProvider類 和 RowSetFactory 接口, 其中 RowSetProvider 負(fù)責(zé)創(chuàng)建 RowSetFactory,而 RowSetFactory 通過方法創(chuàng)建 RowSet 實(shí)例, 這樣就把應(yīng)用程序與RowSet實(shí)現(xiàn)類分離開
-
方法:
- RowSetFactory factory = RowSetProvider.newFactory();
11. RowSetFactory 提供的創(chuàng)建 RowSet 實(shí)例的方法?
CachedRowSet createCachedRowSet()
創(chuàng)建一個(gè)默認(rèn)的 CachedRowSetFilteredRowSet createFilteredRowSet()
創(chuàng)建一個(gè)默認(rèn)的 FilteredRowSedbcRowSet createJdbcRowSet()
創(chuàng)建一個(gè)默認(rèn)的 JdbcRowSet 不支持離線JoinRowSet createJoinRowSet()
創(chuàng)建一個(gè)默認(rèn)的 JoinRowSetWebRowSet createWebRowSet()
創(chuàng)建一個(gè)默認(rèn)的 WebRowSet
12. 裝填 RowSet 兩種方法?
第一種: 通過Statement對象執(zhí)行 executeQuery() 方法返回 ResultSet 對象; 調(diào)用RowSet實(shí)例的 populate(ResultSet rs) 方法, 并將上述的ResultSet 對象傳入其中進(jìn)行裝填
第二種: 通過 RowSet實(shí)例的 setCommand(sql) 和 execute() 方法執(zhí)行SQL查詢, 用返回的數(shù)據(jù)來裝填RowSet
13. 裝填 RowSet 兩種方法的兩種例子?
`import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
import app.MyINI;
public class RowSetFactoryTest1 {
static MyINI myini = new MyINI();
public static void query1(String sql) throws Exception {
Connection conn = JDBCUtil.getConn();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
RowSetFactory factory = RowSetProvider.newFactory();
CachedRowSet cachedRs = factory.createCachedRowSet();
cachedRs.populate(rs);
cachedRs.beforeFirst();
while (cachedRs.next()) {
System.out.println(cachedRs.getString(1) + "\t"
+ cachedRs.getString(2) + "\t"
+ cachedRs.getString(3) + "\t"
+ cachedRs.getString(4) + "\t");
}
rs.close();
stmt.close();
}
public static void query2(String sql) throws Exception {
Class.forName(myini.driver);
//
// 使用 RowSetProvider 創(chuàng)建 RowSetFactory
RowSetFactory factory = RowSetProvider.newFactory();
try (
// 使用 RowSetFactory 創(chuàng)建默認(rèn)的 JdbcRowSet 實(shí)例
CachedRowSet cachedRs = factory.createCachedRowSet()) {
cachedRs.setUrl(myini.url);
cachedRs.setUsername(myini.user);
cachedRs.setPassword(myini.pass);
// 設(shè)置SQL查詢語句
cachedRs.setCommand(sql);
// 執(zhí)行查詢語句
cachedRs.execute();
cachedRs.beforeFirst();
// 向前滾動(dòng)結(jié)果集
while (cachedRs.next()) {
System.out.println(cachedRs.getString(1) + "\t"
+ cachedRs.getString(2) + "\t"
+ cachedRs.getString(3) + "\t"
+ cachedRs.getString(4) + "\t");
}
}
}
public static void main(String[] args) throws Exception {
query1("select * from demo");
System.out.println("=========================");
query2("select * from demo");
}
}