Java數據庫連接技術(Java DataBase Connectivity)能實現java程序對各種數據庫的訪問,
由一組使用java語言編寫的類 和 接口(jdbc api) 組成,他們位於java.sql以及javax.sql中。
2、JDBC API 使用JDBC訪問數據庫就要用JDBC API完成3件事: 與數據庫鏈接,返送sql語句 和 處理結果。
Java應用程序可以使用java.sql和javax.sql包中的JDBC APL來鏈接和操作;
工作的4個重要環節:
(1).DriverManager類:依據數據庫的不同,管理JDBC驅動;
(2).Connection接口:負責鏈接數據庫並擔任傳送數據的任務。
(3).Statement接口:由Connection產生,負責執行SQL語句。
(4).ResultSet接口:負責保存Statement執行后所參數的查詢結果。
3、JDBC訪問數據庫的步驟:
(1)Class.forName(oracle.jdbc.driver.OracleDriver);//加載驅動
(2)Connection conn=DriverManager.getConnection(“jdbc:oracle:thin:@127.0.0.1:1521:orcl”,”scott”,”orcl”);//創建連接
(3).Statement stmt=conn.createStatement();//創建Statement對象
String sql=””;
ResultSet rs= Stmt.executeQuery(sql);
(4)while(rs.next()){int id=rs.getInt(1);
Timestamp time=rs.getTimestamp(“createdate”);}//循環讀取結果集
4.資源的釋放
Re.close();
Stmt.close();
Conn.close();
5、通過DatasourceFactory和創建database.properties配置文件鏈接數據庫
1.建BaseDao文件,提取建立數據庫連接的通用方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
package
demo.mysql.dao;
import
java.sql.Connection;
import
java.sql.DriverManager;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.sql.Statement;
import
javax.naming.Context;
import
javax.naming.InitialContext;
import
javax.naming.NamingException;
import
javax.sql.DataSource;
import
demo.mysql.util.ConfigManager;
public
class
BaseDao {
protected
Connection conn;
protected
PreparedStatement ps;
protected
Statement stmt;
protected
ResultSet rs;
// 獲取數據庫鏈接
public
boolean
getConnection() {
String driver = ConfigManager.getInstance().getString(
"jdbc.driver_class"
);
String url = ConfigManager.getInstance().getString(
"jdbc.connection.url"
);
String username = ConfigManager.getInstance().getString(
"jdbc.connection.username"
);
String password = ConfigManager.getInstance().getString(
"jdbc.connection.password"
);
try
{
// (1).Class.forName()加載驅動
Class.forName(driver);
// (2).DriverManager.getConnection(數據庫url,用戶名,密碼);onnection1521
conn = DriverManager.getConnection(url, username, password);
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
return
false
;
}
catch
(SQLException e) {
e.printStackTrace();
return
false
;
}
return
true
;
}
public
Connection getConnection2(){
try
{
//初始話上下文
Context cxt=
new
InitialContext();
//獲取與邏輯名相關聯的數據源對象
DataSource ds=(DataSource)cxt.lookup(
"java:comp/env/jdbc/orcl"
);
conn=ds.getConnection();
}
catch
(NamingException e) {
e.printStackTrace();
}
catch
(SQLException e) {
e.printStackTrace();
}
return
conn;
}
// 增刪改
public
int
executeUpdate(String sql, Object[] params) {
int
updateRows =
0
;
getConnection();
try
{
ps=conn.prepareStatement(sql);
//填充占位符
for
(
int
i =
0
; i < params.length; i++) {
ps.setObject(i+
1
, params[i]);
}
updateRows=ps.executeUpdate();
}
catch
(SQLException e) {
e.printStackTrace();
}
return
updateRows;
}
// 查詢
public
ResultSet executeSQL(String sql, Object[] params) {
try
{
getConnection();
ps=conn.prepareStatement(sql);
//填充占位符
for
(
int
i =
0
; i < params.length; i++) {
ps.setObject(i+
1
, params[i]);
}
rs=ps.executeQuery();
}
catch
(SQLException e) {
e.printStackTrace();
}
return
rs;
}
// 關閉資源
public
boolean
closeResource() {
if
(rs!=
null
) {
try
{
rs.close();
}
catch
(SQLException e) {
e.printStackTrace();
return
false
;
}
}
if
(ps!=
null
) {
try
{
ps.close();
}
catch
(SQLException e) {
e.printStackTrace();
return
false
;
}
}
if
(stmt!=
null
) {
try
{
stmt.close();
}
catch
(SQLException e) {
e.printStackTrace();
return
false
;
}
}
if
(conn!=
null
) {
try
{
conn.close();
}
catch
(SQLException e) {
e.printStackTrace();
return
false
;
}
}
return
true
;
}
}
|
2.創建EmpDao接口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
package
demo.mysql.dao;
import
java.sql.Date;
public
interface
EmpDao {
/**
* 查詢
*/
public
void
empList();
/**
* 添加
*/
public
void
add(
int
empno,String ename,String job,
int
mgr,Date hireDate,
double
sal,
double
comm,
int
deptno);
/**
* 刪除
*/
public
void
delete(
int
empno);
/**
* 修改
*/
public
void
update(
int
empno,String ename);
}
|
3.創建EmpDaoImpl實現類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package
demo.mysql.dao.impl;
import
java.sql.Date;
import
java.sql.ResultSet;
import
java.sql.SQLException;
import
java.sql.Timestamp;
import
demo.mysql.dao.BaseDao;
import
demo.mysql.dao.EmpDao;
public
class
EmpDaoImpl
extends
BaseDao
implements
EmpDao {
/**
* 查詢
*/
public
void
empList() {
try
{
// (3).創建statement 對象執行sql
String sql =
"select * from emp"
;
Object[] params = {};
ResultSet rs =
this
.executeSQL(sql, params);
// 處理結果集
while
(rs.next()) {
int
empno = rs.getInt(
"EMPNO"
);
String ename = rs.getString(
"ENAME"
);
String job = rs.getString(
"JOB"
);
int
mgr = rs.getInt(
"MGR"
);
Timestamp time = rs.getTimestamp(
"HIREDATE"
);
int
sal = rs.getInt(
"SAL"
);
double
comm = rs.getInt(
"COMM"
);
int
deptno = rs.getInt(
"DEPTNO"
);
System.out.println(empno +
"\t"
+ ename +
"\t"
+ job +
"\t"
+ mgr +
"\t"
+ time +
"\t"
+ sal +
"\t"
+ comm +
"\t"
+ deptno);
}
}
catch
(SQLException e) {
e.printStackTrace();
}
finally
{
this
.closeResource();
}
}
/**
* 添加
*/
public
void
add(
int
empno,String ename,String job,
int
mgr,Date hireDate,
double
sal,
double
comm,
int
deptno){
try
{
//(3).創建statement 對象執行sql
String sql=
"insert into emp values(?,?,?,?,?,?,?,?)"
;
Object[] params={empno,ename,job,mgr,
new
java.sql.Timestamp(hireDate.getTime()),sal,comm,deptno};
int
i=
this
.executeUpdate(sql, params);
if
(i>
0
){
System.out.println(
"插入新聞成功"
);
}
}
finally
{
this
.closeResource();
}
}
/**
* 刪除
*/
public
void
delete(
int
empno){
try
{
String sql=
"delete from emp where empno=?"
;
Object[] params={empno};
int
i=
this
.executeUpdate(sql, params);
if
(i>
0
){
System.out.println(
"刪除信息成功"
);
}
}
finally
{
this
.closeResource();
}
}
/**
* 修改
*/
public
void
update(
int
empno,String ename){
try
{
String sql=
"update emp set ename=? where empno=?"
;
Object[] params={ename,empno};
int
i=
this
.executeUpdate(sql, params);
if
(i>
0
){
System.out.println(
"修改信息成功"
);
}
}
finally
{
this
.closeResource();
}
}
}
|
3.兩種連接數據庫的方式
(1)、通過DatasourceFactory連接數據庫
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
package
demo.mysql.testByDataSource;
import
java.sql.Connection;
import
java.sql.DriverManager;
import
java.sql.SQLException;
public
class
MysqlDatasourceFactory {
private
final
String DRIVER =
"com.mysql.jdbc.Driver"
;
/**
* 子類可以修改url、username以及pwd的值
*/
private
String url =
"jdbc:mysql://192.168.9.223:3306/test_2016?useUnicode=true&characterEncoding=utf-8"
;
private
String username =
"root"
;
private
String pwd =
"ablejava"
;
protected
Connection openConnection(){
Connection con =
null
;
try
{
//裝載數據庫驅動
Class.forName(DRIVER);
//建立數據庫連接
con = DriverManager.getConnection(url,username,pwd);
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
}
catch
(SQLException e) {
e.printStackTrace();
}
return
con;
}
public
void
setUrl(String url) {
this
.url = url;
}
public
void
setUsername(String username) {
this
.username = username;
}
public
void
setPwd(String pwd) {
this
.pwd = pwd;
}
}
|
main方法測試類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
|
package
demo.mysql.testByDataSource;
import
java.sql.Connection;
import
java.sql.PreparedStatement;
import
java.sql.ResultSet;
import
java.sql.Timestamp;
public
class
Test {
public
static
void
main(String[] args) {
try
{
MysqlDatasourceFactory m=
new
MysqlDatasourceFactory();
System.out.println(m.openConnection());
// 建立連接
Connection conn = m.openConnection();
String sql =
"select * from emp"
;
PreparedStatement preparedStatement = conn.prepareStatement(sql);
ResultSet rs = preparedStatement.executeQuery();
while
(rs.next()) {
int
empno = rs.getInt(
"EMPNO"
);
String ename = rs.getString(
"ENAME"
);
String job = rs.getString(
"JOB"
);
int
mgr = rs.getInt(
"MGR"
);
Timestamp time = rs.getTimestamp(
"HIREDATE"
);
int
sal = rs.getInt(
"SAL"
);
double
comm = rs.getInt(
"COMM"
);
int
deptno = rs.getInt(
"DEPTNO"
);
System.out.println(empno +
"\t"
+ ename +
"\t"
+ job +
"\t"
+ mgr +
"\t"
+ time +
"\t"
+ sal +
"\t"
+ comm +
"\t"
+ deptno);
}
}
catch
(Exception e) {
e.printStackTrace();
}
}
}
|
(2)、創建database.properties配置文件鏈接數據庫
在src下創建datebase.properties文件;
添加key – value :
oracle:
1
2
3
4
5
6
7
|
jdbc.driver_class=oracle.jdbc.driver.OracleDriver;
jdbc.connection.url=jdbc:oracle:thin:
@localhost
:
1521
:orcl;
jdbc.connection.username=scott;
jdbc.connection.password=orcl;
|
mysql:
1
2
3
4
|
jdbc.driver_class=com.mysql.jdbc.Driver
jdbc.connection.url=jdbc\:mysql\:
//192.168.9.223\:3306/test_2016?useUnicode\=true&characterEncoding\=utf-8
jdbc.connection.username=root
jdbc.connection.password=ablejava
|
設置配置工具類(Class ConfigManager(){})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
package
demo.mysql.util;
import
java.io.IOException;
import
java.io.InputStream;
import
java.util.Properties;
public
class
ConfigManager {
private
static
ConfigManager configManager;
private
static
Properties properties;
private
ConfigManager(){
String configFile=
"database.properties"
;
try
{
properties=
new
Properties();
InputStream in=ConfigManager.
class
.getClassLoader().getResourceAsStream(configFile);
//讀取配置文件
//properties.load(InputStream);讀取文件
properties.load(in);
in.close();
//將流關閉
}
catch
(IOException e) {
e.printStackTrace();
}
}
/**
* 通過單例模式設置實例化的個數
* @return
*/
public
static
ConfigManager getInstance(){
if
(configManager==
null
) {
configManager=
new
ConfigManager();
}
return
configManager;
}
/**
* 在database.properties總根據key得到對應的value值
*/
public
String getString(String key){
return
properties.getProperty(key);
}
}
|
6.使用ConfigManager()工具類讀取數據庫
1
2
3
4
5
6
7
8
9
10
11
12
13
|
package
demo.mysql.testByProperties;
import
demo.mysql.dao.EmpDao;
import
demo.mysql.dao.impl.EmpDaoImpl;
public
class
Test {
public
static
void
main(String[] args) {
EmpDao empDao =
new
EmpDaoImpl();
empDao.empList();
}
}
|
運行結果:
6、PreparedStatement對象
PreparedStatement接口繼承來自Statement接口,它對SQL語句進行了預編譯,所以執行速度快於Statement對象,Sql語句具有一個或多個數據參數,這些參數的值在SQL中沒指定,可以為每個參數保留一個問號(?)作為占位符,熱后用對象賦值。
如果數據類型是日期格式采用:
SetTimestamp(參數位置,new java.sql.Timestamp(new java.util.Date().getTime()));
如果數據類型為Clob類型,則可將其視為String類型那個進行設置。
7.Sql注入: a’ or 1=1 --
8.MVC設計模式概念(三層模式):
1、 表示層
職責:位於最上層,用戶能夠直接訪問,用與顯示數據和接收用戶數據的數據,為用戶提供一種交互式操作界面,一般為web應用程序,以jsp文件,HTML文件為主。
2、業務邏輯層:
職責:提供對業務邏輯處理的封裝,通常會定義一些接口,通常放在biz包下。
3、 數據庫訪問層:
職責:實現對數據的保存和讀取操作,數據訪問,可以訪問數據庫,文本文件或xml文擋,通常放在dao包中。
MVC:一般把業務邏輯層和數據訪問層稱Modle層,把表示層稱View層,在V層和M層中間還有Control層。
9、數據源與連接池:
數據源的作用就是獲取數據連接,而連接池則是對已經創建好的連接對象進行管理,二者作用不同。
oracle連接數據源的配置步驟:
1. 在tmocat服務器中添加數據庫驅動,將oracle14.jar添加到tomcat安裝目錄的lib文件夾中。
2. 在tomcat服務器中配置。
<Resource name="jdbc/orcl" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="scott" password="orcl" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@localhost:1521:orcl"/>
maxActive:表示處於活動最大連接數量,maxIdle:處於空閑的最大連接數量,maxWait:最大等待時間,-1表示無限等待,單位ms
3. 使用JNDI讀取數據源:
JNDI(Java Naming and Directory interface,java命名與目錄接口),獲取數據源時,javax.naming.context提供了查詢jndiResource的接口,通過該對象的lookup()方法,就可以找到之前創建好的數據源。
public Connection getConnection2(){
try {
//初始話上下文
Context cxt=new InitialContext();
//獲取與邏輯名相關聯的數據源對象
DataSource ds=(DataSource)cxt.lookup("java:comp/env/jdbc/orcl");
conn=ds.getConnection();
} catch (NamingException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
8、jsp中的動作標簽
<jsp:useBean id=”newService” class=”com.service.newServiceImpl” scop=”page”> scop的取值為:page(默認),request,session,application
<jsp:useBean id=”newsDao” class=”com.impl.newDaoImpl” scop=”page”>
<jsp:setProperty property=”newsDao” name=”newsService” value=”<%=newsDao %>”>
等同於:NewsServiceImpl newsService=new NewsServiceImpl();
NewsDao newsDao=new NewsDaoImpl();
newsService.setNewsDao(newsDao);
jsp頁面的包含:
<%@include file="top.jsp" %> 靜態包含
<jsp:include page=”url”> 動態包含
靜態包含與動態包含的區別:
靜態 |
動態 |
<%@include file=”url”> |
<jsp:include page=”url”> |
先將頁面包含,后執行頁面代碼,將一個頁面的代碼復制到另一個頁面中 |
先執行頁面代碼,后將頁面包含,即將一個頁面的運行結果包含到另外一個頁面中 |
被包含的頁面內容發生變化時,包含頁面也將會被重新編譯 |
被包含頁面內容發生變化時,包含頁面不會重新編譯 |
頁面的跳轉:
<jsp:forward page=”url”> 同轉發效果相同
DatasourceFactory