JDBC詳解之與mySQL資料庫的連線和基本操作一
JDBC詳解
一 JDBC基本操作
MySQL的JDBC驅動包: mysql-connector-java-5.1.38-bin.jar
- mysql-connector-java-5.1.38-bin.jar
是MySQL的JDBC驅動包,用JDBC連線MySQL資料庫時必須使用該jar包。
- maven
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
- 1 載入驅動
- 2 獲得連線
- 3 基本操作,執行SQL語句
- 4 遍歷結果集
- 5 釋放資源
程式碼如下
//1 載入驅動
Class.forName("com.mysql.jdbc.Driver");
//2 獲得連線
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/han","root","123");
//3 基本操作,執行SQL
//3.1 獲得執行SQL語句的物件
Statement createStatement = conn.createStatement();
//3.2 編寫SQL語句
String sql = "select * from orderitem";
//3.3 執行SQL
ResultSet resultSet = createStatement.executeQuery(sql);
//3.4 遍歷結果集
while(resultSet.next()){
System.out.println(resultSet.getInt("id"));
System.out.println(resultSet.getString("product"));
System.out.println(resultSet.getDouble("price"));
}
//4. 釋放資源
resultSet.close();
createStatement.close();
conn.close();
}
物件詳解:
DriverManager:驅動管理類
- 作用 1 : 註冊驅動. 實際開發中一般不會使用,它會導致驅動註冊兩次
- 作用 2 : 獲得連線
- getConnection: 用來獲得與資料庫連線的方法:這個方法中有三個引數:
url :與資料庫連線的路徑 user :與資料庫連線的使用者名稱 password :與資料庫連線的密碼
- 主要關注的是url的寫法:
jdbc:mysql://localhost:3306/web_test3 jdbc :連線資料庫的協議 mysql :是jdbc的子協議 localhost :連線的MySQL資料庫伺服器的主機地址。(連線是本機就可以寫成localhost),如果連線不是本機的,就需要寫上連線主機的IP地址。 3306 :MySQL資料庫伺服器的埠號 web_test3 :資料庫名稱 url如果連線的是本機的路徑,可以簡化為如下格式: jdbc:mysql:///web_test3
connection : 資料庫連線物件
- 作用 1 建立執行SQL語句的物件
- 作用 2 管理事務
statement ; 執行SQL
- 執行SQL
- 批處理
- ResultSet :結果集
- 通過SQL語句查詢的結果
JDBC的增刪改查就不多說了,都是最基本的東西
我們來看一下工具類的抽取和配置檔案的設定
-
-
工具類
public class JDBCUtils {
private static final String driverClassName;
private static final String url;
private static final String username;
private static final String password;
// 靜態程式碼塊,隨著類的載入二載入
static {
// 獲取屬性檔案中的內容
Properties pro = new Properties();
try {
pro.load(new FileInputStream("src/db.properties"));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driverClassName = pro.getProperty("driverClassName");
url = pro.getProperty("url");
username = pro.getProperty("username");
password = pro.getProperty("password");
}
/**
* 註冊驅動
* @throws ClassNotFoundException
*/
public static void loadDriver() throws ClassNotFoundException{
Class.forName(driverClassName);
}
/**
* 獲得連線
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(url,username,password);
}
/**
* 釋放資源的方法
*/
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
/**
* 釋放資源
* @param rs
* @param stmt
* @param conn
*/
public static void release(ResultSet rs,Statement stmt,Connection conn){
// 資源釋放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
配置檔案 db.properties :
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/han
username=root
password=123
二 c3p0連線池
連線池是裝有連線的容器,使用連線的話,可以從連線池中進行獲取,使用完成之後將連線歸還給連線池。
為什麼要使用連線池:
連線物件建立和銷燬是需要耗費時間的,在伺服器初始化的時候就初始化一些連線。把這些連線放入到記憶體中,使用的時候可以從記憶體中獲取,使用完成之後將連線放入連線池中。從記憶體中獲取和歸還的效率要遠遠高於建立和銷燬的效率。(提升效能)。
這裡我們使用c3p0連線池 :
c3p0是一個開源的JDBC連線池.它實現了資料來源和JNDI的繫結,支援JDBC3規範和JDBC2的標準擴充套件.
c3p0 需要引入的jar包:
c3p0-0.9.1.2.jar
- maven
<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
使用連線池查詢資料:
public class C3p0Demo1 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1 建立池
ComboPooledDataSource dataSource = new ComboPooledDataSource();
//2 設定連線資料庫的引數
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/han");
dataSource.setUser("root");
dataSource.setPassword("123");
//3 獲得連線
conn = dataSource.getConnection();
//4 編寫SQL
String sql = "select * from orderitem";
//5 預編譯sql
ps = conn.prepareStatement(sql);
//6 執行sql
rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("id"));
System.out.println(rs.getString("product"));
System.out.println(rs.getDouble("price"));
}
//4. 釋放資源
JDBCUtils.release(rs, ps, conn);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
c3p0的配置檔案c3p0-config.xml
c3p0可以使用出c3p0-config.xml檔案配置,也可以使用 .properties檔案配置
建立連線池時預設去類的路徑下查詢一個名字叫 c3p0-config.xml 的檔案.
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///han</property>
<property name="user">root</property>
<property name="password">123</property>
<!-- 預設初始化的連線數量,往連線池放5個連線-->
<property name="initialPoolSize">5</property>
<!--連線的最少數量-->
<property name="minPoolSize">5</property>
<!--連線的最大數量-->
<property name="maxPoolSize">20</property>
</default-config>
<!-- This app is massive! -->
<!-- <named-config name="oracle">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///han</property>
<property name="user">root</property>
<property name="password">123</property>
</named-config> -->
</c3p0-config>
- 連線池物件應該是一個應用只建立一次就可以的,不需要每次使用都建立一個新的連線池。所以我們要改寫工具類:
public class JDBCUtils2 {
//獲得連線池
private static final ComboPooledDataSource dataSource = new ComboPooledDataSource();
/**
* 返回連線池
*/
public static DataSource getDataSource(){
return dataSource;
}
/**
* 獲得連線
* @throws SQLException
*/
public static Connection getConnection() throws Exception{
return dataSource.getConnection();
}
/**
* 釋放資源的方法
*/
public static void release(Statement stmt,Connection conn){
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
public static void release(ResultSet rs,Statement stmt,Connection conn){
// 資源釋放:
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(stmt != null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
三 JDBC的工具類庫: DBUtils的概述
開源工具類庫: 對JDBC的簡單封裝,而且沒有影響效能。 因為JDBC手寫比較麻煩,而且有非常多的程式碼是類似的。比如獲得連線,預編譯SQL,釋放資源等..那麼可以將這些程式碼抽取出來放到工具類中。將類似的程式碼進行抽取。大大簡化JDBC的程式設計。
DBUtils需要使用的jar包:**
commons-dbutils-1.6.jar
maven
<!-- https://mvnrepository.com/artifact/commons-dbutils/commons-dbutils -->
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
DBUtils的API詳解:
- QueryRunner物件:核心執行類
- 在一般情況下如果執行CRUD的操作:
- 構造:
QueryRunner(DataSource ds); - 方法:
int update(String sql,Object… args);
T query(String sql,ResultSetHandler rsh,Object… args);
- 構造:
- 如果有事務管理的話使用另一套完成CRUD的操作
- 構造:
QueryRunner(); - 方法:
int update(Connection conn,String sql,Object… args);
T query(Connection conn,String sql,ResultSetHandler rsh,Object… args);
- 構造:
- 在一般情況下如果執行CRUD的操作:
增刪改:
匯入jar包,配置出c3p0-config.xml, JDBCUtils2工具類
這裡不需要手動的釋放資源,DBUtils會自動的釋放資源,則JDBCUtils2工具類中的釋放資源的程式碼就可以刪掉了.
這裡只寫一個插入資料:
//插入資料
public void insertProduct() throws SQLException{
QueryRunner queryRunner = new QueryRunner(JDBCUtils2.getDataSource());
queryRunner.update("insert into orderitem values (?,?,?)",null,"電視","45.2");
}
查詢
建立JavaBean :Student 類
處理結果集介面 ResultSetHandler 的實現類:
- BeanHandler : 將一條記錄封裝到javaBean中去 行 (常用)
@Test
public void demo1() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
Student student = qr.query(" select * from user where id = ?",new BeanHandler<Student>(Student.class),2 );
System.out.println(student);
}
- BeanListHandler : 將多條記錄封裝到裝有javaBean的List集合中去 行(常用)
@Test
/**
* 一條記錄就是一個Java物件(javaBean),如果多條記錄,則將多個物件裝到List集合中去.
* @throws SQLException
*/
public void demo2() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
List<Student> list = qr.query("select * from user ", new BeanListHandler<Student>(Student.class));
for (Student student : list) {
System.out.println(student);
}
}
- ArrayHandler : 將一條記錄封裝到一個Object陣列中
@Test
public void demo5() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
Object[] obj = qr.query("select * from user where id = ?", new ArrayHandler(),3);
for (Object object : obj) {
System.out.println(object);
}
}
- ArrayListHandler :.將多條記錄封裝到一個裝有Object陣列的List集合中去.
ScalarHandler : 將單個值封裝.
@Test
public void demo3() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
Object obj = qr.query("select count(*) from user", new ScalarHandler());
System.out.println(obj);
}
- ColumnListHandler() : 將一列(欄位)的值封裝到List集合中 ()可以傳入引數,傳入的是要封裝的列.
@Test
public void demo4() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
List<Object> list = qr.query("select nickname from user ", new ColumnListHandler());
for (Object obj : list) {
System.out.println(obj);
}
}
MapHandler: 將一條記錄封裝到一個Map集合中,Map集合的key是列名(欄位名) values是表中列的記錄值 //結果 {id=1, username=小張, nickname=張三, age=12, password=123}
MapListHandler : 將多條記錄封裝到一個裝有Map集合中的List集合中
@Test
public void demo6() throws SQLException{
QueryRunner qr = new QueryRunner(JDBCUtils.getDataSource());
List<Map<String,Object>> list = qr.query("select * from user", new MapListHandler());
for (Map<String, Object> map : list) {
System.out.println(map);
}
}
第一次寫部落格,如果有錯誤的地方指正