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实现数据库操作的时候,需要考虑以下几个问题:
- 如何获取数据库连接?
- 如何进行SQL操作?
- 如何释放数据库连接?
下面将分别讲解这三个问题。
如何获取数据库连接?
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技术站