日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

手撸一个JdbcTemplate,带你了解其原理

發布時間:2023/11/28 生活经验 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 手撸一个JdbcTemplate,带你了解其原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前提要求

  • 能夠使用jdbc鏈接數據庫
  • 能夠利用jdbc完成數據庫的增刪改查等操作
  • 對泛型有一定的了解

基本原理

  • 通過jdbc鏈接數據庫,查詢數據庫中內容
  • 利用反射對數據庫中查詢字段進行封裝

步驟

1、創建項目

  • 創建Maven工程
  • 輸入項目名稱
  • 創建resource文件目錄:父目錄為java文件夾
  • 設置resource文件夾為resource文件夾:單擊文件,項目結構

    工程創建到此結束。

2、代碼編寫

2.1 maven導包,配置pom文件

  • 添加依賴
    mysql依賴、druid連接池依賴
 <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><!-- https://mvnrepository.com/artifact/com.alibaba/druid --><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.5</version></dependency>

2.2 druid配置

resource文件夾下面創建文件并命名為:druid.properties 名稱可以隨便
并在文件中添加配置信息:

druid.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&serverTimezone=Asia/Shanghai
druid.driverClassName=com.mysql.cj.jdbc.Driver
druid.username=root
druid.password=123456

根據自己的不同,自行修改

2.3 創建數據庫以及表

CREATE DATABASE /*!32312 IF NOT EXISTS*/`demo` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;USE `demo`;/*Table structure for table `user` */DROP TABLE IF EXISTS `user`;CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT,`username` varchar(30) COLLATE utf8mb4_general_ci NOT NULL,`age` int NOT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;/*Data for the table `user` */insert  into `user`(`id`,`username`,`age`) values 
(1,'張三',20),
(2,'李四',21),
(3,'王五',33),
(4,'陳六',25);

創建之后的數據展示:

2.4 創建數據庫對應的Java實體類

import java.util.Objects;public class User {private Long id;private String username;private Integer age;public User() {}public User(Long id, String username, Integer age) {this.id = id;this.username = username;this.age = age;}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}@Overridepublic boolean equals(Object o) {if (this == o) return true;if (o == null || getClass() != o.getClass()) return false;User user = (User) o;return Objects.equals(id, user.id) && Objects.equals(username, user.username) && Objects.equals(age, user.age);}@Overridepublic int hashCode() {return Objects.hash(id, username, age);}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", age=" + age +'}';}
}

2.5 創建DBUtils


