目錄
一、JDBC 介紹
二、使用 JDBC 查詢用戶信息
三、ResultSet 結果集
四、預編譯 SQL - SQL 注入問題
五、預編譯 SQL - 性能更高
六、JDBC 增刪改操作
插入數據:
更新數據:
?刪除數據:
七、MyBatis 介紹
八、MyBatis 入門程序
引入依賴:
?創建實體類:
?創建 SQL 映射文件(UserMapper.xml):
?配置 MyBatis 核心文件(mybatis-config.xml):
?編寫測試代碼:
九、MyBatis 輔助配置 - SQL 提示
十、MyBatis 輔助配置 - 日志輸出
引入 Log4j 依賴:
?配置 Log4j 配置文件(log4j2.xml)
?在 MyBatis 配置文件中啟用日志:
十一、MyBatis 數據庫連接池
十二、MyBatis 增刪改查 - 刪除用戶
在 SQL 映射文件(UserMapper.xml)中添加刪除語句:
?在接口(UserMapper.java)中添加對應的方法:
?編寫測試代碼:
一、JDBC 介紹
????????JDBC(Java Database Connectivity)即 Java 數據庫連接,是 Java 語言中用來規范客戶端程序如何來訪問數據庫的應用程序接口,提供了諸如查詢和更新數據庫中數據的方法。它由一組用 Java 語言編寫的類和接口組成,使得 Java 程序能夠與各種關系型數據庫進行交互,如 MySQL、Oracle、SQL Server 等。通過 JDBC,開發人員可以在 Java 代碼中執行 SQL 語句,處理數據庫事務,獲取查詢結果等。
二、使用 JDBC 查詢用戶信息
下面是一個簡單的使用 JDBC 查詢用戶信息的示例代碼:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JDBCUserQuery {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "password";try (Connection connection = DriverManager.getConnection(url, user, password);Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM users")) {while (resultSet.next()) {int id = resultSet.getInt("id");String username = resultSet.getString("username");String email = resultSet.getString("email");System.out.println("ID: " + id + ", Username: " + username + ", Email: " + email);}} catch (SQLException e) {e.printStackTrace();}}
}
????????在上述代碼中,首先通過?
DriverManager.getConnection()
?方法獲取數據庫連接,然后創建?Statement
?對象用于執行 SQL 語句,最后執行?executeQuery()
?方法獲取?ResultSet
?結果集,并遍歷結果集輸出用戶信息。
三、ResultSet 結果集
????????
ResultSet
?是 JDBC 中用于存儲數據庫查詢結果的對象。它就像一個表格,每一行代表一條記錄,每一列代表一個字段。ResultSet
?提供了一系列方法來訪問其中的數據,如?getInt()
、getString()
、getDouble()
?等,根據字段的數據類型來獲取相應的值。同時,ResultSet
?有一個游標,默認位于第一行之前,通過?next()
?方法可以將游標移動到下一行,當游標指向有效行時,才能獲取該行的數據。當游標移動到結果集的末尾(即?next()
?方法返回?false
)時,表示結果集遍歷結束。
四、預編譯 SQL - SQL 注入問題
????????SQL 注入是一種常見的安全漏洞,攻擊者通過在輸入參數中插入惡意的 SQL 代碼,從而改變原本 SQL 語句的邏輯,獲取敏感信息或進行非法操作。例如,在一個用戶登錄驗證的場景中,如果使用普通的 SQL 語句拼接用戶輸入:
String username = request.getParameter("username");
String password = request.getParameter("password");
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
????????如果用戶輸入的?
username
?為?' OR '1'='1
,那么拼接后的 SQL 語句就變成了?SELECT * FROM users WHERE username = '' OR '1'='1' AND password = ''
,這樣無論密碼是否正確,都能成功登錄。????????預編譯 SQL 可以有效防止 SQL 注入問題。預編譯 SQL 是將 SQL 語句先發送到數據庫進行編譯,然后再將參數傳遞給已經編譯好的語句。在 JDBC 中,使用?
PreparedStatement
?來實現預編譯 SQL:
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
String username = request.getParameter("username");
String password = request.getParameter("password");try (Connection connection = DriverManager.getConnection(url, user, password);PreparedStatement preparedStatement = connection.prepareStatement("SELECT * FROM users WHERE username =? AND password =?")) {preparedStatement.setString(1, username);preparedStatement.setString(2, password);ResultSet resultSet = preparedStatement.executeQuery();// 處理結果集
} catch (SQLException e) {e.printStackTrace();
}
????????在上述代碼中,使用?
?
?作為占位符,然后通過?setString()
?等方法設置參數,這樣數據庫會將參數作為普通值處理,而不會將其解析為 SQL 代碼,從而避免了 SQL 注入問題。
五、預編譯 SQL - 性能更高
????????預編譯 SQL 除了能防止 SQL 注入外,還具有更高的性能。當使用普通的?
Statement
?執行 SQL 語句時,數據庫每次都需要對 SQL 語句進行語法解析、查詢優化等操作。而預編譯 SQL 會將 SQL 語句先編譯好,后續如果執行相同結構的 SQL 語句,只需要傳遞參數即可,數據庫不需要再次進行語法解析和查詢優化,從而提高了執行效率。特別是在需要頻繁執行相同結構 SQL 語句的場景下,預編譯 SQL 的性能優勢更加明顯。
六、JDBC 增刪改操作
以下是使用 JDBC 進行增刪改操作的示例代碼:
插入數據:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class JDBCInsert {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "password";try (Connection connection = DriverManager.getConnection(url, user, password);PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO users (username, email, password) VALUES (?,?,?)")) {preparedStatement.setString(1, "newuser");preparedStatement.setString(2, "newuser@example.com");preparedStatement.setString(3, "newpassword");int rowsInserted = preparedStatement.executeUpdate();if (rowsInserted > 0) {System.out.println("A new user was inserted successfully!");}} catch (SQLException e) {e.printStackTrace();}}
}
更新數據:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class JDBCUpdate {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "password";try (Connection connection = DriverManager.getConnection(url, user, password);PreparedStatement preparedStatement = connection.prepareStatement("UPDATE users SET password =? WHERE username =?")) {preparedStatement.setString(1, "newpassword123");preparedStatement.setString(2, "newuser");int rowsUpdated = preparedStatement.executeUpdate();if (rowsUpdated > 0) {System.out.println("User password was updated successfully!");}} catch (SQLException e) {e.printStackTrace();}}
}
?刪除數據:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;public class JDBCDelete {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydb";String user = "root";String password = "password";try (Connection connection = DriverManager.getConnection(url, user, password);PreparedStatement preparedStatement = connection.prepareStatement("DELETE FROM users WHERE username =?")) {preparedStatement.setString(1, "newuser");int rowsDeleted = preparedStatement.executeUpdate();if (rowsDeleted > 0) {System.out.println("User was deleted successfully!");}} catch (SQLException e) {e.printStackTrace();}}
}
七、MyBatis 介紹
????????MyBatis 是一款優秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集,它可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 對象)映射成數據庫中的記錄。MyBatis 對 JDBC 進行了封裝,使得數據庫操作更加簡潔、高效,同時也提高了代碼的可維護性和可擴展性。
八、MyBatis 入門程序
以下是一個簡單的 MyBatis 入門示例:
引入依賴:
在 Maven 項目的?
pom.xml
?文件中添加 MyBatis 和數據庫驅動依賴:
<dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.9</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.26</version></dependency>
</dependencies>
?創建實體類:
public class User {private int id;private String username;private String email;private String password;// 省略 getters 和 setters
}
?創建 SQL 映射文件(UserMapper.xml):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.UserMapper"><select id="getUserById" parameterType="int" resultType="com.example.User">SELECT * FROM users WHERE id = #{id}</select>
</mapper>
?配置 MyBatis 核心文件(mybatis-config.xml):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//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/mydb"/><property name="username" value="root"/><property name="password" value="password"/></dataSource></environment></environments><mappers><mapper resource="UserMapper.xml"/></mappers>
</configuration>
?編寫測試代碼:
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 MyBatisTest {public static void main(String[] args) throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.getUserById(1);System.out.println(user.getUsername());}}
}
九、MyBatis 輔助配置 - SQL 提示
????????為了在開發過程中獲得更好的 SQL 提示,可以使用一些 IDE 插件,如在 IntelliJ IDEA 中安裝 MyBatis Log Plugin 等插件,這些插件可以將 MyBatis 執行的 SQL 語句打印出來,并對 SQL 語法進行高亮顯示和提示,方便開發人員調試和優化 SQL 語句。同時,也可以在 SQL 映射文件中使用?
<!-- -->
?進行注釋,對 SQL 語句的功能和邏輯進行說明,提高代碼的可讀性。
十、MyBatis 輔助配置 - 日志輸出
????????MyBatis 支持配置日志輸出,以便更好地了解程序的執行情況。可以通過在?
mybatis-config.xml
?文件中配置日志工廠來實現。例如,使用 Log4j 作為日志框架:
引入 Log4j 依賴:
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-api</artifactId><version>2.14.1</version>
</dependency>
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.14.1</version>
</dependency>
?配置 Log4j 配置文件(log4j2.xml)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN"><Appenders><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Console></Appenders><Loggers><Root level="error"><AppenderRef ref="Console"/></Root><Logger name="com.example" level="debug"/></Loggers>
</Configuration>
?在 MyBatis 配置文件中啟用日志:
<configuration><settings><setting name="logImpl" value="LOG4J2"/></settings><!-- 其他配置 -->
</configuration>
這樣,MyBatis 執行的 SQL 語句等信息就會按照配置的日志級別進行輸出。
十一、MyBatis 數據庫連接池
????????MyBatis 支持使用不同的數據庫連接池,如?
POOLED
?連接池(默認)、UNPOOLED
?連接池等。POOLED
?連接池會管理一定數量的數據庫連接,當需要連接時從連接池中獲取,使用完畢后再歸還到連接池,這樣可以避免頻繁地創建和銷毀數據庫連接,提高性能。在?mybatis-config.xml
?文件中配置?POOLED
?連接池的示例如下:
<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/mydb"/><property name="username" value="root"/><property name="password" value="password"/></dataSource>
</environment>
????????此外,也可以使用第三方連接池,如 HikariCP、C3P0 等,只需要在項目中引入相應的依賴,并在 MyBatis 配置文件中進行相應的配置即可。
十二、MyBatis 增刪改查 - 刪除用戶
以下是使用 MyBatis 實現刪除用戶的示例:
在 SQL 映射文件(UserMapper.xml)中添加刪除語句:
<mapper namespace="com.example.UserMapper"><!-- 其他語句 --><delete id="deleteUserById" parameterType="int">DELETE FROM users WHERE id = #{id}</delete>
</mapper>
?在接口(UserMapper.java)中添加對應的方法:
public interface UserMapper {// 其他方法int deleteUserById(int id);
}
?編寫測試代碼:
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 MyBatisDeleteTest {public static void main(String[] args) throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);try (SqlSession sqlSession = sqlSessionFactory.openSession()) {UserMapper userMapper = sqlSession.getMapper(UserMapper.class);int rowsDeleted = userMapper.deleteUserById(1);if (rowsDeleted > 0) {System.out.println("User was deleted successfully!");}sqlSession.commit();}}
}
????????在上述代碼中,通過?
UserMapper
?接口的?deleteUserById()
?方法執行刪除操作,最后調用?sqlSession.commit()
?方法提交事務。????????通過以上對 JDBC 和 MyBatis 的詳細介紹和示例代碼,希望能幫助讀者更好地理解和掌握這兩種數據庫操作技術,在實際項目中選擇合適的方式進行數據庫開發。