JDBC与数据库之间的操作(增删改查、获取主键、业务逻辑分离、属性文件配置)

参考视频哔哩哔哩

1、Service和Servicelmpl的概念

java中service和servicelmpl是常见的代码组织方式

  • Service是指业务逻辑的接口,定义了系统对外提供的功能。Servicelmpl是Service接口的具体实现,实现了具体的业务逻辑。

Service和Servicelmpl的好处
使用Service和Servicelmpl的方式可以带来以下好处:

  1. 代码分层清晰:通过将业务逻辑抽象为接口和实现类的方式,可以将不同层次的代码分离,提高代码的可读性和可维护性

  2. 便于扩展和测试:由于业务逻辑被封装在Service中,当需要添加新的功能时,只需要在Service接口中添加方法,并在Servicelmpl中实现即可。同时,由于业务逻辑和其他层解耦,可以方便地进行单元测试。

  3. 支持事务管理:在实际开发中,往往需要对一组操作进行事务管理。Service的设计可以方便地实现对一组操作的事务管理,保证数据的一致性。

2、DAO(Data Access Object Layer)

DAO层(Data Access Object Layer)是软件开发中的一种设计模式,主要用于将应用程序的业务逻辑与数据访问逻辑分离。DAO层提供了一种抽象的方式来处理数据库操作,使得数据存取和业务逻辑之间的解耦更为清晰。

2、1 DAO层的特点

  1. 职责明确:DAO层专注于数据的持久化与访问,不涉及业务逻辑。
  2. 抽象化:通过接口或类对数据访问进行封装,隐藏具体的数据访问实现细节,比如使用何种数据库、如何执行SQL语句等。
  3. 重用性:可以在多个地方复用相同的数据库访问代码,提高代码的一致性和可维护性。
  4. 易于测试:由于数据访问逻辑被封装,可以方便地使用模拟对象进行单元测试。

2、2 DAO层的组成

  • DAO接口:定义了数据访问的方法,如增、删、改、查等。
  • DAO实现类:实现具体的DAO接口,并包含与数据库交互的代码。
  • VO(Value Object)/DTO(Data Transfer Object):用于在DAO层与其他层之间传递数据的对象。

3、相关代码的实现:

3、1 链接数据库(逻辑和界面未分离):

1、加载驱动

2、创建连接

3、sql预编译

4、执行sql语句

5、关闭连接

java 复制代码
package DBtest;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;

public class jdbctext {
    private static String URL;
    private static String USER;
    private static String PASSWORD;
    private static String DRIVER;

