Java泛型与数据库应用实例详解

Java泛型与数据库应用实例详解

什么是Java泛型?

Java泛型是Java SE 5中引入的一项语言特性,它提供了一种编写泛化代码的方法,能够提高代码的通用性和复用性,从而提高了代码的可维护性和可扩展性。

Java泛型的语法

Java泛型使用尖括号<>来规定类型参数,语法格式如下:

public class GenericClass<T1, T2, ..., Tn>{
    //泛型类或者接口体
}

泛型类或者接口体可以包含泛型方法,泛型方法的语法格式如下:

public <T> R methodName(T arg1, arg2, ..., argn){
    //泛型方法体
}

Java泛型应用于数据库操作

Java的数据库操作通常需要使用JDBC(Java DataBase Connectivity)的API,JDBC API提供了一组接口和类,可以访问各种不同类型的数据库。在使用JDBC实现数据库操作的时候,需要考虑以下几个问题:

  1. 如何获取数据库连接?
  2. 如何进行SQL操作?
  3. 如何释放数据库连接?

下面将分别讲解这三个问题。

如何获取数据库连接?

Java数据库连接通常需要使用DataSource或DriverManager两种方式获取连接,具体介绍如下:

使用DataSource获取数据库连接

DataSource是Java EE规范中定义的接口,提供了获取数据库连接和释放数据库连接的方法。DataSource编码如下:

// 加载配置文件获取DataSource
DataSource ds = (DataSource)
                new InitialContext().lookup("java:comp/env/jdbc/myDataSource");
// 获取Connection对象
Connection conn = ds.getConnection();

这种方式最大的优点是可以方便地进行数据库连接池配置,提高了数据库连接的复用性和扩展性。

使用DriverManager获取数据库连接

DriverManager是JDBC API提供的一个类,它提供了获取数据库连接的静态方法。DriverManager编码如下:

// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection(url, username, password);

这种方式最大的优点是简单方便,便于单独测试和调试。

如何进行SQL操作?

JDBC API提供了大量的接口和类,用于进行SQL操作。以下是使用JDBC API实现数据库插入和查询操作的示例代码:

数据库插入操作

Connection conn = null;
PreparedStatement stmt = null;
try{
    // 获取数据库连接
    conn = getConnection();
    // SQL语句
    String sql = "insert into user(name, age) values(?, ?)";
    // 创建PreparedStatement对象
    stmt = conn.prepareStatement(sql);
    // 设置参数值
    stmt.setString(1, "张三");
    stmt.setInt(2, 20);
    // 执行SQL语句
    int num = stmt.executeUpdate();
    System.out.println("插入" + num + "条记录");
} catch (SQLException e){
    e.printStackTrace();
} finally {
    // 释放资源
    try{
        if(stmt != null){
            stmt.close();
        }
        if(conn != null){
            conn.close();
        }
    } catch(SQLException e){
        e.printStackTrace();
    }
}

数据库查询操作

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
    // 获取数据库连接
    conn = getConnection();
    // SQL语句
    String sql = "select * from user where age=?";
    // 创建PreparedStatement对象
    stmt = conn.prepareStatement(sql);
    // 设置参数值
    stmt.setInt(1, 20);
    // 执行SQL语句
    rs = stmt.executeQuery();
    // 处理结果集
    while(rs.next()){
        System.out.println(rs.getInt("id") + ":" + rs.getString("name"));
    }
} catch (SQLException e){
    e.printStackTrace();
} finally {
    // 释放资源
    try{
        if(rs != null){
            rs.close();
        }
        if(stmt != null){
            stmt.close();
        }
        if(conn != null){
            conn.close();
        }
    } catch(SQLException e){
        e.printStackTrace();
    }
}

如何释放数据库连接?

JDBC连接是一种稀缺的资源,连接不当会导致系统性能下降。释放数据库连接的方式有两种:

自动释放

JDBC连接池可以根据一定的策略来自动回收链接,释放连接资源。可以使用数据库连接池工具来实现该功能。

手动释放

