Java中連接數(shù)據(jù)庫(kù)方式詳細(xì)步驟記錄
一、JDBC(Java Database Connectivity)
這是 Java 連接數(shù)據(jù)庫(kù)最基本的方式。
- 導(dǎo)入數(shù)據(jù)庫(kù)驅(qū)動(dòng):首先需要將特定數(shù)據(jù)庫(kù)的 JDBC 驅(qū)動(dòng)添加到項(xiàng)目的依賴中。
- 加載驅(qū)動(dòng):使用
Class.forName()
方法加載數(shù)據(jù)庫(kù)驅(qū)動(dòng)。例如,Class.forName("com.mysql.cj.jdbc.Driver");
。 - 建立連接:使用
DriverManager.getConnection()
方法建立與數(shù)據(jù)庫(kù)的連接。例如,String url = "jdbc:mysql://localhost:3306/mydb";
,String username = "root";
,String password = "password";
,Connection connection = DriverManager.getConnection(url, username, password);
。 - 執(zhí)行 SQL 語(yǔ)句:通過(guò)
Statement
或PreparedStatement
對(duì)象執(zhí)行 SQL 查詢、插入、更新或刪除等操作。 - 處理結(jié)果集:如果是查詢操作,需要處理返回的
ResultSet
結(jié)果集。 - 關(guān)閉連接:在操作完成后,務(wù)必關(guān)閉連接、語(yǔ)句和結(jié)果集以釋放資源。
1、添加依賴
- 確定數(shù)據(jù)庫(kù)類(lèi)型:首先確定你要連接的數(shù)據(jù)庫(kù)類(lèi)型,比如 MySQL、Oracle、SQL Server 等。不同的數(shù)據(jù)庫(kù)需要不同的 JDBC 驅(qū)動(dòng)。
- 添加依賴:將相應(yīng)數(shù)據(jù)庫(kù)的 JDBC 驅(qū)動(dòng)添加到你的項(xiàng)目中。如果是 Maven 項(xiàng)目,可以在
pom.xml
文件中添加依賴;如果是 Gradle 項(xiàng)目,則在build.gradle
文件中添加。例如,對(duì)于 MySQL 數(shù)據(jù)庫(kù),可以添加mysql-connector-java
依賴。
2、連接數(shù)據(jù)庫(kù)
Java 虛擬機(jī)能夠找到并加載特定數(shù)據(jù)庫(kù)的 JDBC 驅(qū)動(dòng)程序
try { Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); }
3、建立連接
url
是數(shù)據(jù)庫(kù)的連接字符串,其中localhost
是數(shù)據(jù)庫(kù)服務(wù)器地址,3306
是 MySQL 的默認(rèn)端口號(hào),your_database_name
是你要連接的數(shù)據(jù)庫(kù)名稱(chēng)。username
和password
分別是數(shù)據(jù)庫(kù)的用戶名和密碼。
String url = "jdbc:mysql://localhost:3306/your_database_name"; String username = "your_username"; String password = "your_password"; try { Connection connection = DriverManager.getConnection(url, username, password); // 連接成功后可以進(jìn)行后續(xù)數(shù)據(jù)庫(kù)操作 } catch (SQLException e) { e.printStackTrace(); }
4、執(zhí)行 SQL 語(yǔ)句
可以使用Statement
或PreparedStatement
來(lái)執(zhí)行 SQL 語(yǔ)句。
Statement
示例:
try { Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table_name"); while (resultSet.next()) { // 處理結(jié)果集 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } } catch (SQLException e) { e.printStackTrace(); }
若使用PreparedStatement
,(可以防止 SQL 注入):
try { String sql = "SELECT * FROM your_table_name WHERE id =?"; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, 123); // 設(shè)置參數(shù)值 ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()) { // 處理結(jié)果集 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } } catch (SQLException e) { e.printStackTrace(); }
5、處理結(jié)果集
根據(jù)執(zhí)行的 SQL 語(yǔ)句類(lèi)型(查詢、插入、更新、刪除等),處理結(jié)果集的方式不同。
對(duì)于查詢語(yǔ)句,使用ResultSet
的方法(如getInt
、getString
等)獲取結(jié)果集中的列值。
1)查詢語(yǔ)句處理
- 使用
ResultSet
遍歷結(jié)果集:
- 當(dāng)執(zhí)行查詢語(yǔ)句后,會(huì)得到一個(gè)
ResultSet
對(duì)象,它代表了從數(shù)據(jù)庫(kù)返回的結(jié)果集??梢允褂?code>while循環(huán)結(jié)合ResultSet.next()
方法來(lái)遍歷結(jié)果集中的每一行數(shù)據(jù)。 - 例如:
- 當(dāng)執(zhí)行查詢語(yǔ)句后,會(huì)得到一個(gè)
try { Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("SELECT * FROM your_table_name"); while (resultSet.next()) { // 處理每一行數(shù)據(jù) int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println("ID: " + id + ", Name: " + name); } } catch (SQLException e) { e.printStackTrace(); }
- 在循環(huán)中,可以根據(jù)列名或者列索引,使用
ResultSet
的相應(yīng)方法(如getInt
、getString
、getDouble
等)來(lái)獲取每一列的值。列索引從 1 開(kāi)始。 - 獲取特定類(lèi)型的數(shù)據(jù):
- 根據(jù)數(shù)據(jù)庫(kù)中列的數(shù)據(jù)類(lèi)型,選擇合適的
ResultSet
方法來(lái)獲取值。 - 例如,如果列是整數(shù)類(lèi)型,可以使用
getInt
;如果是字符串類(lèi)型,可以使用getString
;如果是浮點(diǎn)數(shù)類(lèi)型,可以使用getDouble
等。 - 同時(shí),可以傳入列名或者列索引作為參數(shù)。例如:
- 根據(jù)數(shù)據(jù)庫(kù)中列的數(shù)據(jù)類(lèi)型,選擇合適的
int id = resultSet.getInt(1); // 通過(guò)列索引獲取第一列的值(整數(shù)類(lèi)型) String name = resultSet.getString("name"); // 通過(guò)列名獲取名為"name"的列的值(字符串類(lèi)型)
2)插入語(yǔ)句處理
- 執(zhí)行插入語(yǔ)句后,通??梢垣@取插入行的自增主鍵值(如果數(shù)據(jù)庫(kù)表有自增主鍵):
- 使用
PreparedStatement
執(zhí)行插入語(yǔ)句,并設(shè)置返回自增主鍵的參數(shù)。 - 例如:
- 使用
String sql = "INSERT INTO your_table_name (column1, column2) VALUES (?,?)"; try { PreparedStatement preparedStatement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS); preparedStatement.setString(1, "value1"); preparedStatement.setString(2, "value2"); int rowsInserted = preparedStatement.executeUpdate(); if (rowsInserted > 0) { // 獲取自增主鍵 ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); if (generatedKeys.next()) { int generatedId = generatedKeys.getInt(1); System.out.println("Inserted row with id: " + generatedId); } } } catch (SQLException e) { e.printStackTrace(); }
- 在執(zhí)行插入操作后,通過(guò)
PreparedStatement.getGeneratedKeys()
方法可以獲取包含自增主鍵值的ResultSet
,然后可以從這個(gè)結(jié)果集中獲取插入行的主鍵值。
3)更新語(yǔ)句處理
- 執(zhí)行更新語(yǔ)句后,通常會(huì)返回受影響的行數(shù):
- 使用
Statement
或PreparedStatement
執(zhí)行更新語(yǔ)句,然后通過(guò)executeUpdate
方法的返回值來(lái)判斷有多少行被更新。 - 例如:
- 使用
String sql = "UPDATE your_table_name SET column1 =? WHERE column2 =?"; try { PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, "newValue1"); preparedStatement.setString(2, "conditionValue"); int rowsUpdated = preparedStatement.executeUpdate(); System.out.println("Updated " + rowsUpdated + " rows."); } catch (SQLException e) { e.printStackTrace(); }
- 如果返回值大于 0,表示有行被更新;如果返回值為 0,表示沒(méi)有滿足條件的行被更新。
4)刪除語(yǔ)句處理
- 與更新語(yǔ)句類(lèi)似,執(zhí)行刪除語(yǔ)句后也會(huì)返回受影響的行數(shù):
- 使用
Statement
或PreparedStatement
執(zhí)行刪除語(yǔ)句,然后通過(guò)executeUpdate
方法的返回值來(lái)判斷有多少行被刪除。 - 例如:
- 使用
String sql = "DELETE FROM your_table_name WHERE column1 =?"; try { PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1, "valueToDelete"); int rowsDeleted = preparedStatement.executeUpdate(); System.out.println("Deleted " + rowsDeleted + " rows."); } catch (SQLException e) { e.printStackTrace(); }
- 如果返回值大于 0,表示有行被刪除;如果返回值為 0,表示沒(méi)有滿足條件的行被刪除。
在處理這些 SQL 語(yǔ)句時(shí),需要注意捕獲SQLException
異常,以確保在出現(xiàn)數(shù)據(jù)庫(kù)錯(cuò)誤時(shí)能夠正確處理異常情況,并進(jìn)行適當(dāng)?shù)腻e(cuò)誤處理和日志記錄。
6、關(guān)閉連接
在完成數(shù)據(jù)庫(kù)操作后,務(wù)必關(guān)閉連接以釋放資源。
try { if (connection!= null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); }
二、數(shù)據(jù)庫(kù)連接池
使用數(shù)據(jù)庫(kù)連接池可以提高數(shù)據(jù)庫(kù)連接的性能和效率,常見(jiàn)的數(shù)據(jù)庫(kù)連接池有 HikariCP、C3P0、Druid 等。
以 Druid 為例,首先添加 Druid 的依賴到項(xiàng)目中,配置連接池參數(shù),如數(shù)據(jù)庫(kù) URL、用戶名、密碼、最大連接數(shù)等,通過(guò)連接池獲取數(shù)據(jù)庫(kù)連接進(jìn)行操作。
1、添加依賴
如果是 Maven 項(xiàng)目,在pom.xml
中添加以下依賴:
<dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.2.12</version> </dependency>
如果是 Gradle 項(xiàng)目,在build.gradle
中添加:
implementation 'com.alibaba:druid:1.2.12'
2、基本使用步驟
1)配置數(shù)據(jù)源:
import com.alibaba.druid.pool.DruidDataSource; public class DruidExample { public static void main(String[] args) { // 創(chuàng)建 Druid 數(shù)據(jù)源對(duì)象 DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl("jdbc:mysql://localhost:3306/your_database"); dataSource.setUsername("your_username"); dataSource.setPassword("your_password"); // 可以設(shè)置其他屬性,如最大連接數(shù)、最小連接數(shù)等 dataSource.setInitialSize(5); dataSource.setMaxActive(10); } }
2)獲取數(shù)據(jù)庫(kù)連接:
try { Connection connection = dataSource.getConnection(); // 使用連接進(jìn)行數(shù)據(jù)庫(kù)操作 } catch (SQLException e) { e.printStackTrace(); }
3)關(guān)閉數(shù)據(jù)源(通常在應(yīng)用程序關(guān)閉時(shí)執(zhí)行)
dataSource.close();
3、監(jiān)控功能
Druid 提供了強(qiáng)大的監(jiān)控功能,可以通過(guò)以下方式訪問(wèn)監(jiān)控頁(yè)面:
- 在應(yīng)用程序中配置 Druid 的監(jiān)控屬性:
dataSource.setFilters("stat"); dataSource.setEnable(true);
訪問(wèn)監(jiān)控頁(yè)面:默認(rèn)情況下,可以通過(guò)http://localhost:8080/druid/index.html
訪問(wèn) Druid 的監(jiān)控頁(yè)面,前提是你的應(yīng)用程序在端口 8080 運(yùn)行。在監(jiān)控頁(yè)面中,可以查看連接池的狀態(tài)、SQL 執(zhí)行情況等信息。
4、結(jié)合 Spring 使用
如果在 Spring 項(xiàng)目中使用 Druid,可以通過(guò)以下步驟進(jìn)行配置:
- 在配置文件中配置數(shù)據(jù)源:
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="url" value="jdbc:mysql://localhost:3306/your_database"/> <property name="username" value="your_username"/> <property name="password" value="your_password"/> <!-- 其他屬性配置 --> </bean>
在代碼中通過(guò)@Autowired
注入數(shù)據(jù)源:
import javax.sql.DataSource; @Service public class YourService { private DataSource dataSource; @Autowired public YourService(DataSource dataSource) { this.dataSource = dataSource; } public void doSomethingWithDatabase() { try { Connection connection = dataSource.getConnection(); // 進(jìn)行數(shù)據(jù)庫(kù)操作 } catch (SQLException e) { e.printStackTrace(); } } }
三、ORM框架
- Hibernate:Hibernate 是一個(gè)強(qiáng)大的 ORM 框架,它允許將數(shù)據(jù)庫(kù)表映射為 Java 對(duì)象,簡(jiǎn)化了數(shù)據(jù)庫(kù)操作。通過(guò)配置 Hibernate 的配置文件和實(shí)體類(lèi)的映射文件,可以輕松地連接到數(shù)據(jù)庫(kù)并進(jìn)行各種數(shù)據(jù)庫(kù)操作。
- MyBatis:MyBatis 也是一種常用的數(shù)據(jù)庫(kù)訪問(wèn)框架,它通過(guò) SQL 映射文件將 SQL 語(yǔ)句與 Java 方法進(jìn)行映射。雖然 MyBatis 不是嚴(yán)格意義上的 ORM 框架,但它提供了一種方便的方式來(lái)操作數(shù)據(jù)庫(kù),同時(shí)也允許編寫(xiě)自定義 SQL 語(yǔ)句以滿足復(fù)雜的業(yè)務(wù)需求。
這里以MyBatis舉例:
1、添加依賴
如果是 Maven 項(xiàng)目,在pom.xml
中添加以下依賴:
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency>
如果是 Gradle 項(xiàng)目,在build.gradle
中添加:
implementation 'org.mybatis:mybatis:3.5.10'
同時(shí),如果使用數(shù)據(jù)庫(kù),還需要添加相應(yīng)數(shù)據(jù)庫(kù)的驅(qū)動(dòng)依賴。
2、創(chuàng)建實(shí)體類(lèi)
例如,有一個(gè)用戶實(shí)體類(lèi):
public class User { private int id; private String username; private String password; // 構(gòu)造函數(shù)、getter 和 setter 方法 }
3、創(chuàng)建映射接口
import java.util.List; public interface UserMapper { List<User> getAllUsers(); User getUserById(int id); void insertUser(User user); void updateUser(User user); void deleteUser(int id); }
4、編寫(xiě) SQL 映射文件
創(chuàng)建一個(gè)與映射接口同名的 XML 文件,例如UserMapper.xml
:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="your.package.name.UserMapper"> <select id="getAllUsers" resultType="User"> SELECT * FROM users; </select> <select id="getUserById" parameterType="int" resultType="User"> SELECT * FROM users WHERE id = #{id}; </select> <insert id="insertUser" parameterType="User"> INSERT INTO users (username, password) VALUES (#{username}, #{password}); </insert> <update id="updateUser" parameterType="User"> UPDATE users SET username = #{username}, password = #{password} WHERE id = #{id}; </update> <delete id="deleteUser" parameterType="int"> DELETE FROM users WHERE id = #{id}; </delete> </mapper>
5、配置 MyBatis
創(chuàng)建mybatis-config.xml
配置文件:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/your_database"/> <property name="username" value="your_username"/> <property name="password" value="your_password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="your/package/name/UserMapper.xml"/> </mappers> </configuration>
在代碼中加載配置文件并使用 MyBatis:
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; public class MyBatisExample { public static void main(String[] args) { String resource = "mybatis-config.xml"; InputStream inputStream = null; try { inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); // 獲取映射接口的實(shí)現(xiàn) UserMapper userMapper = sqlSession.getMapper(UserMapper.class); // 查詢所有用戶 List<User> users = userMapper.getAllUsers(); for (User user : users) { System.out.println(user.getId() + ", " + user.getUsername() + ", " + user.getPassword()); } // 插入用戶 User newUser = new User(); newUser.setUsername("newUser"); newUser.setPassword("newPassword"); userMapper.insertUser(newUser); sqlSession.commit(); // 根據(jù) ID 查詢用戶 User userById = userMapper.getUserById(1); System.out.println(userById.getId() + ", " + userById.getUsername() + ", " + userById.getPassword()); // 更新用戶 User userToUpdate = userMapper.getUserById(2); userToUpdate.setUsername("updatedUser"); userMapper.updateUser(userToUpdate); sqlSession.commit(); // 刪除用戶 userMapper.deleteUser(3); sqlSession.commit(); sqlSession.close(); } catch (IOException e) { e.printStackTrace(); } } }
總結(jié)
到此這篇關(guān)于Java中連接數(shù)據(jù)庫(kù)方式詳細(xì)步驟的文章就介紹到這了,更多相關(guān)Java連接數(shù)據(jù)庫(kù)方式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java8 List<Object>去掉重復(fù)對(duì)象的幾種方法
本文主要介紹了java8 List<Object>去掉重復(fù)對(duì)象的幾種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-04-04Java實(shí)現(xiàn)字符串的分割(基于String.split()方法)
Java中的我們可以利用split把字符串按照指定的分割符進(jìn)行分割,然后返回字符串?dāng)?shù)組,下面這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)字符串的分割的相關(guān)資料,是基于jDK1.8版本中的String.split()方法,需要的朋友可以參考下2022-09-09Java 中的字符串替換方法之replace, replaceAll 和 rep
在Java中,字符串的替換是一種常見(jiàn)的操作,特別是在處理文本和格式化輸出時(shí),本文將詳細(xì)討論這些方法的用法、區(qū)別以及示例,感興趣的朋友一起看看吧2024-12-12Java使用NIO包實(shí)現(xiàn)Socket通信的實(shí)例代碼
本篇文章主要介紹了Java使用NIO包實(shí)現(xiàn)Socket通信的實(shí)例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-02-02java字節(jié)碼框架ASM操作字節(jié)碼的方法淺析
這篇文章主要給大家介紹了關(guān)于java字節(jié)碼框架ASM如何操作字節(jié)碼的相關(guān)資料,文中通過(guò)示例代碼介紹的很詳細(xì),有需要的朋友可以參考借鑒,下面來(lái)一起看看吧。2017-01-01JavaWeb實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)(3)
這篇文章主要為大家詳細(xì)介紹了JavaWeb實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)第三篇,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08