    static {
        try {
            InputStream in = DbUutil.class.getResourceAsStream("DbUtil.properties");
            Properties prop = new Properties();
            prop.load(in);
            DRIVER = prop.getProperty("driver");
            URL = prop.getProperty("url");
            USER = prop.getProperty("user");
            PASSWORD = prop.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConn() throws SQLException {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static int update(String sql, Object... params) throws SQLException {
        Connection conn = getConn();
        PreparedStatement ps = null;
        try {
            ps = conn.prepareStatement(sql);
            setParams(ps, params);
            return ps.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(conn, ps, null);
        }
        return -1;
    }

    public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {
        try {
            if (ps != null) {
                ps.close();
            }
            if (rs != null) {
                rs.close();
            }
            if (conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void setParams(PreparedStatement ps, Object... params) throws SQLException {
        if (params != null && params.length > 0) {
            for (int i = 0; i < params.length; i++) {
                ps.setObject(i + 1, params[i]);
            }
        }
    }

    public static List<List> queryList(String sql, Object... params) throws SQLException {
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<List> lists = new ArrayList<>();
        try {
            ps = conn.prepareStatement(sql);
            setParams(ps, params);
            rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();

            while (rs.next()) {
                List<Object> list = new ArrayList<>();
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    list.add(rs.getObject(i + 1));
                }
                lists.add(list);
            }
            return lists;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(conn, ps, rs);
        }
        return null;
    }

    public static List<Map<String, Object>> queryMap(String sql, Object... params) throws SQLException {
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;
        List<Map<String, Object>> maps = new ArrayList<>();

        try {
            ps = conn.prepareStatement(sql);
            setParams(ps, params);
            rs = ps.executeQuery();
            ResultSetMetaData metaData = rs.getMetaData();

            while (rs.next()) {
                Map<String, Object> map = new HashMap<>();
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    map.put(metaData.getColumnLabel(i + 1), rs.getObject(i + 1));
                }
                maps.add(map);
            }
            return maps;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(conn, ps, rs);
        }
        return null;
    }

    public static int getPrimaryKey(String sql, Object... params) throws SQLException {
        Connection conn = getConn();
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            setParams(ps, params);
            ps.executeUpdate();
            rs = ps.getGeneratedKeys();
            if (rs.next()) {
                return rs.getInt(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeAll(conn, ps, rs);
        }
        return -1;
    }
}

4、业务逻辑分离

4、1 加载配置文件

java 复制代码
public class jdbctext {
 //   Connection con;
    private static String URL;
    private static String USER;
    private static String PASSWORD;
    private static String DRIVER;
    static {
        try {
            InputStream in = DbUutil.class.getResourceAsStream("DbUtil.properties");
            Properties prop = new Properties();
            prop.load(in);
          DRIVER  =prop.getProperty("driver");
          URL = prop.getProperty("url");
          USER = prop.getProperty("user");
          PASSWORD = prop.getProperty("password");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

配置文件DbUtil.properties

java 复制代码
driver  = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/contact?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
user = root
password = 123456

4、2 封装创建连接的方法

java 复制代码
/**
1、方法名:getConn();
2、参数列表  不需要
3、返回值 Connection conn
*/
public static Connection getConn() throws SQLException {
    Connection conn = null;
    
    try {
        conn = DriverManager.getConnection(URL, USER, PASSWORD);
    } catch (SQLException e) {
        e.printStackTrace();
        // throw new RuntimeException(e); // Uncomment if you want to rethrow the exception
    }
    
    return conn;
}

4、3 通用增删改查操作

1、方法名:update()

2、参数列表:

(1)sql语句 参数

(2)sql ?的占位符,所代表的参数

3、返回值:返回增删改查的结果,成功还是失败,返回值是成功改变数据的行数。

java 复制代码
public static int update(String sql, Object... params) throws SQLException {
    // 调用上面封装好的,得到conn连接
    Connection conn = getConn();
    PreparedStatement ps = null;
    
    try {
        ps = conn.prepareStatement(sql);
        
        // 调用通用的设置sql语句的方法,向sql中设置参数
        setParams(ps, params);
        
        // 执行sql语句
        int i = ps.executeUpdate();
        return i;
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // 调用通用的关闭方法
        closeAll(conn, ps, null);
    }
    
    return -1; // 在异常情况下返回 -1
}

4、4 封装通用的关闭的方法:

1、方法名 closeAll()

2、参数列表:

ResultSet set;PrearedlStatement ps;Connection conn

3、返回值 :不需要返回值

java 复制代码
public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {
    // Close PreparedStatement
    try {
        if (ps != null) {
            ps.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

    // Close ResultSet
    try {
        if (rs != null) {
            rs.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

    // Close Connection
    try {
        if (conn != null) {
            conn.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

4、5 封装通用查询方法(List)

/**

*封装通用的查询方法

*需要做数据的转储:目的是能够把查询的出的数据 在程序中别的地方使用。

*可以转储两种形式:

* List

* List
* 方法名 queryList()
* 参数列表 sql,Object...params :传入参数不定个数相当于数组,在传递参时,不传也不会报错
* 返回值 查询到的结果
*/

java 复制代码
public static List<List> queryList(String sql, Object... params) throws SQLException {
    // Establish the connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement
        ps = conn.prepareStatement(sql);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the SQL query
        rs = ps.executeQuery();
        
        // Retrieve metadata about the result set
        ResultSetMetaData metaData = rs.getMetaData();

        // Create a list to hold all rows of data
        List<List<Object>> lists = new ArrayList<>();

        // Process each row in the result set
        while (rs.next()) {
            // Create a list to hold data for the current row
            List<Object> list = new ArrayList<>();

            // Populate the row list with data from the result set
            for (int i = 0; i < metaData.getColumnCount(); i++) {
                list.add(rs.getObject(i + 1));
            }

            // Add the current row list to the main list
            lists.add(list);
        }

        return lists;
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // Ensure all resources are closed
        closeAll(conn, ps, rs);
    }

    return null;
}

4、6 封装通用查询方法(Map)

/**

* 封装List<>map<String,Object>类型

* 方法的三要素:

* 1、方法名 queryMap()

* 2、参数列表 sql,Object ...

* 3、返回值 如果没有查到数据 就返回NUll

*/

java 复制代码
public static List<Map<String, Object>> queryMap(String sql, Object... params) throws SQLException {
    // Establish the connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement
        ps = conn.prepareStatement(sql);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the SQL query
        rs = ps.executeQuery();

        // Create a list to hold the maps of each row
        List<Map<String, Object>> maps = new ArrayList<>();
        
        // Retrieve metadata about the result set
        ResultSetMetaData metaData = rs.getMetaData();

        // Process each row in the result set
        while (rs.next()) {
            // Create a map to hold data for the current row
            Map<String, Object> map = new HashMap<>();

            // Populate the map with column labels and values from the result set
            for (int i = 0; i < metaData.getColumnCount(); i++) {
                map.put(metaData.getColumnLabel(i + 1), rs.getObject(i + 1));
            }

            // Add the current row map to the main list
            maps.add(map);
        }

        return maps;
    } catch (SQLException e) {
        e.printStackTrace();
        // Optionally throw a runtime exception if needed
        // throw new RuntimeException(e);
    } finally {
        // Ensure all resources are closed
        closeAll(conn, ps, rs);
    }

    return null;
}

4、7 新增时返回自增主键的方法

/**

* 新增时返回自增主键的方法

* 1、方法名 getParmaryKey()

* 2、参数列表 String sql, Object ...params

* 3、返回值 int

*/

java 复制代码
public static int getPrimaryKey(String sql, Object... params) throws SQLException {
    // Establish the connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement to return generated keys
        ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the update SQL statement
        ps.executeUpdate();
        
        // Retrieve the generated keys (primary key)
        rs = ps.getGeneratedKeys();
        
        // Check if the result set has a row and return the primary key
        if (rs.next()) {
            return rs.getInt(1);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // Ensure all resources are closed
        closeAll(conn, ps, rs);
    }

    // Return -1 if no primary key was generated
    return -1;
}

5、测试及结果:

java 复制代码
package DBtest;

import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Objects;

public class DBtext {
    public static void main(String[] args) throws SQLException {
        //测试封装的增删改方法
    String sql ="insert into text values(?,?,null)";
      //  String sql ="select *from text";
   //    List<Map<String, Object>> list= jdbctext.queryMap(sql);
        Object[] parms = { "活着","23"};
     //   Object[] parms=null; 这里是没传入参数
      // int i= jdbctext.update(sql,parms);
       int key= jdbctext.getParmaryKey(sql,parms);
        System.out.println(key);
      //  System.out.println(list);

    }
}
相关推荐
小汤猿人类8 分钟前
open Feign 连接池(性能提升)
数据库
阳冬园29 分钟前
mysql数据库 主从同步
数据库·主从同步
Mr.132 小时前
数据库的三范式是什么?
数据库
Cachel wood2 小时前
python round四舍五入和decimal库精确四舍五入
java·linux·前端·数据库·vue.js·python·前端框架
Python之栈2 小时前
【无标题】
数据库·python·mysql
风_流沙2 小时前
java 对ElasticSearch数据库操作封装工具类(对你是否适用嘞)
java·数据库·elasticsearch
亽仒凣凣2 小时前
Windows安装Redis图文教程
数据库·windows·redis
亦世凡华、2 小时前
MySQL--》如何在MySQL中打造高效优化索引
数据库·经验分享·mysql·索引·性能分析
YashanDB2 小时前
【YashanDB知识库】Mybatis-Plus调用YashanDB怎么设置分页
数据库·yashandb·崖山数据库
ProtonBase3 小时前
如何从 0 到 1 ,打造全新一代分布式数据架构
java·网络·数据库·数据仓库·分布式·云原生·架构