JDBC如何连接不同类型数据库

 更新时间:2024年04月01日 17:09:25   作者:thulium_  
这篇文章主要介绍了JDBC如何连接不同类型数据库问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一、连接数据库

1. 连接mysql数据库

  		Connection conn = null;
        //数据库连接驱动名:针对不同的数据库,驱动名称不同,但是同一种类型的数据库改字符串相同
       	Class.forName("com.mysql.jdbc.Driver");
		String url="JDBC:mysql://localhost:8080/testDB";
		String user="test";
		String password="test";
		try {
            //1.加载驱动     
            Class.forName(driver );
             //2.连接
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("连接数据库成功!");
            PreparedStatement statement = null;
            //举个查询例子测试一下
            //查询userinfo表的数据
            statement = conn .prepareStatement("select * from userInfo");
            ResultSet res = null;
            res = statement.executeQuery();
            //当查询下一行有记录时:res.next()返回值为true,反之为false
            while (res.next()) {
                String TenantCode = res.getString("TenantCode");
                String TenantName = res.getString("TenantName");
                String Cloud = res.getString("Cloud");
                System.out.println("学号:" + TenantCode + "姓名:" + TenantName + " 性别:" + Cloud);
            }
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("连接数据库失败!");
        }

2.连接sqlserver数据库

		Connection conn = null;
		Class.forName("com.microsoft.JDBC.sqlserver.SQLServerDriver");
		String url="JDBC:microsoft:sqlserver://localhost:1433;DatabaseName=testDb";
		String user="test"; 
		String password="test";
		try {
            //1.加载驱动     
            Class.forName(driver );
            //2.连接
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("连接数据库成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("连接数据库失败!");
        }

3. 连接postgresql数据库

		Connection conn = null;
        //数据库连接驱动名:针对不同的数据库,驱动名称不同,但是同一种类型的数据库改字符串相同
      	Class.forName("org.postgresql.Driver");
		String url="JDBC:postgresql://localhost/testDb";
		String user="test"; 
		String password="test";
		try {
            //1.加载驱动     
            Class.forName(driver );
             //2.连接
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("连接数据库成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("连接数据库失败!");
        }

4. 连接Oracle 数据库

		Connection conn = null;
      	Class.forName("oracle.JDBC.driver.OracleDriver");
		String url="JDBC:oracle:thin:@localhost:1521:orcl"//orcl为Oracle数据库的SID
		String user="test";
		String password="test";
		try {
            //1.加载驱动     
            Class.forName(driver );
             //2.连接
            conn = DriverManager.getConnection(url, user, password);
            System.out.println("连接数据库成功!");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("连接数据库失败!");
        }

二、JDBCUtils(数据库常用操作工具类)

(1)获取数据库连接对象

(2)获取查询结果集

(3)将查询结果集转化为指定对象(使用者自行提供类参数,通过反射和转化)

(4)执行更新、删除、插入操作

(5)关闭数据库连接

package utils;
 
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * 数据库常用操作工具类
 * 
 */
public final class JdbcUtils {
	// mysql8驱动
	public static final String MYSQL8_DRIVER = "com.mysql.cj.jdbc.Driver";
 
	/**
	 * 结果集处理器
	 * 
	 */
	public static interface ResultSetHandler<T> {
		/**
		 * 将一个结果集转换成T类型
		 * 
		 * @param rs
		 * @return
		 */
		T handle(ResultSet rs);
	}
 
	/**
	 * 列处理器
	 * 
	 */
	public static interface ColumnHandler<T> {
		/**
		 * 
		 * @param method     根据列名自动匹配的方法名
		 * @param columnName 列名
		 * @param t          对象
		 * @param value      值
		 * @return 返回true,表示用户已处理完成,无需再处理,返回false,则代表用户不处理
		 */
		boolean handleColumn(Method method, String columnName, T t, Object value);
	}
 
	/**
	 * 内部类的目的,就是为了将结果集中的数据自动封装成对象
	 * 
	 */
	public static class BeanListHandler<T> implements ResultSetHandler<List<T>> {
		private final Class<T> clazz;
		private ColumnHandler<T> columnHandler;
 
		public BeanListHandler(Class<T> clazz) {
			this.clazz = clazz;
		}
 
		public BeanListHandler(Class<T> clazz, ColumnHandler<T> columnHandler) {
			this.clazz = clazz;
			this.columnHandler = columnHandler;
		}
 
		@Override
		public List<T> handle(ResultSet rs) {
			// 返回值
			List<T> list = new ArrayList<>();
			// 存储所有列名(别名)
			List<String> columnNames = new ArrayList<>();
			// 存储所有方法,键名是列名(别名),值即其对应的setter方法
			Map<String, Method> methodMap = new HashMap<>();
 
			// 获取所有列名
			try {
				// 结果集元数据
				ResultSetMetaData rsmd = rs.getMetaData();
				// 返回查询结果集的列数
				int count = rsmd.getColumnCount();
				// 返回此类型的所有方法
				Method[] methods = clazz.getDeclaredMethods();
 
				for (int i = 0; i < count; i++) {
					// 获取列名,如果起别名,则获取别名
					String columnName = rsmd.getColumnLabel(i + 1);
					columnNames.add(columnName);// 返回查询结果集的列名
 
					// 组装出对象的方法名
					String methodName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
					methodName = "set" + methodName;
 
					for (Method me : methods) {
						if (me.getName().equals(methodName)) {
							methodMap.put(columnName, me);// 设置到map中
							break;
						}
					}
				}
 
				// 准备工作已完成,将结果集中的数据转换成T类型的实例
				if (rs != null) {
					// 获取无参的构造方法
					Constructor<T> con = clazz.getDeclaredConstructor();
					while (rs.next()) {
						T t = con.newInstance();// T类型的实例
						for (int i = 0; i < count; i++) {
							String columnName = columnNames.get(i);
 
							// 从结果集中取出对应列的数据
							Object value = rs.getObject(columnName);
 
							// 取出方法
							Method method = methodMap.get(columnName);
							if (method != null) {
								if (columnHandler != null) {
									boolean done = columnHandler.handleColumn(method, columnName, t, value);
 
									if (!done) {
										// 通过反射给T类型的实例赋值
										method.invoke(t, value);
									}
								}
							}
						}
						list.add(t);
					}
				}
				return list;
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
	}
 
	/**
	 * 获取数据库连接
	 * 
	 * @param url
	 * @param user
	 * @param password
	 * @return
	 */
	public static final Connection getConnection(String driver, String url, String user, String password) {
		try {
			Class.forName(driver);
			return DriverManager.getConnection(url, user, password);
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		throw new RuntimeException("无法创建数据库连接");
	}
 
	/**
	 * 获取数据库连接
	 * 
	 * @param url
	 * @param user
	 * @param password
	 * @return
	 */
	public static final Connection getConnection(String url, String user, String password) {
		return getConnection(MYSQL8_DRIVER, url, user, password);
	}
 
	/**
	 * 执行查询操作,返回结果集
	 * 
	 * @param conn
	 * @param sql
	 * @param args
	 * @return
	 */
	private static final ResultSet query(Connection conn, String sql, Object[] args) {
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			if (args != null) {
				// 给PreparedStatement实例设置参数
				for (int i = 0; i < args.length; i++) {
					ps.setObject(i + 1, args[i]);
				}
			}
			return ps.executeQuery();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		throw new RuntimeException("查询出现异常");
	}
 
	/**
	 * 返回对象的集合
	 * 
	 * @param <T>
	 * @param conn
	 * @param sql
	 * @param args
	 * @return
	 */
	public static final <T> T query(Connection conn, ResultSetHandler<T> handler, String sql, Object[] args) {
		ResultSet rs = query(conn, sql, args);
		return handler.handle(rs);
	}
 
	/**
	 * 写操作
	 * 
	 * @return 返回受影响的行数
	 */
	public static final int update(Connection conn, String sql, Object[] args) {
		try {
			PreparedStatement ps = conn.prepareStatement(sql);
			if (args != null) {
				// 给PreparedStatement实例设置参数
				for (int i = 0; i < args.length; i++) {
					ps.setObject(i + 1, args[i]);
				}
			}
			return ps.executeUpdate();
		} catch (SQLException e) {
			// e.printStackTrace();
		}
		return -1;
	}
 
	/**
	 * 关闭数据库连接
	 * 
	 * @param conn
	 */
	public static final void closeConnection(Connection conn) {
		if (conn != null) {
			try {
				conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
 
}

三、自定义JDBCUtils

我采用的是:

  • JDBCUtils来连接和关闭数据库相关资源。
  • 再写一个类(BeanJDBCUtils)来进行数据库的基本操作。
  • 最后写一个类来实现具体的操作。

1. JDBCUtils

/**
 * @author long
 * @date 2022/6/15 14:00
 * @Description: 连接数据库的类
 */
 
@SuppressWarnings("all")
public class JDBCUtils {
 
    private static final String url;
    private static final String userName;
    private static final String password;
    private static final String driver;
 
    static {
 
        Properties properties = new Properties();
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            properties.load(is);
            url = properties.getProperty("url");
            userName = properties.getProperty("userName");
            password = properties.getProperty("password");
            driver = properties.getProperty("driver");
 
            //注册驱动
            Class.forName(driver);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
 
    }
 
    /**
     * @Description 获取数据库的连接
     * @return
     */
    public Connection getConnection() {
        try {
            return DriverManager.getConnection(url, userName, password);
        } catch (SQLException e) {
            throw new RuntimeException("无法连接到数据库\n");
        }
    }
 
    /**
     * @Description 关闭连接
     * @param connection
     */
    public void close(Connection connection) {
        try {
            connection.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
 
    /**
     * @Description 关闭连接
     * @param connection
     */
    public void close(Connection connection, ResultSet resultSet) {
        try {
            connection.close();
            resultSet.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}

2. BeanJDBCUtils

/**
 * @author long
 * @date 2022/6/15 15:23
 * @Description: 对数据的操作的基本类
 */
 
@SuppressWarnings("all")
public class BeanJDBCUtils<T> extends JDBCUtils {
 
    private Connection connection;
    private PreparedStatement preparedStatement;
 
    private Class entityClass;
 
    /**
     * 构造方法,为了获取到泛型的对象的类,将其赋值给entityClass
     */
    public BeanJDBCUtils() {
        //getClass() 获取Class对象,当前我们执行的是new FruitDAOImpl() , 创建的是FruitDAOImpl的实例
        //那么子类构造方法内部首先会调用父类(BaseDAO)的无参构造方法
        //因此此处的getClass()会被执行,但是getClass获取的是FruitDAOImpl的Class
        //所以getGenericSuperclass()获取到的是BaseJDBCUtils的Class
 
        //System.out.println("获取父类对象:" + clazz.getSuperclass());
        Type genericType = getClass().getGenericSuperclass();
        //ParameterizedType 参数化类型
        Type[] actualTypeArguments = ((ParameterizedType) genericType).getActualTypeArguments();
        //获取到的<T>中的T的真实的类型
        Type actualType = actualTypeArguments[0];
        try {
            entityClass = Class.forName(actualType.getTypeName());
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
 
    /**
     * @param sql
     * @param args
     * @return
     * @Description: 查找数据库中多行数据
     */
    public List<T> query(String sql, Object... args) {
        List<T> list = new ArrayList<>();
        connection = getConnection();
        ResultSet resultSet = null;
        try {
            preparedStatement = connection.prepareStatement(sql);
            /*填充占位符*/
            for (int i = 0; i < args.length; ++i)
                preparedStatement.setObject(i + 1, args[i]);
            preparedStatement.execute();
            /*获取返回结果*/
            resultSet = preparedStatement.getResultSet();
            /*获取返回结果的数据*/
            ResultSetMetaData metaData = resultSet.getMetaData();
            /*获取数据的行数*/
            int columnCount = metaData.getColumnCount();
            while (resultSet.next()) {
                /*初始化泛型*/
                T entity = (T) entityClass.newInstance();
                Object object = new Object();
                for (int i = 0; i < columnCount; ++i) {
                    /*获取列名的别名,如果没有别名则直接获取列名*/
                    String columnLabel = metaData.getColumnLabel(i + 1);
                    object = resultSet.getObject(i + 1);
                    /*使用反射给泛型变量赋值*/
                    Field field = entity.getClass().getDeclaredField(columnLabel);
                    field.setAccessible(true);
                    field.set(entity, object);
                }
                list.add(entity);
            }
 
            return list;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, resultSet);
        }
    }
 
 
    /**
     *
     * @param sql
     * @param clazz
     * @param args
     * @return
     * @Description: 查找数据库中单行数据
     */
    public T query(String sql, Class clazz, Object... args) {
        connection = getConnection();
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; ++i)
                preparedStatement.setObject(i + 1, args[i]);
            resultSet = preparedStatement.executeQuery();
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();
            T t = (T) entityClass.newInstance();
            if (resultSet.next()) {
                Object object = new Object();
                for (int i = 0; i < columnCount; i++) {
                    String columnLabel = metaData.getColumnLabel(i + 1);
                    Field field = t.getClass().getDeclaredField(columnLabel);
                    field.setAccessible(true);
                    object = resultSet.getObject(columnLabel);
                    field.set(t, object);
                }
            }
            return t;
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, resultSet);
        }
    }
 
    /**
     * @param sql
     * @param args
     * @return 影响的行数
     * @Description: 增删改
     */
    public Integer updata(String sql, Object... args) {
 
        connection = getConnection();
        PreparedStatement preparedStatement = null;
        try {
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < args.length; ++i)
                preparedStatement.setObject(i + 1, args[i]);
            return preparedStatement.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(connection);
        }
    }
 
    /**
     * @param sql
     * @param args
     * @param <E>
     * @return
     * @Description: 查找特定的值,并返回单一基本类型
     */
    public <E> E getElement(String sql, Object... args) {
        connection = getConnection();
        ResultSet resultSet = null;
        try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
            for (int i = 0; i < args.length; i++) {
                preparedStatement.setObject(i + 1, args[i]);
            }
            Object object = null;
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                object = resultSet.getObject(1);
            }
            return (E) object;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            close(connection, resultSet);
        }
    }
}

创建一个与数据库表t_fruit一一对应的Fruit类

 
import lombok.*;
 
/**
 * @author long
 * @date 2022/6/15 14:58
 * @Description: 与数据库中的t_fruit表一一对应的水果类
 */
@ToString
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuppressWarnings("all")
public class Fruit {
    private Integer fid;
    private String fname;
    private Integer price;
    private Integer fcount;
    private String remark;
 
    public Fruit(String fname, Integer price, Integer fcount, String remark) {
        this.fname = fname;
        this.price = price;
        this.fcount = fcount;
        this.remark = remark;
    }
}
 

创建一个接口(FruitDAO)来声明对改数据库的表中的操作的方法。

import java.util.List;
 
public interface FruitDAO {
    /*获取所有水果信息*/
    List<Fruit> getAllFruit();
 
    /*添加水果信息*/
    Integer addFruit(Fruit fruit);
 
    /*获取水果的种类的数量*/
    Long getAllCount();
 
    /*获取最大价格*/
    Integer getMaxPrice();
 
    /*获取最小价格*/
    Integer getMinPrice();
 
    Fruit getFruitById(Integer id);
 
}
 

对上述接口(FruitDAO)的实现类(FruitDAOImpl)

/**
 * @author long
 * @date 2022/6/15 15:04
 * @Description: 对数据库中t_fruit表的操作的类
 */
public class FruitDAOImpl extends BeanJDBCUtils<Fruit> implements FruitDAO {
 
    @Override
    public List<Fruit> getAllFruit() {
        String sql = "select * from t_fruit";
        return query(sql);
    }
 
    @Override
    public Integer addFruit(Fruit fruit) {
        String sql = "insert into t_fruit(fname,price,fcount,remark) values(?,?,?,?)";
        return updata(sql, fruit.getFname(), fruit.getPrice(), fruit.getFcount(), fruit.getRemark());
    }
 
    @Override
    public Long getAllCount() {
        String sql = "select count(*) from t_fruit";
        return getElement(sql);
    }
 
    @Override
    public Integer getMaxPrice() {
        String sql = "select max(price) from t_fruit";
        return getElement(sql);
    }
 
    @Override
    public Integer getMinPrice() {
        String sql = "select min(price) from t_fruit";
        return getElement(sql);
    }
 
    @Override
    public Fruit getFruitById(Integer id) {
        String sql = "select * from t_fruit where fid = ?";
        return query(sql, Fruit.class, id);
    }
 
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • mysql百万数据表加索引优化的方法

    mysql百万数据表加索引优化的方法

    在大数据时代,随着数据量的快速增长,对数据库的索引优化变得尤为重要,本文主要介绍了mysql百万数据表加索引优化的方法,感兴趣的可以了解一下
    2024-02-02
  • MySQL选择合适的备份策略和备份工具

    MySQL选择合适的备份策略和备份工具

    这篇文章主要介绍了MySQL选择合适的备份策略和备份工具,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下,希望对你的学习有所帮助
    2022-05-05
  • Ubuntu下mysql安装和操作图文教程

    Ubuntu下mysql安装和操作图文教程

    这篇文章主要为大家详细分享了Ubuntu下mysql安装和操作图文教程,喜欢的朋友可以参考一下
    2016-05-05
  • 深度解析MySQL 5.7之中文全文检索

    深度解析MySQL 5.7之中文全文检索

    InnoDB默认的全文索引parser非常合适于Latin,因为Latin是通过空格来分词的。但对于像中文,日文和韩文来说,没有这样的分隔符。一个词可以由多个字来组成,所以我们需要用不同的方式来处理。在MySQL 5.7.6中我们能使用一个新的全文索引插件来处理它们:n-gram parser。
    2016-12-12
  • mysql中如何对列求和

    mysql中如何对列求和

    这篇文章主要介绍了mysql中如何对列求和问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • MySQL动态字符串处理DYNAMIC_STRING

    MySQL动态字符串处理DYNAMIC_STRING

    本文主要给大家简单讲解了mysql如何使用DYNAMIC_STRING来进行动态字符串的保存,非常的实用,有需要的小伙伴可以参考下
    2016-10-10
  • MySQL数据库优化推荐的编译安装参数小结

    MySQL数据库优化推荐的编译安装参数小结

    这篇文章主要介绍了MySQL数据库优化推荐的编译安装参数小结,需要的朋友可以参考下
    2015-04-04
  • MySQL删除有外键约束的表数据方法介绍

    MySQL删除有外键约束的表数据方法介绍

    这篇文章主要介绍了MySQL删除有外键约束的表数据方法介绍,还是非常不错的,这里给大家分享下,需要的朋友可以参考。
    2017-10-10
  • Mysql之如何实现全外连接

    Mysql之如何实现全外连接

    这篇文章主要介绍了Mysql之如何实现全外连接问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • mysql定时备份shell脚本和还原的示例

    mysql定时备份shell脚本和还原的示例

    数据库备份是防止数据丢失的一种重要手段,生产环境中,数据的安全性是至关重要的,任何数据的丢失都可能产生严重的后果,所以本文给大家介绍了mysql定时备份shell脚本和还原的实例,需要的朋友可以参考下
    2024-02-02

最新评论