1.jdbc簡(jiǎn)介(本文使用的數(shù)據(jù)庫(kù)為MySQL)
? ? 1.1)JDBC(Java DataBase Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL語(yǔ)句的Java API磷支,可以為多種數(shù)據(jù)庫(kù)提供統(tǒng)一的訪問(wèn)(支持多種數(shù)據(jù)庫(kù))。即:用Java語(yǔ)言來(lái)操作數(shù)據(jù)庫(kù)廓潜,JDBC是sun公司提供的的一套規(guī)范(mysql善榛,sql server移盆,oracle都需要遵循)
? ? 2.1)jdbc原理
? ? 應(yīng)用程序? ? >JDBC? ? >數(shù)據(jù)庫(kù)驅(qū)動(dòng)? ? >數(shù)據(jù)庫(kù)
? ? JDBC是接口,而JDBC驅(qū)動(dòng)才是接口的實(shí)現(xiàn)据途,沒(méi)有驅(qū)動(dòng)就無(wú)法完成數(shù)據(jù)庫(kù)連接,每個(gè)數(shù)據(jù)庫(kù)廠商都使用自己的驅(qū)動(dòng) 用來(lái)連接自己的驅(qū)動(dòng)
????3.1)jdbc核心類(接口)
? ? JDBC中的核心類有:DriverManager位衩、Connection熔萧、Statement佛致,和ResultSet!使用時(shí)記得導(dǎo)入MySQL驅(qū)動(dòng)包? ??
? ? 1.1)DriverManager:驅(qū)動(dòng)管理
? ? 注冊(cè)驅(qū)動(dòng):可以讓JDBC知道要使用的是那個(gè)驅(qū)動(dòng)
Class.forName(“com.mysql.jdbc.Driver”);
????1.2)Connection:數(shù)據(jù)庫(kù)連接感昼,數(shù)據(jù)庫(kù)操作基于此對(duì)象罐脊,通過(guò)方法獲取Statement對(duì)象
????獲取Connection:可以獲取到Connection爹殊,如果能獲取Connection說(shuō)明數(shù)據(jù)庫(kù)連接成功
String url ="jdbc:mysql://127.0.0.1:3306/數(shù)據(jù)庫(kù)名稱?useUnicode=true&characterEncoding=utf8";
String username="root";
String password="123";
conn = DriverManager.getConnection(url,username,password);
? ? 1.3)Statement:向數(shù)據(jù)庫(kù)發(fā)送sql語(yǔ)句奸绷,在實(shí)際開(kāi)發(fā)中使用的是PreparedStatement(預(yù)編譯聲明)
Statement stmt = con.createStatement();
????executeUpdate():更新操作(增号醉,刪,改)
????executeQuery():查詢操作
? ? 1.4)ResultSet:查詢結(jié)果集铅碍,只有在sql語(yǔ)句執(zhí)行后才會(huì)產(chǎn)生結(jié)果集线椰,結(jié)果集是一個(gè)二位表格憨愉,有行有列
? ? next():使“行光標(biāo)”移動(dòng)到下一行,并返回移動(dòng)后是否有數(shù)據(jù)配紫,遍歷結(jié)果集
? ? getInt(index):獲取第index行的數(shù)據(jù)
? ? 1.5)close:與io流一樣使用后需要關(guān)閉躺孝,先創(chuàng)建的后關(guān)閉底桂,后創(chuàng)建的先關(guān)閉
rs.close();
stmt.close();
con.close();
? ? 1.6)一個(gè)用戶登陸JDBC方法實(shí)例
public void login1(String username, String password) throws ClassNotFoundException, SQLException {
// 1.注冊(cè)驅(qū)動(dòng)
Class.forName("com.mysql.jdbc.Driver");
// 2.獲取連接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web08", "root", "123");
// 3.編寫(xiě)sql語(yǔ)句
String sql = "select * from tbl_user where uname=? and upassword=?";
// 4.創(chuàng)建預(yù)處理對(duì)象
PreparedStatement pstmt = conn.prepareStatement(sql);
// 5.設(shè)置參數(shù)(給占位符)
pstmt.setString(1, username);
pstmt.setString(2, password);
// 6.執(zhí)行查詢操作
ResultSet rs = pstmt.executeQuery();
// 7.對(duì)結(jié)果集進(jìn)行處理
if (rs.next()) {
System.out.println("恭喜您籽懦," + username + ",登錄成功!");
System.out.println(sql);
} else {
System.out.println("賬號(hào)或密碼錯(cuò)誤!");
}
if (rs != null)
rs.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
}
? ? 1.7)JDBC工具類封裝
public class JDBCUtil {
private static String driver;
private static String url;
private static String username;
private static String password;
/**
* 靜態(tài)代碼塊加載配置文件信息
*/
static {
try {
// 1.通過(guò)當(dāng)前類獲取類加載器
ClassLoader classLoader = JDBCUtil.class.getClassLoader();
// 2.通過(guò)類加載器的方法獲得一個(gè)輸入流
InputStream is = classLoader.getResourceAsStream("db.properties");
// 3.創(chuàng)建一個(gè)properties對(duì)象
Properties props = new Properties();
// 4.加載輸入流
props.load(is);
// 5.獲取相關(guān)參數(shù)的值
driver = props.getProperty("driver");
url = props.getProperty("url");
username = props.getProperty("username");
password = props.getProperty("password");
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 獲取連接方法
*
* @return
*/
public static Connection getConnection() {
Connection conn = null;
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
/**
* 釋放資源方法
*
* @param conn
* @param pstmt
* @param rs
*/
public static void release(Connection conn, PreparedStatement pstmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
????db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
username=root
password=123456
2.連接池
? ? 包含:自定義連接池,c3p0連接池(大多數(shù)使用)拖云,dcbp連接池(少數(shù)使用)应又!使用時(shí)需要導(dǎo)入相應(yīng)到j(luò)ar包,自定義不用
???連接池:用池來(lái)管理Connection尤筐,這樣可以重復(fù)使用Connection洞就。連接池會(huì)自己創(chuàng)建Connection旬蟋,使用時(shí)通過(guò)池來(lái)獲取Connection對(duì)象,當(dāng)使用完后再將Connection歸還到池中去冕碟。池就可以再利用這個(gè)Connection
????2.1)自定義連接池(通過(guò)JDBCUtil獲取的連接)
? ? 自定義類(implements DataSource)? ? >定義一個(gè)容器用于儲(chǔ)存Connection對(duì)象? ? >創(chuàng)建5個(gè)連接對(duì)象放到容器中去? ? >獲取連接的方法? ? >歸還連接方法
/*
* 連接池類
*/
public class MyDataSource implements DataSource{
//1.定義一個(gè)容器用于儲(chǔ)存Connection對(duì)象匆浙,list集合中LinkedList 比較適合插入和刪除首尼,ArrayList適合數(shù)據(jù)查詢和更新
private static LinkedList<Connection> pool = new LinkedList<Connection>();
//2.創(chuàng)建5個(gè)連接對(duì)象放到容器中去
static{
for (int i = 0; i < 5; i++) {
Connection conn = JDBCUtil.getConnection();
pool.add(conn);
}
}
//重寫(xiě)獲取連接的方法
@Override
public Connection getConnection() throws SQLException {
Connection conn = null;
//3.先判斷一下,conn里面是否有連接挠羔,沒(méi)有就創(chuàng)建埋嵌,有就直接使用
if(pool==null){
for (int i = 0; i < 5; i++) {
conn = JDBCUtil.getConnection();//使用的時(shí)1.7)JDBCUtil獲取連接
pool.add(conn);
}
}
//4.從池子中取出連接
conn = pool.remove(0);
return conn;
}
//歸還連接到連接池中的方法(類似于close方法)
public void backClose(Connection conn){
pool.add(conn);
}
? ? 2.2)c3p0連接池:通過(guò)?c3p0-config.xml配置文件獲取連接
????是一個(gè)免費(fèi)開(kāi)源的連接池雹嗦!使用的開(kāi)源項(xiàng)目有:Spring合是,Hibernate等
? ? 導(dǎo)入jar包(c3p0-0.9.1.2.jar)? ? >c3p0-config.xml(必須此文件名)? ? >編寫(xiě)工具類? ? >使用
????c3p0-config.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<!-- 默認(rèn)執(zhí)行 -->
? <default-config>
? ? <property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web08</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
? </default-config>
? <!-- 指定名稱執(zhí)行 -->
? <named-config name="imwj">
? ? <property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///web08</property>
<property name="user">root</property>
<property name="password">123456</property>
? </named-config>
</c3p0-config>
<!-- 此文件的名稱必須是 c3p0-config.xml-->
????編寫(xiě)工具類
package com.imwj.jdbc.utils;
import java.sql.Connection;
import java.sql.SQLException;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/*
* c3p0工具類
*/
public class C3p0Util {
//此處如果不寫(xiě)imwj就會(huì)執(zhí)行默認(rèn)的配置文件
private static ComboPooledDataSource dataSource = new ComboPooledDataSource("imwj");
//返回一個(gè)DataSource連接
public static ComboPooledDataSource getDataSource(){
return dataSource;
}
//返回一個(gè)Connection連接
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
}
? ? 使用
package com.imwj.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
import com.imwj.jdbc.utils.C3p0Util;
import com.imwj.jdbc.utils.JDBCUtil;
public class testC3p0 {
@Test
public void testC3p0Util(){
Connection conn =null;
PreparedStatement pstmt = null;
try{
String sql = "insert into tbl_user values(null,?,?)";
conn = C3p0Util.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "admin5");
pstmt.setString(2, "12345");
int rows = pstmt.executeUpdate();
if(rows!=0){
System.out.println("數(shù)據(jù)添加成功");
}else{
System.out.println("數(shù)據(jù)添加失敗");
}
}catch(Exception e){
throw new RuntimeException(e);
}finally{
JDBCUtil.release(conn, pstmt, null);
}
}
}
? ? 2.3)dcbp連接池:通過(guò)db.properties配置文件獲取連接
????也是一個(gè)開(kāi)源連接池,是Apache Common成員之一难礼,tomcat內(nèi)置連接池
? ? 導(dǎo)入jar包(commons-dbcp-1.4.jar玫锋,commons-pool-1.5.6.jar)? ? >配置文件? ? >編寫(xiě)工具類? ? >使用
????db.properties配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=utf8
username=root
password=123456
? ? 編寫(xiě)工具類
package com.imwj.jdbc.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class dbcpUtil {
private static DataSource dataSource;
static{
try {
//1.加載db.properties文件輸入流
InputStream in = dbcpUtil.class.getClassLoader().getResourceAsStream("db.properties");
//2.讀取輸入流
Properties props = new Properties();
props.load(in);
//3.創(chuàng)建數(shù)據(jù)源
dataSource = BasicDataSourceFactory.createDataSource(props);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
}
? ? 使用
package com.imwj.jdbc.test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
import com.imwj.jdbc.utils.JDBCUtil;
import com.imwj.jdbc.utils.dbcpUtil;
public class testDbcp {
@Test
public void testC3p0Util(){
Connection conn =null;
PreparedStatement pstmt = null;
try{
String sql = "insert into tbl_user values(null,?,?)";
conn = dbcpUtil.getConnection();
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "admin5");
pstmt.setString(2, "12345");
int rows = pstmt.executeUpdate();
if(rows!=0){
System.out.println("數(shù)據(jù)添加成功");
}else{
System.out.println("數(shù)據(jù)添加失敗");
}
}catch(Exception e){
throw new RuntimeException(e);
}finally{
JDBCUtil.release(conn, pstmt, null);
}
}
}
3.DBUtil(劃重點(diǎn))
? ?如果只是使用JDBC開(kāi)發(fā)谦炬,冗余代碼過(guò)多,為了簡(jiǎn)化開(kāi)發(fā)便使用DButil节沦,也是Apache Common成員之一键思。DBUtil是用了連接池,SQL語(yǔ)句并沒(méi)有減少
? ? 導(dǎo)入jar包(commons-dbutils-1.4.jar)? ? >編寫(xiě)JavaBean? ? >創(chuàng)建QueryRunner對(duì)象(并傳入dataSource)? ? >執(zhí)行SQL語(yǔ)句后ResultSetHandler結(jié)果集接收
? ? 3.1)JavaBean:數(shù)據(jù)庫(kù)表的映射
? ? 要求:JavaBean寫(xiě)在domian目錄下甫贯;屬性是私有字段:private吼鳞;有g(shù)et/set方法;?提供無(wú)參構(gòu)造方法
package com.imwj.domain;
public class User {
private int uid;
private String uname;
private String upassword;
public User() {
super();
// TODO Auto-generated constructor stub
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getUpassword() {
return upassword;
}
public void setUpassword(String upassword) {
this.upassword = upassword;
}
}
? ? 3.2)QueryRunner對(duì)象:通過(guò)c3p0獲取數(shù)據(jù)源
????QueryRunner(DataSource ds):提供數(shù)據(jù)源(連接池)
//1.創(chuàng)建QueryRunner對(duì)象叫搁,并傳入dataSource
QueryRunner qr = new QueryRunner(C3p0Util.getDataSource());
? ? update(String sql,Object parmas):執(zhí)行增赖条、刪常熙、改操作,parmas是一個(gè)數(shù)組碱茁,即占位符的內(nèi)容
//2.編寫(xiě)sql語(yǔ)句
String sql = "insert into tbl_user values(null,?,?)";
//3.占位符數(shù)組
Object params[] = {"admin6","123456"};
//4.執(zhí)行sql語(yǔ)句
int rows = qr.update(sql, params);//此處需拋出異常
? ? query(String sql,ResultSetHandler<T> rsh,Object parmas):執(zhí)行查詢類操作
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
? ? 3.3)ResultSetHandler對(duì)象
? ? BeanHandler:將結(jié)果集中的第一條記錄封裝到一個(gè)指定的JavaBean中裸卫,查詢單條數(shù)據(jù)時(shí)使用
User user = qr.query(sql, new BeanHandler<User>(User.class), params);//查詢單個(gè)用戶select * from tbl_user where uid=?
? ? BeanListHandler:將結(jié)果集中的每一條記錄封裝到指定的JavaBean中,再將JavaBean封裝到List中纽竣,查詢多條或所有數(shù)據(jù)時(shí)使用
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));//查詢所有用戶select * from tbl_user
? ? ScalarHandler:用于單數(shù)據(jù)墓贿,栗子:select count(*) from tbl_user 時(shí)使用
Long count = (Long) qr.query(sql, new ScalarHandler());//查詢數(shù)據(jù)總行數(shù)select count(*) from tbl_user
? ? 以下幾個(gè)作了解:
? ? ArrayHandler:將結(jié)果集的第一條數(shù)據(jù)封裝到一個(gè)Object[]數(shù)組中,數(shù)組中的每一個(gè)元素就是這條記錄的一個(gè)值
????ArrayListHandler:將結(jié)果集的每一條數(shù)據(jù)都封裝到一個(gè)Object[]數(shù)組中蜓氨,再將數(shù)組封裝到List集合中
? ? ColumnListHandler:指定查詢列名聋袋,再將結(jié)果封裝到一個(gè)List集合中
? ? MapHandler:將結(jié)果集的第一條數(shù)據(jù)封裝到Map<String,Object>,key就是字段名稱穴吹,value就是字段的值
? ? MapListHandler:將結(jié)果集的每一條都數(shù)據(jù)封裝到Map<String,Object>幽勒,再將Map封裝到List集合中
????3.4)DBUtil栗子:
//查詢所有用戶,BeanListHandler
@Test
public void selectAllUser(){
try {
//1.創(chuàng)建QueryRunner對(duì)象港令,并傳入dataSource
QueryRunner qr = new QueryRunner(C3p0Util.getDataSource());
//2.編寫(xiě)sql語(yǔ)句
String sql = "select * from tbl_user";//省略了3.占位符數(shù)組
//4.執(zhí)行sql語(yǔ)句
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
//5.遍歷結(jié)果集
for (User user : users) {
System.out.println(user.getUname()+":"+user.getUpassword());
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
throw new RuntimeException(e);
}
}
? ? 在不使用框架的前提下啥容,絕大多數(shù)都是使用DBUtil工具開(kāi)發(fā)锈颗,這樣會(huì)極大的節(jié)省系統(tǒng)資源,提高開(kāi)發(fā)效率_浠荨(重點(diǎn))
---------------------
作者:langao_
來(lái)源:CSDN
原文:https://blog.csdn.net/langao_q/article/details/81052042
版權(quán)聲明:本文為博主原創(chuàng)文章击吱,轉(zhuǎn)載請(qǐng)附上博文鏈接!