1. 程式人生 > 其它 >Orm-JDBC(物件關係對映的資料庫查詢)

Orm-JDBC(物件關係對映的資料庫查詢)

技術標籤:mysqljava

Orm-JDBC(物件關係對映的資料庫查詢)

大致說明

實現將資料庫查詢結果用物件封裝,連線池採用的druid連線池
示例:

public static void main(String[] args) {
        CommonDao dao=new CommonDao();
        String sql="select * from tb_goods where id=?";
        TbGoods object = dao.findObject(sql, TbGoods.class,2);
        System.err.println(object);
 }
    
二月 14, 2021 9:22:50 下午 com.alibaba.druid.pool.DruidDataSource info
資訊: {dataSource-1} inited
TbGoods{id='2', name='12', remark='112', createdTime=Sat Jan 16 14:05:33 CST 2021}
配置檔案
#驅動載入
driverClassName=com.mysql.cj.jdbc.Driver
#註冊驅動
url=jdbc:mysql://42.193.171.7:3306/dbgoods?serverTimezone=GMT%2B8&characterEncoding=utf-8
#連線資料庫的使用者名稱
username=root
#連線資料庫的密碼
password=Gepoint
#屬性型別的字串,通過別名的方式配置擴充套件外掛, 監控統計用的stat 日誌用log4j 防禦sql注入:wall
filters=stat
#初始化時池中建立的物理連線個數。
initialSize=2
#最大的可活躍的連線池數量
maxActive=300
#獲取連線時最大等待時間,單位毫秒,超過連線就會失效。配置了maxWait之後,預設啟用公平鎖,併發效率會有所下降, 如果需要可以通過配置useUnfairLock屬性為true使用非公平鎖。
maxWait=60000
#連接回收器的執行週期時間,時間到了清理池中空閒的連線,testWhileIdle根據這個判斷
timeBetweenEvictionRunsMillis=60000
minEvictableIdleTimeMillis=300000
#用來檢測連線是否有效的sql,要求是一個查詢語句。
validationQuery=SELECT 1
#建議配置為true,不影響效能,並且保證安全性。 申請連線的時候檢測,如果空閒時間大於timeBetweenEvictionRunsMillis, 執行validationQuery檢測連線是否有效。
testWhileIdle=true
#申請連線時執行validationQuery檢測連線是否有效,做了這個配置會降低效能。設定為false
testOnBorrow=false
#歸還連線時執行validationQuery檢測連線是否有效,做了這個配置會降低效能,設定為flase
testOnReturn=false
#是否快取preparedStatement,也就是PSCache。
poolPreparedStatements=false
#池中能夠緩衝的preparedStatements語句數量
maxPoolPreparedStatementPerConnectionSize=200

