JDBC(一)
1、简介
Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。我们通常说的JDBC是面向关系型数据库的。
2、原理
Java制定的统一规范,然后各个数据库厂商根据这个规范接口来实现。
3、编写步骤
事先导入mysql-connector的jar包
- 注册驱动Driver
- 建立数据库连接connection
- 创建statement对象,并用来执行sql
- 关闭连接
3.1、加载MySQL数据库的驱动
Class.forName(“com.mysql.jdbc.Driver”);
(MySQL5.1.6以后会自动加载,这一步可以省略,但还是建议写上,因为可能会换别的数据库驱动)
3.2、建立数据库连接
Connection connection = DriverManager.getConnection(url, user, password);
将配置文件信息写在properties文件中,方便以后修改
user=root password=1234 url=jdbc:mysql://127.0.0.1:3306/数据库名 driver=com.mysql.jdbc.Driver
// 通过properties文件获取配置信息 Properties properties = new Properties(); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url");
- url注意事项
本机的ip可以用localhost代替
jdbc:mysql://localhost:3306/数据库名
仅限该连接还可以进一步省略
jdbc:mysql:///数据库名
// MySQL在高版本需要指明是否进行SSL连接,可以通过设置useSSL=false来显式禁用SSL String url = "jdbc:mysql://localhost:3306/java2207&useSSL=false"; // MySQL8.0之后要加上时区 String url = "jdbc:mysql://localhost:3306/java2207?serverTimezone=Asia/Shanghai";
3.3、Statement对象
- Statement执行sql语句并返其生成结果的对象(有sql注入风险--- or '1'= '1万能密码)
- 用PreparedStatement接口,预处理,可以写?占位符;解决sql注入问题;减少编译次数。
- public interface PreparedStatement
- extends Statement
- 示预编译的 SQL 语句的对象。
- SQL 语句被预编译并存储在
PreparedStatement
对象中。然后可以使用此对象多次高效地执行该语句。
String sql = ""; PreparedStatement ps = connection.prepareStatement(sql);
3.4、关闭连接
先开后关
.close();
4、JDBCUtils
将相同操作部分封装到工具类中
public class JdbcUtils { public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException { // 先通过properties文件获取配置信息 Properties properties = new Properties(); properties.load(new FileInputStream("src\\jdbc.properties")); String user = properties.getProperty("user"); String password = properties.getProperty("password"); String driver = properties.getProperty("driver"); String url = properties.getProperty("url"); // 加载驱动 Class.forName(driver); // 返回数据库连接 return DriverManager.getConnection(url, user, password); } public static void closeResource(Connection connection, Statement statement) { try { if (statement != null) { statement.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } } public static void closeResource(Connection connection, Statement statement, ResultSet resultSet) { try { if (statement != null) { statement.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (connection != null) { connection.close(); } } catch (SQLException e) { e.printStackTrace(); } try { if (resultSet != null) { resultSet.close(); } } catch (SQLException e) { e.printStackTrace(); } }}
5、通用增删改
/** * 通用增删改 * @param sql * @param args */ public int update(String sql,Object...args){ Connection connection = null; PreparedStatement ps = null; try { // 1.获取数据库连接 connection = JdbcUtils.getConnection(); // 2.预编译sql ps = connection.prepareStatement(sql); // 3.填充占位符 for (int i = 0; i < args.length; i++) { // 注意这里i从1开始,要记得+1 ps.setObject(i + 1,args[i]); } // 4.执行并返回受影响的行数 return ps.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } finally { // 5.关闭资源 JdbcUtils.closeResource(connection,ps); } return 0; }
6、通用查询
6.1、针对不同表进行查询,返回单条记录
/** * 通用查询,返回单条记录 */ public <T> T queryOne(Class<T> clz, String sql, Object...args) { Connection connection = null; PreparedStatement ps = null; ResultSet resultSet = null; try { // 1.获取数据库连接 connection = JdbcUtils.getConnection(); // 2.预编译sql ps = connection.prepareStatement(sql); // 3.填充占位符 for (int i = 0; i < args.length; i++) { // 注意这里i从1开始,要记得+1 ps.setObject(i + 1,args[i]); } // 4.执行操作,返回结果集 resultSet = ps.executeQuery(); // 获取结果集元数据 ResultSetMetaData metaData = resultSet.getMetaData(); // 获取结果集的列数 int columnCount = metaData.getColumnCount(); if (resultSet.next()){ // newInstance创建此 Class 对象所表示的类的一个新实例 T t = clz.newInstance(); for (int i = 0; i < columnCount; i++) { // 获取列值 Object columnValue = resultSet.getObject(i + 1); // 获取每个列的列名getColumnName // 获取每个列的别名getColumnLabel String columnLabel = metaData.getColumnLabel(i + 1); // 通过反射,给clz对象指定的ColumnName属性,赋值为columnValue Field field = clz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t,columnValue); } return t; } } catch (Exception e) { e.printStackTrace(); } finally { // 5.关闭资源 JdbcUtils.closeResource(connection,ps,resultSet); } return null; }
6.2、针对不同表进行查询,返回多条记录
/** * 通用查询,返回多条记录 */ public <T> List<T> queryList(Class<T> clz, String sql, Object...args) { Connection connection = null; PreparedStatement ps = null; ResultSet resultSet = null; try { // 1.获取数据库连接 connection = JdbcUtils.getConnection(); // 2.预编译sql ps = connection.prepareStatement(sql); // 3.填充占位符 for (int i = 0; i < args.length; i++) { // 注意这里i从1开始,要记得+1 ps.setObject(i + 1,args[i]); } // 4.执行操作,返回结果集 resultSet = ps.executeQuery(); // 获取结果集元数据 ResultSetMetaData metaData = resultSet.getMetaData(); // 获取结果集的列数 int columnCount = metaData.getColumnCount(); // 创建一个集合,用于存放对象 ArrayList<T> arrayList = new ArrayList<>(); while (resultSet.next()){ // newInstance创建此 Class 对象所表示的类的一个新实例 T t = clz.newInstance(); // 这个for循环是给t对象指定的属性赋值 for (int i = 0; i < columnCount; i++) { // 获取列值 Object columnValue = resultSet.getObject(i + 1); // 获取每个列的列名getColumnName // 获取每个列的别名getColumnLabel String columnLabel = metaData.getColumnLabel(i + 1); // 通过反射,给clz对象指定的ColumnName属性,赋值为columnValue Field field = clz.getDeclaredField(columnLabel); field.setAccessible(true); field.set(t,columnValue); } arrayList.add(t); } return arrayList; } catch (Exception e) { e.printStackTrace(); } finally { // 5.关闭资源 JdbcUtils.closeResource(connection,ps,resultSet); } return null; }
本文作者:Ritchie里其
本文链接:https://www.cnblogs.com/wang-zeyu/p/16882312.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步