手动释放数据库连接的方式是在使用完数据库连接后,显式地将连接对象、Statement对象、ResultSet对象的引用置为空,表示不再使用该资源。示例代码如下:

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
    // 获取数据库连接
    conn = getConnection();
    // SQL语句
    String sql = "select * from user where age=?";
    // 创建PreparedStatement对象
    stmt = conn.prepareStatement(sql);
    // 设置参数值
    stmt.setInt(1, 20);
    // 执行SQL语句
    rs = stmt.executeQuery();
    // 处理结果集
    while(rs.next()){
        System.out.println(rs.getInt("id") + ":" + rs.getString("name"));
    }
} catch (SQLException e){
    e.printStackTrace();
} finally {
    // 释放资源
    try{
        if(rs != null){
            rs.close();
            rs = null;
        }
        if(stmt != null){
            stmt.close();
            stmt = null;
        }
        if(conn != null){
            conn.close();
            conn = null;
        }
    } catch(SQLException e){
        e.printStackTrace();
    }
}

实例一:使用Java泛型批量插入数据

假设有一个用户实体类User,包含id、name、age三个属性。现在需要将一批用户信息插入数据库,可以使用Java泛型来实现。

public class JdbcUtil {

    //加载数据库驱动(使用MySQL数据库)
    private static final String DRIVER = "com.mysql.jdbc.Driver";

    //数据库连接信息
    private static final String URL = "jdbc:mysql://localhost:3306/test?" + "useUnicode=true&characterEncoding=utf8&useSSL=false";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "mypassword";

