JDBC 與 MyBatis從基礎到實踐
一、JDBC 介紹
JDBC(Java Database Connectivity)即 Java 數(shù)據(jù)庫連接,是 Java 語言中用來規(guī)范客戶端程序如何來訪問數(shù)據(jù)庫的應用程序接口,提供了諸如查詢和更新數(shù)據(jù)庫中數(shù)據(jù)的方法。它由一組用 Java 語言編寫的類和接口組成,使得 Java 程序能夠與各種關系型數(shù)據(jù)庫進行交互,如 MySQL、Oracle、SQL Server 等。通過 JDBC,開發(fā)人員可以在 Java 代碼中執(zhí)行 SQL 語句,處理數(shù)據(jù)庫事務,獲取查詢結果等。
二、使用 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()方法獲取數(shù)據(jù)庫連接,然后創(chuàng)建Statement對象用于執(zhí)行 SQL 語句,最后執(zhí)行executeQuery()方法獲取ResultSet結果集,并遍歷結果集輸出用戶信息。
三、ResultSet 結果集
ResultSet是 JDBC 中用于存儲數(shù)據(jù)庫查詢結果的對象。它就像一個表格,每一行代表一條記錄,每一列代表一個字段。ResultSet提供了一系列方法來訪問其中的數(shù)據(jù),如getInt()、getString()、getDouble()等,根據(jù)字段的數(shù)據(jù)類型來獲取相應的值。同時,ResultSet有一個游標,默認位于第一行之前,通過next()方法可以將游標移動到下一行,當游標指向有效行時,才能獲取該行的數(shù)據(jù)。當游標移動到結果集的末尾(即next()方法返回false)時,表示結果集遍歷結束。
四、預編譯 SQL - SQL 注入問題
SQL 注入是一種常見的安全漏洞,攻擊者通過在輸入?yún)?shù)中插入惡意的 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 語句先發(fā)送到數(shù)據(jù)庫進行編譯,然后再將參數(shù)傳遞給已經(jīng)編譯好的語句。在 JDBC 中,使用
PreparedStatement來實現(xiàn)預編譯 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()等方法設置參數(shù),這樣數(shù)據(jù)庫會將參數(shù)作為普通值處理,而不會將其解析為 SQL 代碼,從而避免了 SQL 注入問題。
五、預編譯 SQL - 性能更高
預編譯 SQL 除了能防止 SQL 注入外,還具有更高的性能。當使用普通的
Statement執(zhí)行 SQL 語句時,數(shù)據(jù)庫每次都需要對 SQL 語句進行語法解析、查詢優(yōu)化等操作。而預編譯 SQL 會將 SQL 語句先編譯好,后續(xù)如果執(zhí)行相同結構的 SQL 語句,只需要傳遞參數(shù)即可,數(shù)據(jù)庫不需要再次進行語法解析和查詢優(yōu)化,從而提高了執(zhí)行效率。特別是在需要頻繁執(zhí)行相同結構 SQL 語句的場景下,預編譯 SQL 的性能優(yōu)勢更加明顯。
六、JDBC 增刪改操作
以下是使用 JDBC 進行增刪改操作的示例代碼:
插入數(shù)據(jù):
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();
}
}
}更新數(shù)據(jù):
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();
}
}
}刪除數(shù)據(jù):
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 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數(shù)以及獲取結果集,它可以使用簡單的 XML 或注解來配置和映射原生信息,將接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 對象)映射成數(shù)據(jù)庫中的記錄。MyBatis 對 JDBC 進行了封裝,使得數(shù)據(jù)庫操作更加簡潔、高效,同時也提高了代碼的可維護性和可擴展性。
八、MyBatis 入門程序
以下是一個簡單的 MyBatis 入門示例:
引入依賴:
在 Maven 項目的
pom.xml文件中添加 MyBatis 和數(shù)據(jù)庫驅(qū)動依賴:
<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>創(chuàng)建實體類:
public class User {
private int id;
private String username;
private String email;
private String password;
// 省略 getters 和 setters
}創(chuàng)建 SQL 映射文件(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="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 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/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 提示
為了在開發(fā)過程中獲得更好的 SQL 提示,可以使用一些 IDE 插件,如在 IntelliJ IDEA 中安裝 MyBatis Log Plugin 等插件,這些插件可以將 MyBatis 執(zhí)行的 SQL 語句打印出來,并對 SQL 語法進行高亮顯示和提示,方便開發(fā)人員調(diào)試和優(yōu)化 SQL 語句。同時,也可以在 SQL 映射文件中使用
<!-- -->進行注釋,對 SQL 語句的功能和邏輯進行說明,提高代碼的可讀性。
十、MyBatis 輔助配置 - 日志輸出
MyBatis 支持配置日志輸出,以便更好地了解程序的執(zhí)行情況??梢酝ㄟ^在
mybatis-config.xml文件中配置日志工廠來實現(xiàn)。例如,使用 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 執(zhí)行的 SQL 語句等信息就會按照配置的日志級別進行輸出。
十一、MyBatis 數(shù)據(jù)庫連接池
MyBatis 支持使用不同的數(shù)據(jù)庫連接池,如
POOLED連接池(默認)、UNPOOLED連接池等。POOLED連接池會管理一定數(shù)量的數(shù)據(jù)庫連接,當需要連接時從連接池中獲取,使用完畢后再歸還到連接池,這樣可以避免頻繁地創(chuàng)建和銷毀數(shù)據(jù)庫連接,提高性能。在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 實現(xiàn)刪除用戶的示例:
在 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()方法執(zhí)行刪除操作,最后調(diào)用sqlSession.commit()方法提交事務。通過以上對 JDBC 和 MyBatis 的詳細介紹和示例代碼,希望能幫助讀者更好地理解和掌握這兩種數(shù)據(jù)庫操作技術,在實際項目中選擇合適的方式進行數(shù)據(jù)庫開發(fā)。
到此這篇關于JDBC 與 MyBatis從基礎到實踐的文章就介紹到這了,更多相關JDBC 與 MyBatis詳解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
- MyBatis 如何簡化的 JDBC(思路詳解)
- 詳解如何使用MyBatis簡化JDBC開發(fā)
- MyBatis中的JdbcType映射使用詳解
- sharding-jdbc 兼容 MybatisPlus動態(tài)數(shù)據(jù)源的配置方法
- MySQL text類型對應mybatis jdbcType類型方式
- 解決mybatis plus報錯com.microsoft.sqlserver.jdbc.SQLServerException:必須執(zhí)行該語句才能獲得結果
- 淺談MyBatis所有的jdbcType類型
- SpringBoot多數(shù)據(jù)源配置詳細教程(JdbcTemplate、mybatis)
相關文章
淺談MultipartFile中transferTo方法的坑
這篇文章主要介紹了MultipartFile中transferTo方法的坑,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07
Mybatis開發(fā)要點-resultType和resultMap有什么區(qū)別詳解
本文主要介紹了Mybatis開發(fā)要點-resultType和resultMap有什么區(qū)別詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2022-04-04
java通過反射創(chuàng)建對象并調(diào)用方法
這篇文章主要介紹了java通過反射創(chuàng)建對象并調(diào)用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-01-01
Java實現(xiàn)數(shù)組去除重復數(shù)據(jù)的方法詳解
這篇文章主要介紹了Java實現(xiàn)數(shù)組去除重復數(shù)據(jù)的方法,結合實例形式詳細分析了java數(shù)組去除重復的幾種常用方法、實現(xiàn)原理與相關注意事項,需要的朋友可以參考下2017-09-09