public class DBUtils {private static DataSource dataSource;static {// 配置文件try {InputStream is = App.class.getClassLoader().getResourceAsStream("druid.properties");Properties properties = new Properties();properties.load(is);dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (IllegalArgumentException e) {System.out.println("文件有誤");} catch (IOException e) {System.out.println("打開配置文件失敗");} catch (Exception e) {System.out.println("德魯伊數據源創建失敗");}}/*** 獲取鏈接** @return 數據庫鏈接*/public static Connection getConnection() {Connection connection = null;try {connection = dataSource.getConnection();} catch (SQLException e) {e.printStackTrace();}return connection;}/*** 資源釋放*/public static void release(Connection connection, Statement statement, RowSet rowSet) {try {release(connection, statement, null, rowSet);} catch (SQLException e) {e.printStackTrace();}}public static void release(Connection connection, Statement statement, ResultSet resultSet) {try {release(connection, statement, resultSet, null);} catch (SQLException e) {e.printStackTrace();}}public static void release(Connection connection, Statement statement, ResultSet resultSet, RowSet rowSet) throws SQLException {if (rowSet != null) {rowSet.close();}if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}}}

2.6 創建JDBCTemplate抽象類

import java.util.List;public abstract class JdbcTemplate<T> {protected Class<T> entityClass;protected JdbcTemplate(Class<T> entityClass) {this.entityClass = entityClass;}public abstract List<T> query(String sql, Object... args);}

2.7 創建QueryTemplate查詢模板

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.*;public class QueryTemplate<T> extends JdbcTemplate<T> {public QueryTemplate(Class<T> entityClass) {super(entityClass);}@Overridepublic List<T> query(String sql, Object... args) {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet = null;List<T> result = new ArrayList<>();try {connection = DBUtils.getConnection();preparedStatement = connection.prepareStatement(sql);// 設置參數for (int i = 1; i <= args.length; i++) {setValue(i, args[i - 1], preparedStatement);}resultSet = preparedStatement.executeQuery();Map<String, String> metaMap = getMetaMap(preparedStatement);while (resultSet.next()) {T entity = getEntity(preparedStatement, resultSet);result.add(entity);}} catch (Exception e) {e.printStackTrace();} finally {DBUtils.release(connection, preparedStatement, resultSet);}return result;}/*** 獲得具體的對象,并賦值*/private T getEntity(PreparedStatement preparedStatement, ResultSet resultSet) {Map<String, String> metaMap = getMetaMap(preparedStatement);try {T object = entityClass.newInstance();Set<String> keySet = metaMap.keySet();for (String key : keySet) {Object value = getValue(key, metaMap.get(key), resultSet);// 獲取屬性Field field = entityClass.getDeclaredField(key);Method declaredMethod = entityClass.getMethod(constructSetMethod(key), field.getType());declaredMethod.invoke(object, value);}return object;} catch (Exception e) {e.printStackTrace();}return null;}/*** 獲得數據庫中 字段名稱與數據類型的映射* @return Map*/private static Map<String, String> getMetaMap(PreparedStatement preparedStatement) {Map<String, String> metaMap = new HashMap<>();try {ResultSetMetaData metaData = preparedStatement.getMetaData();// 遍歷元素for (int i = 1; i <= metaData.getColumnCount(); i++) {String columnName = metaData.getColumnName(i);String columnTypeName = metaData.getColumnTypeName(i);metaMap.put(columnName, columnTypeName);}} catch (SQLException e) {e.printStackTrace();}return metaMap;}/*** 根據具體字段獲得其屬性賦值方法* @param key 成員名稱* @return 方法名稱*/private static String constructSetMethod(String key) {String substring = key.substring(0, 1).toUpperCase() + key.substring(1);return "set" + substring;}/*** 預編譯statement賦值* @param index 參數占位符 索引* @param value 具體值*/private static void setValue(int index, Object value, PreparedStatement preparedStatement) {// 獲得類型String typeName = value.getClass().getTypeName();try {switch (typeName) {case "java.lang.Long":preparedStatement.setLong(index, Long.parseLong(value.toString()));break;case "java.lang.String":preparedStatement.setString(index, value.toString());break;case "java.lang.Integer":preparedStatement.setInt(index, Integer.parseInt(value.toString()));break;}} catch (SQLException e) {e.printStackTrace();}}/*** 從ResultSet中獲取對應的值* @param key 字段* @param typeName 返回數據類型* @param resultSet 結果集* @return 值*/private static Object getValue(String key, String typeName, ResultSet resultSet) {Object value = null;try {switch (typeName) {case "BIGINT":value = resultSet.getLong(key);break;case "INT":value = resultSet.getInt(key);break;case "VARCHAR":value = resultSet.getString(key);break;}} catch (SQLException e) {e.printStackTrace();}return value;}}

創建程序入口類App

public class App {public static void main(String[] args) {JdbcTemplate<User> jdbcTemplate= new QueryTemplate<>(User.class);// 定義sql語句String sql = "select * from user where age > 20";// 執行List<User> users = jdbcTemplate.query(sql);for (User user : users) {System.out.println(user);}}
}

運行結果:

總結: 通過這段代碼,基本上就能夠知道如何去封裝一個數據集,這也是ORM框架的基本封裝思路,主要是數據查詢比較麻煩,數據封裝較為繁瑣,其他的方法可以入法炮制,這里不再演示。讀者也可以自行測試其他類,或者完成其他操作的封裝。

項目Gitee地址

總結

以上是生活随笔為你收集整理的手撸一个JdbcTemplate,带你了解其原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。