    /**
     * 批量插入数据
     * @param sql 插入数据的SQL语句
     * @param dataList 数据列表
     * @return 插入成功的行数
     */
    public static <T> int batchInsert(String sql, List<T> dataList) throws SQLException {
        Connection conn = null;
        PreparedStatement stmt = null;
        int result = 0;
        try {
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            stmt = conn.prepareStatement(sql);
            for (T data : dataList) {
                if (data != null) {
                    setPreparedStatementParameters(stmt, data);
                    stmt.addBatch();
                }
            }
            int[] rows = stmt.executeBatch();
            for (int i : rows) {
                if (i > 0) {
                    result++;
                }
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            closeConnection(conn, stmt, null);
        }
        return result;
    }

    /**
     * 设置PreparedStatement对象的参数值
     * @param stmt PreparedStatement对象
     * @param data 数据对象
     */
    private static <T> void setPreparedStatementParameters(PreparedStatement stmt, T data) throws SQLException {
        if (data instanceof User) {
            User user = (User) data;
            stmt.setString(1, user.getName());
            stmt.setInt(2, user.getAge());
        }
        //其他数据类型类似
    }

    /**
     * 关闭数据库连接和相关资源
     */
    private static void closeConnection(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

实例二:使用Java泛型查询数据

假设有一个用户实体类User,包含id、name、age三个属性,现在需要根据用户id查询用户信息,可以使用Java泛型来实现。

public class JdbcUtil {

    //加载数据库驱动(使用MySQL数据库)
    private static final String DRIVER = "com.mysql.jdbc.Driver";

    //数据库连接信息
    private static final String URL = "jdbc:mysql://localhost:3306/test?" + "useUnicode=true&characterEncoding=utf8&useSSL=false";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "mypassword";

    /**
     * 根据ID查找数据
     * @param sql 查询数据的SQL语句
     * @param clazz 被查询的对象类型
     * @param id ID
     * @return 查找到的数据
     */
    public static <T> T selectById(String sql, Class<T> clazz, int id) throws SQLException {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        T result = null;
        try {
            conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, id);
            rs = stmt.executeQuery();
            if (rs.next()) {
                result = clazz.newInstance();
                ResultSetMetaData rsmd = rs.getMetaData();
                int columnCount = rsmd.getColumnCount();
                for (int i = 1; i <= columnCount; i++) {
                    String columnName = rsmd.getColumnLabel(i);
                    Object columnValue = rs.getObject(columnName);
                    setFieldValue(result, columnName, columnValue);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            closeConnection(conn, stmt, rs);
        }
        return result;
    }

    /**
     * 设置对象属性的值
     * @param obj 对象
     * @param fieldName 属性名
     * @param fieldValue 属性值
     */
    private static <T> void setFieldValue(T obj, String fieldName, Object fieldValue) throws Exception {
        Field field = obj.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(obj, fieldValue);
    }

    /**
     * 关闭数据库连接和相关资源
     */
    private static void closeConnection(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (stmt != null) {
                stmt.close();
            }
            if (conn != null) {
                conn.close();
            }
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Java泛型与数据库应用实例详解 - Python技术站

(0)
上一篇 2023年5月20日
下一篇 2023年5月20日

相关文章

  • jsp response.sendRedirect不跳转的原因分析及解决

    针对“jsp response.sendRedirect不跳转的原因分析及解决”,以下是完整攻略: 1. 确认response.sendRedirect是否执行 首先要确认response.sendRedirect是否真正执行了。可以通过在response.sendRedirect前后,分别加入System.out.println语句,输出一些信息,在控制台…

    Java 2023年6月15日
    00
  • MyBatis使用Zookeeper保存数据库的配置可动态刷新的实现代码

    下面我将为你详细讲解使用Zookeeper保存数据库的配置并实现动态刷新的实现过程。本文主要分为以下几个部分: MyBatis使用Zookeeper保存数据库的配置的原理 实现动态刷新的流程 代码实现及示例说明 1. MyBatis使用Zookeeper保存数据库的配置的原理 MyBatis使用Zookeeper保存数据库的配置,可以将配置信息保存在Zook…

    Java 2023年6月16日
    00
  • 创建Java线程安全类的七种方法

    让我详细讲解“创建Java线程安全类的七种方法”的完整攻略。Java线程安全类是多线程环境下安全并发的类,可以保证并发性的正确性。在Java中,可以使用以下7种方法来创建线程安全的类: 不可变性(Immutability):在Java中,不可变的对象是线程安全的,因为不可变对象的状态是不可更改的。你可以通过使用final修饰符来创建不可变的对象。例如: pu…

    Java 2023年5月19日
    00
  • MyBatis入门学习教程-MyBatis快速入门

    对于”MyBatis入门学习教程-MyBatis快速入门”,我们可以按照如下步骤来进行学习,包括环境搭建、对象映射、CRUD操作等内容。 一、环境搭建 下载MyBatis在MyBatis的官方网站上下载最新版本的MyBatis(https://github.com/mybatis/mybatis-3/releases),解压后将其中的mybatis-3.x.…

    Java 2023年5月20日
    00
  • 浅谈JavaScript中promise的使用

    首先需要了解promise是一种异步编程的解决方案,是一个对象,用来进行异步操作的状态管理和结果返回。 一、Promise的基本使用 1. Promise的三种状态 一个Promise对象有三种状态(state): pending(进行中) fulfilled(已成功) rejected(已失败) 2. Promise的基本结构 Promise对象的基本结构…

    Java 2023年5月23日
    00
  • Spring mvc Controller和RestFul原理解析

    下面是关于Spring MVC Controller和RestFul的原理解析,包含两个示例说明。 Spring MVC Controller和RestFul原理解析 Spring MVC是一个流行的Java Web框架,它可以帮助我们快速构建Web应用程序。在Spring MVC中,Controller是一个重要的组件,它用于处理请求并返回响应。在本文中,…

    Java 2023年5月17日
    00
  • 用headjs来管理和加载js 提高网站加载速度

    使用headjs来管理和加载JS可以提高网站的加载速度,这是因为headjs通过异步加载JS文件来提高页面渲染的速度。下面是使用headjs来管理和加载JS的完整攻略: 1. 下载并引入headjs 首先,需要下载head.js库,并在网页中引入该文件,可以使用CDN来引入该文件,如下所示: <script src="https://cdn.…

    Java 2023年6月15日
    00
  • 三张图彻底了解Java中字符串的不变性

    首先,让我们来了解Java中字符串的不变性。 Java中的字符串是不可变的。这意味着,一旦字符串被创建,它的值不可以被改变。在Java中,每当我们对字符串进行操作的时候,都会创建一个新的字符串对象,而原始的字符串对象则保持不变。这个特性叫做字符串的“不变性”。 接下来,我们来看三张图来彻底了解Java中字符串的不变性。 图1:字符串的创建 String s …

    Java 2023年5月27日
    00
合作推广
合作推广
分享本页
返回顶部