druid 連線工具類
package com.epoint.util;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidUtils {
    //Druid德魯伊,據說是魔獸世界中的一個角色,森林女神
    public static DruidDataSource dataSource;//資料庫連線池

    //1.初始化Druid連線池
    static {
        //第二種方式:使用軟編碼通過配置檔案初始化
        try {
            Properties properties = new Properties();
            //通過類載入器載入配置檔案
            InputStream inputStream = DruidUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            properties.load(inputStream);
            //建立連線池
            dataSource = (DruidDataSource) DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //2.獲取連線
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();//從連線池中獲取連線
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static DataSource getDataSource(){
        return dataSource;
    }

    //3.釋放資源
    public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
        //釋放resultSet
        try {
            if (resultSet != null) {
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //釋放Statement
        try {
            if (statement != null) {
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //釋放Connection
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

}


CommonDao 持久化dao
package com.epoint.util;

import java.lang.reflect.Method;
import java.sql.*;
import java.text.SimpleDateFormat;

public class CommonDao
{
    private static Connection conn = null;

    static {
        conn=DruidUtils.getConnection();
    }

    /**
     * 獲取例項化CommonDao
     */
    public CommonDao getInstance() {
        CommonDao dao = new CommonDao();
        return dao;
    }

    /**
     * 查詢一條資料
     * @param sql 需要查詢的sql
     * @param cls 對映的物件
     * @param params sql中的引數
     * @param <T> 泛型
     * @return 返回傳入物件型別
     */
    public <T> T findObject(String sql, Class cls, Object... params) {
        Object obj =null;
        try {
            //3.通過資料庫的連線操作資料庫,實現增刪改查
            PreparedStatement statement = conn.prepareStatement(sql);
            //獲取需要傳入引數的個數
            ParameterMetaData parameterMetaData = statement.getParameterMetaData();
            //如果需要傳入的引數個人大於>0則需要設定引數
            if(parameterMetaData.getParameterCount()>0){
                for (int i = 1; i <= parameterMetaData.getParameterCount(); i++) {
                    statement.setString(1, params[i-1].toString());
                }
            }

            //4.獲取結果集
            ResultSet resultSet =statement.executeQuery();

            //6.獲取結果集元資料
            ResultSetMetaData metaData = resultSet.getMetaData();
            //7.獲取欄位的個數
            int columnCount = metaData.getColumnCount();
            //是否例項化的開關,保證物件只例項化一次
            boolean flag=true;
            //8.遍歷  建立類物件(來接資料查詢出來的資料)
            while (resultSet.next()) {
                if(flag){
                    obj = cls.getConstructor(null).newInstance(null);
                    flag=false;
                }
                for (int i = 1; i <= columnCount; i++) {
                    //9.獲取欄位的名字
                    String columnName = metaData.getColumnName(i);//id, name ,age
                    //10.獲取對應欄位的資料
                    Object value = resultSet.getObject(columnName);
                    //11.給指定欄位的資料在類物件中給賦值
                    setValue(columnName, value, obj, cls);
                }
            }
            DruidUtils.closeAll(conn,statement,resultSet);
        }catch (Exception e){
            e.printStackTrace();
        }
        //返回查詢到的物件
        return (T) obj;
    }

    private void setValue(String field, Object value, Object obj, Class cls) throws Exception {
        //獲取物件中的方法陣列
        Method[] method = cls.getMethods();
        //加上資料庫欄位加上set
        String fieldName = "set" + field;
        for (int n = 0; n < method.length; n++) {
            //如果匹配到對應的set方法則執行賦值操作
            if (method[n].getName().equalsIgnoreCase(fieldName)) {
                //獲取方法引數資料型別
                String[] clsList = method[n].getParameterTypes()[0].getName().split("\\.");
                String type = clsList[clsList.length - 1];
                switch (type) {
                    case "Integer":
                    case "int":
                        method[n].invoke(obj, Integer.parseInt(value.toString()));//給對應的方法引數賦值
                        break;

                    case "Double":
                    case "double":
                        method[n].invoke(obj, Double.parseDouble(value.toString()));
                        break;

                    case "Long":
                    case "long":
                        method[n].invoke(obj, Long.parseLong(value.toString()));
                        break;

                    case "Float":
                    case "float":
                        method[n].invoke(obj, Float.parseFloat(value.toString()));
                        break;

                    case "Date":
                        method[n].invoke(obj, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value.toString()));
                        break;
                    case "String":
                        method[n].invoke(obj, value.toString());
                        break;
                }
                break;
            }
        }
    }
}

測試

在這裡插入圖片描述

  • 步驟一:建立查詢物件
package com.epoint.entity;

import java.util.Date;
public class TbGoods
{
    private String id;
    private String name;
    private String remark;
    private Date createdTime;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    public Date getCreatedTime() {
        return createdTime;
    }

    public void setCreatedTime(Date createdTime) {
        this.createdTime = createdTime;
    }

    @Override
    public String toString() {
        return "TbGoods{" + "id='" + id + '\'' + ", name='" + name + '\'' + ", remark='" + remark + '\'' + ", createdTime=" + createdTime + '}';
    }
}

  • 步驟二 建立測試類,傳入sql
package com.epoint.test;

import com.epoint.entity.TbGoods;
import com.epoint.util.CommonDao;

public class Test
{
    public static void main(String[] args) {
        CommonDao dao=new CommonDao();
        String sql="select * from tb_goods where id=?";
        TbGoods object = dao.findObject(sql, TbGoods.class,2,3);
        System.err.println(object);
    }
}

結果

二月 14, 2021 9:22:50 下午 com.alibaba.druid.pool.DruidDataSource info
資訊: {dataSource-1} inited
TbGoods{id='2', name='12', remark='112', createdTime=Sat Jan 16 14:05:33 CST 2021}

程序已結束,退出程式碼0

程式還在不斷編寫中,希望有喜歡的朋友加入一起完成
加粗樣式