JDBC单独了解一下
JDBC
1.JDBC
JDBC:Java DataBase Connectivty:Java數據庫連接 ,簡單的來說:Java語言操作數據庫。
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-o8xNXYQ1-1616838354633)(E:\JAVA上課筆記\img\image-20210225194955000.png)]
JDBC:其實是Sun公司定義的一套操作所有關系型數據庫的規則,即接口。各個數據庫廠商實現這套接口,提供數據庫驅動jar包,我們可以使用這套接口進行編程,真正執行代碼的是數據庫驅動jar包
2.JDBC快速入門
步驟:
1.導入驅動jar包
? 2.注冊驅動,讓程序知道我們用的是哪個版本的驅動
3.獲取數據庫連接對象:Connection
? 4.定義sql
? 5.獲取執行sql語句的對象:Statement
? 6.執行sql,接收返回結果
? 7.處理結果
? 8.釋放資源
案例
package org.wdit.jdbc;import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement;/* * jdbc入門案例*/ public class jdbcDemo {public static void main(String[] args) throws Exception {//1.注冊驅動Class.forName("com.mysql.jdbc.Driver");//2.獲取數據庫連接對象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456");//3.定義sqlString sql="update student set english=100 where id=4";//4.獲取執行sql語句的對象:statementStatement statement = connection.createStatement();//5.執行sql,接收返回結果int count = statement.executeUpdate(sql);//count:受影響行數//6.處理結果System.out.println(count);//7.釋放資源statement.close();connection.close();} }3.JDBC入門案例過程詳解
3.1Class.forName()
源碼:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-LGQKMlKn-1616838354635)(E:\JAVA上課筆記\img\image-20210225214752160.png)]
回憶:類的加載:加載,鏈接,初始化
在初始化這一步,會執行類構造方法
clint(),而該方法是有變量的賦值動作 和 靜態代碼塊的語句合并產生的,也就是說:類加載器在加載指定結構中包含靜態代碼塊,就會執行靜態代碼塊中的代碼。
因為JDBC驅動有多個版本,所以JDBC規范中規定,所有驅動必須向驅動管理器進行注冊以辨別各種版本。而Drive類中只有一個無參構造和一個靜態代碼塊,靜態代碼塊中內容剛好就是驅動注冊的代碼,所以:
Class.forName()目的是加載類的時候向驅動管理器注冊自己
3.2 DriveManager:驅動器管理對象
功能
1.注冊驅動:(Class.forName中已解釋)Mysql 5之后的驅動jar包可以不注冊驅動,它會自動幫我們注冊
2.獲取數據庫連接對象:
-
方法:
DriveManager.getConnection(“URL”,“用戶名”,“密碼”);
-
參數
? 注意:
如果mysql是本地數據庫,并且端口號使用的是默認端口:3306,則可以將IP(域名):端口號這部分省略
jdbc:mysql:///數據庫名稱2.用戶名:連接mysql的用戶名
3.密碼:對應的密碼
3.3Connection:數據庫連接對象
功能:
1.獲取執行sql的對象
- createStatement() 返回一個Statement對象
- PrepareStatement(String sql)
? 2.管理事務
- 開啟事務:setAutoCommit(boolean autoCommit):調用該方法,false為開啟
- 提交事務:commit()
- 回滾事務:rollback()
3.4Statement:執行靜態sql對象
功能:
- **boolean excute(String sql):**可以執行任意的sql(不常用)
- **int excuteUpdate(String sql):**可以執行DML.(insert,update,delete)和DDL(create,alter,drop)語句
- 返回值int:受影響的行數,我們可以將返回值作為是否執行成功的標準:>0,成功
- **ResultSet excuteQuery(String sql):**執行DQL(select)語句
練習:
1.給student表中添加一條記錄
package org.wdit.jdbc;import java.sql.*;/*練習:給表中添加一條記錄*/ public class jdbcDemo2 {public static void main(String[] args) throws Exception {Connection connection = null;Statement statement = null;try {//1.注冊驅動Class.forName("com.mysql.jdbc.Driver");//2.獲取數據庫連接對象connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8", "root", "123456");//3.編寫sqlString sql="insert into student(id,name,age,sex,address,math,english) values (7,'白冰',18,'女','西安',90,90)";//4.獲取執行sql的對象statement = connection.createStatement();//5.執行sqlint count = statement.executeUpdate(sql);//6.處理結果if(count>0){System.out.println("添加成功");}else{System.out.println("添加失敗");}} catch (Exception e) {e.printStackTrace();} finally {//7.釋放資源try {if(statement!=null){statement.close();}if(connection!=null){connection.close();}} catch (Exception e) {e.printStackTrace();}}} }3.5ResultSet:結果集對象
功能:
? 1.next():類似于Itrator迭代器的next()功能 ,將游標移動到下一條記錄,起始位置在表頭位置,所以第一次取數據,需先調用一次next()方法。
? 2.getXxx(參數):獲取數據
- ? Xxx:代表數據類型
- ? 參數:
- int:代表列的編號。從1開始
- String:代表列名稱
SQL注入:
因為某些關鍵字參與SQL語句的拼接導致出現安全問題
如何解決SQL注入?
? 使用PrepareStatement
4.PrepareStatement:執行動態SQL的對象
PrepareStatement執行指定的sql語句,參數使用占位符,在執行的時候通過某些方法給相應的占位符賦值,才能獲得完整的sql語句,這樣就有效防止了SQL注入
步驟:
? 1.導入驅動jar包
? 2.注冊驅動,讓程序知道我們用的是哪個版本的驅動
3.獲取數據庫連接對象:Connection
? 4.定義sql,參數使用占位符
? 5.獲取執行動態sql對象PrepareStatement:
-
connection.PrepareStatement(String sql)
6.給?占位符賦值
-
setXxx(參數1,參數2)
-
參數1:?占位符的位置編號,從1開始
-
參數2:?占位符對應的值
7.執行sql,接收返回結果,執行不需要傳遞sql語句
8.處理結果
? 9.釋放資源
模擬登錄的優化
靜態
package org.wdit.jdbc;import org.wdit.utils.JDBCUtils;import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Scanner;/* 模擬登錄分析:1.用戶輸入用戶名和密碼2.連接數據庫,查詢是否有該信息*有,登陸成功*沒有:用戶名或密碼錯誤* */ public class jdbcDemo6 {public static void main(String[] args) throws Exception {Scanner scanner=new Scanner(System.in);System.out.println("請輸入用戶名:");String userName=scanner.next();System.out.println("請輸入密碼:");String password=scanner.next();boolean flag = login(userName,password);if(flag){System.out.println("登陸成功");}else{System.out.println("用戶名或密碼錯誤");}}public static boolean login(String userName,String password) throws Exception {if (userName!=null&&password!=null){//獲取連接對象Connection connection = JDBCUtils.getConnection();//sqlString sql="select * from user where usename='"+ userName +"' and password='"+password+"'";//執行sql對象Statement statement = connection.createStatement();//執行ResultSet resultSet = statement.executeQuery(sql);return resultSet.next();}return false;}//a'or'a'='a密碼都正確 }動態sql
package org.wdit.jdbc;import org.wdit.utils.JDBCUtils;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.Statement; import java.util.Scanner;/* 模擬登錄-改進版,防止sql注入分析:1.用戶輸入用戶名和密碼2.連接數據庫,查詢是否有該信息*有,登陸成功*沒有:用戶名或 密碼錯誤* */ public class jdbcDemo7 {public static void main(String[] args) throws Exception {Scanner scanner=new Scanner(System.in);System.out.println("請輸入用戶名:");String userName=scanner.next();System.out.println("請輸入密碼:");String password=scanner.next();boolean flag = login(userName,password);if(flag){System.out.println("登陸成功");}else{System.out.println("用戶名或密碼錯誤");}}public static boolean login(String userName,String password) throws Exception {if (userName!=null&&password!=null){//獲取連接對象Connection connection = JDBCUtils.getConnection();//sqlString sql="select * from user where usename=?and password=? ";//執行sql對象PreparedStatement preparedStatement = connection.prepareStatement(sql);//占位符賦值preparedStatement.setString(1,userName);preparedStatement.setString(2,password);//執行ResultSet resultSet = preparedStatement.executeQuery();return resultSet.next();}return false;}//a'or'a'='a密碼都正確 }5.JDBC-控制事務
5.1事務:
一個包含多個步驟的業務操作,如果這個業務被事務管理,則這多步操作,要么同時成功,要么同時失敗
5.2事務的操作
1.開啟事務
2.提交事務
3.回滾事務
5.3使用Connection對象管理事務
- 開啟事務:setAutoCommit(boolean autoCommit):調用該方法,false為開啟
- 獲取連接對象后可開啟事務
- 提交事務:commit()
- 所有語句執行完畢,即可提交
- 回滾事務:rollback()
- 只要捕捉到異常,就在catch中進行事務回滾
6.數據庫連接池
數據庫連接池類似于多線程的線程池。
概述:
數據庫連接池就是一個容器,存放著一些數據庫的連接對象。
當系統初始化完成后,容器被創建,容器會申請一些連接對象 ,當用戶訪問數據庫時,從容器中獲取連接對象即可,訪問完成后,會將連接對象歸還給連接池,這樣可以提高訪問效率,還可以提高鏈接對象的復用率
實現:
java提供了一個接口:javax.sql.DataSourse該接口是連接池技術的規范,具體的實現 還是由數據庫廠商實現,該接口中定義了兩個方法
- getConnection():獲取連接
- close():歸還連接
主流連接池技術實現
- c3p0:
- Druid:由阿里巴巴提供的數據庫連接池技術
6.1 C3P0連接池
步驟
? 1.導入jar包
- c3p0-0.9.5.2.jar
- mchange-commons-java-0.2.12.jar
? 2.定義配置文件
- 有規定名稱:c3p0.prooperties或c3p0-config.xml
- 規定路徑:放在src目錄下
? 3.創建核心對象:數據庫連接池對象CombopooledDataSource
? 4.獲取連接:getConnection()
package org.wdit.c3p0;import com.mchange.v2.c3p0.ComboPooledDataSource;import java.sql.Connection; import java.sql.SQLException;/*c3p0演示案例*/ public class c3p0Demo1 {public static void main(String[] args) throws Exception {//創建數據庫連接池對象ComboPooledDataSource dataSource = new ComboPooledDataSource();//獲取連接對象Connection connection = dataSource.getConnection();//查看連接對象System.out.println(connection);} }演示配置參數
package org.wdit.c3p0;import com.mchange.v2.c3p0.ComboPooledDataSource; import org.junit.jupiter.api.Test;import java.sql.Connection; import java.sql.SQLException;/*演示配置參數*/ public class c3p0Demo2 {@Testpublic void test() throws Exception {//1.獲取連接池對象ComboPooledDataSource dataSource = new ComboPooledDataSource();//2.獲取連接對象for(int i=1;i<=11;i++) {Connection connection = dataSource.getConnection();System.out.println(i+" "+connection);}}/*驗證connection對象是復用的*/@Testpublic void test2() throws Exception {//1.獲取連接池對象ComboPooledDataSource dataSource = new ComboPooledDataSource();//2.獲取連接對象for(int i=1;i<=11;i++) {Connection connection = dataSource.getConnection();System.out.println(i+" "+connection);if(i==3){connection.close();}}}/*指定配置信息:如果使用無參構造,則使用默認配置:default-config * 如果使用有參構造,則使用和參數名相同的連接池配置信息*/@Testpublic void test3() throws Exception {//1.獲取連接池對象ComboPooledDataSource dataSource = new ComboPooledDataSource();//2.獲取連接對象for(int i=1;i<=11;i++) {Connection connection = dataSource.getConnection();System.out.println(i+" "+connection);if(i==3){connection.close();}}} }6.2Druid連接池
步驟:
1.導包: druid-1.0.9.jar
2.定義配置文件:
- 是properties格式的
- 可以是任意名稱,可以在任意目錄下
? 3.加載配置文件
4.獲取連接池對象:通過工廠來獲取:DruidDataSourceFactory
5.獲取連接:getConnection()
package org.wdit.Druid;import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.pool.DruidDataSourceFactory;import javax.sql.DataSource; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.util.Properties;/*Druid連接池演示案例*/ public class DruidDemo1 {public static void main(String[] args) throws Exception {//加載配置文件Properties properties=new Properties();InputStream resourceAsStream = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");properties.load(resourceAsStream);//獲取連接池對象DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);//獲取連接Connection connection = dataSource.getConnection();//查看連接System.out.println(connection);} }6.3使用Druid連接池定義JDBCUtils
步驟:
1.定義一個工具類:JDBCUtils
2.提供靜態代碼塊:加載配置文件,初始化連接池對象
3.提供方法:
- 獲取連接
- 釋放資源
- 獲取連接池對象的方法
案例
package org.wdit.Druid;import org.junit.jupiter.api.Test;import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class DruidDemo2 {/*向student表中插入一條數據*/@Testpublic void test() throws Exception {//獲取連接對象Connection connection= JDBUtils.getConnection();//定義sqlString sql="insert into student(id,name,age,sex,address,math,english) values (?,?,?,?,?,?,?)";//獲取執行sql對象PreparedStatement preparedStatement = connection.prepareStatement(sql);//給?賦值preparedStatement.setInt(1,9);preparedStatement.setString(2,"邢菲");preparedStatement.setInt(3,18);preparedStatement.setString(4,"女");preparedStatement.setString(5,"西安");preparedStatement.setInt(6,99);preparedStatement.setInt(7,99);//執行int count = preparedStatement.executeUpdate();System.out.println(count);}/*查詢英語成績>60分的所有學生信息*/@Testpublic void test2() throws Exception {//連接對象Connection connection = JDBUtils.getConnection();//sqlString sql="SELECT * FROM student WHERE english >?";//獲取對象。當定占位符PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setInt(1,60);//執行ResultSet resultSet = preparedStatement.executeQuery();//遍歷結果集while(resultSet.next()){int id = resultSet.getInt("id");String name = resultSet.getString("name");System.out.println(id+"----"+name);}}}7.Spring JDBCTemplate
概述:
? Spring框架對JDBC的簡單封裝,提供了一個JDBCTemplate對象,來簡化JDBC的操作。
步驟:
? 1.導包
? 2.創建JDBCTemplate對象,依賴于數據源DataSource
? 3.通過JDBCTemplate對象調用封裝好的一些方法來完成CRUD操作
-
update():執行 增刪改
-
參數1:sql語句
-
參數2-n:根據?數量確定,按?順序給他傳值
-
queryForMap():查詢,將結果封裝成map結合
-
將記錄的字段名作為key,字段值作為value封裝到Map集合中
-
注意事項:結果集長度只能是1,超過就會報錯
-
queryForList():將結果封裝成List集合
-
將每一條記錄封裝到map集合,再把每一條記錄對應的map集合封裝到List集合中
-
query():查詢,將結果封裝成JavaBean對象
- 方式1:query(sql語句,RowMapper接口:我們通過匿名內部類的方式對該接口進行實現)
- 方式2:query(sql語句,new BeanPropertyMapper<>(要封裝的實體類.class))
-
queryForObject():查詢,將結果封裝成對象
新建項目:
1.新建module
2.右鍵–>add…
3.web-InFO–>lib用來存放jar包
-
JDBCTemplate對應的jar包
-
Druid的jar包
-
mysql連接驅動的jar包
4.配置文件
-
Druid.properties
案例:修改學生成績
package org.wdit.test; import org.junit.Test; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.wdit.pojo.Student; import org.wdit.utils.JDBCUtils;import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import java.util.Map; public class JDBCTemplateDemo {/** 入門案例:修改學生成績*///創建JDBCTemplate對象JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());@Testpublic void test(){//調用方法String sql="update student set english= ? where name = ?";int count = template.update(sql,78,"唐浩");System.out.println(count);}/*給student表中添加一條數據*/@Testpublic void test2(){//2.sqlString sql="insert into student(id,name,age,sex,address,math,english) values (?,?,?,?,?,?,?)";//3.調用方法int count = template.update(sql, 10, "smile", 18, "女", "西安", 100, 100);System.out.println(count);}/*刪除添加的一條數據*/@Testpublic void test3(){//2.sqlString sql="delete from student where id= ?";//3.調用方法int count = template.update(sql, 10);System.out.println(count);}/*查詢id=3的學生記錄,將其封裝到Map集合中*/@Testpublic void test4(){String sql="select * from student where id = ?";Map<String, Object> map = template.queryForMap(sql, 3);System.out.println(map);System.out.println("____________________________________________________");}/*查詢所有記錄,將其封裝到List集合中*/@Testpublic void test5(){String sql="select * from student";List<Map<String, Object>> maps= template.queryForList(sql);for(Map<String,Object>map:maps){System.out.println(map);}}/*查詢所有記錄,將其封裝到Student對象的List集合中*/@Testpublic void test6(){System.out.println("-________________________________________________________________");String sql="select * from student";List<Student> students=template.query(sql, new RowMapper<Student>() {@Overridepublic Student mapRow(ResultSet resultSet, int i) throws SQLException {int id = resultSet.getInt("id");String name = resultSet.getString("name");int age = resultSet.getInt("age");String sex = resultSet.getString("sex");String address = resultSet.getString("address");int math = resultSet.getInt("math");int english = resultSet.getInt("english");Student student=new Student(id,name,age,sex,address,math,english);return student;}});for(Student student:students){System.out.println(student);}}/*查詢所有記錄,將其封裝到Student對象的List集合中---(方式2)注意,如果用方式2:你的實體類屬性的基本數據類型一定定義成包裝類型,否則如果你的查詢記錄中有null就會報錯,因為基本數據類型不能存null、2.如果查不到數據也會報錯 */@Testpublic void test7(){System.out.println("________________________________________________________________");String sql="select * from student";List<Student> students=template.query(sql,new BeanPropertyRowMapper<>(Student.class));for(Student student:students){System.out.println(student);}}/*查詢name="唐浩"的學生信息,并封裝成student對象*/@Testpublic void test8(){System.out.println("8________________________________________________________________");String sql="select * from student where name = ?";Student student = template.queryForObject(sql, new BeanPropertyRowMapper<>(Student.class), "唐浩");System.out.println(student);}
}
}/*查詢所有記錄,將其封裝到Student對象的List集合中---(方式2)注意,如果用方式2:你的實體類屬性的基本數據類型一定定義成包裝類型,否則如果你的查詢記錄中有null就會報錯,因為基本數據類型不能存null、2.如果查不到數據也會報錯 */@Testpublic void test7(){System.out.println("________________________________________________________________");String sql="select * from student";List<Student> students=template.query(sql,new BeanPropertyRowMapper<>(Student.class));for(Student student:students){System.out.println(student);}}/*查詢name="唐浩"的學生信息,并封裝成student對象*/@Testpublic void test8(){System.out.println("8________________________________________________________________");String sql="select * from student where name = ?";Student student = template.queryForObject(sql, new BeanPropertyRowMapper<>(Student.class), "唐浩");System.out.println(student);}}總結
以上是生活随笔為你收集整理的JDBC单独了解一下的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Louvain、Lpa、Infomap算
- 下一篇: xml生成2维码_MyBatis(2)之