1、JDBC的概念:
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文件,提取建立數據庫連接的通用方法
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接口
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實現類:
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連接數據庫
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方法測試類:
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:
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:
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(){})
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()工具類讀取數據庫
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