JDBC概述
- JDBC:Java Database Connectivity ,是sun公司为了简化和统一java连接数据库定义的一套规范
JDBC和数据库驱动的关系
JDBC编程6步
- 注册驱动
- 获得连接
- 获取执行sql语句的对象
- 执行sql语句
- 处理结果
- 释放资源
1 2 3 4 5 6
| Class.forName("驱动的路径"); DriverManager.getConnection("数据库路径","数据库用户名","数据库密码"); statement : 执行SQL语句的对象 Connection:连接数据库的对象 ResultSet:结果集对象,作用:保存查询后的结果集 Close:释放资源
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| package top.simba1949.jdbc; import com.mysql.jdbc.Driver; import org.junit.Test; import java.sql.*; public class JDBCTest { @Test public void tt01() throws SQLException { ResultSet resultSet = null; Statement statement = null; Connection connection = null; try { DriverManager.registerDriver(new Driver()); String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "19491001"; connection = DriverManager.getConnection(url, user, password); statement = connection.createStatement(); String sql = "select * from USER "; resultSet = statement.executeQuery(sql); while (resultSet.next()){ System.out.println(resultSet.getString("uid")); System.out.println(resultSet.getString(2)); } } catch (SQLException e) { e.printStackTrace(); }finally { resultSet.close(); statement.close(); connection.close(); } } }
|
JDBC API详解
1.java.sql.DriverManager
作用:主要是用于加载驱动,并且创建和数据库的连接
1.1 RegisterDriver(Driver driver) ;注册驱动
- 翻阅源码发现,通过API的方式注册驱动,Driver会new两次,所有推荐这种写法:
1
| Class.forName("com.mysql.jdbc.Driver");
|
1.2 getConnection(String url, String user, String password) ;与数据库建立连接
常见的几种数据库连接字符串的写法:
1 2 3
| MySQL写法: jdbc:mysql: Oracle写法: jdbc:oracle:thin:@localhost:1521:sid SqlServer写法: jdbc:microsoft:sqlserver:
|
2.java.sql.Connection接口
- 接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。
2.1 createStatement() ;创建执行sql语句对象
2.2 prepareStatement(String sql) ;创建预编译执行sql语句的对象
3.java.sql.Statement接口
- 接口的实现在数据库驱动中
- 操作sql语句,并返回相应结果对象
3.1 Statement; 执行sql语句对象
- ResultSet executeQuery(String sql) 根据查询语句返回结果集。只能执行select语句。
- int executeUpdate(String sql) 根据执行的DML(insert update delete)语句,返回受影响的行数。
- boolean execute(String sql) 此方法可以执行任意sql语句。返回boolean值,表示是否返回的是ResultSet结果集。仅当执行select语句,且有返回结果时返回true, 其它语句都返回false
4.java.sql.ResultSet接口
4.1封装结果集,查询结果表的对象
- 提供一个游标,默认游标指向结果集第一行之前。
- 调用一次next(),游标向下移动一行。
- 提供一些getXXX方法。XXX代表的是数据类型
4.2ResultSet接口常用API
- boolean next() ;将光标从当前位置向下移动一行
- XXX getXXX(int columnIndex) : 根据列的序号获取XXX类型的值,列的序号从1开始
- XXX getXXX(String columnName) : 根据列名去获取XXX类型的值
- void close()关闭ResultSet 对象
SQL注入问题解决:preparedStatement
什么是SQL注入:
SQL 注入是用户利用某些系统没有对输入数据进行充分的检查,从而进行恶意破坏的行为。
1.preparedStatement概述
预编译对象, 是Statement对象的子类。
特点:
- 性能要高
- 会把sql语句先编译,格式固定好,
- sql语句中的参数会发生变化,过滤掉用户输入的关键字(or)。
2.用法
2.1通过connection对象创建
- prepareStatement(String sql) ;创建prepareStatement对象
- sql表示预编译的sql语句,如果sql语句有参数通过?来占位
2.2通过setxxx方法来指定参数
- setxxx(int i,Obj obj); i 指的就是问号的索引(指第几个问号,从1开始),xxx是类型(eg:int,String,Long)
eg:
1 2 3 4 5 6 7
| String sql = "select *from user where username =? and password =?";
statement = connection.prepareStatement(sql);
statement.setString(1, username); statement.setString(2, password); resultSet = statement.executeQuery();
|
连接池技术
自定义连接池
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| package top.simba1949.jdbc; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.util.LinkedList; public class DataSourceTest { private static LinkedList<Connection> pool = new LinkedList<>(); private static String url = "jdbc:mysql://localhost:3306/test"; private static String user = "root"; private static String password = "19491001"; static { try { Class.forName("com.mysql.jdbc.Driver"); for (int i = 0;i < 3;i++){ Connection connection = DriverManager.getConnection(url, user, password); pool.add(connection); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }
public static Connection getConnection(){ return pool.removeFirst(); } public static void release(Connection connection){ if (null != connection){ pool.add(connection); } } }
|
自定义规范连接池(装饰者设计模式)
装饰者设计模式
固定结构:接口A,已知实现类C,需要装饰者创建代理类B
- 创建类B,并实现接口A
- 提供类B的构造方法,参数类型为A,用于接受A的其他实现类
- 给类B添加类型为A的成员变量,用于存放A接口的实现类
- 增强需要的方法
- 实现不需要增强的方法,方法体重新调用成员变量存放的其他实现类对应的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package top.simba1949.jdbc; import java.sql.*; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executor; public class ConnectionTest implements Connection{ private Connection connection; private List<Connection> pool; public ConnectionTest(Connection connection) { this.connection = connection; } public ConnectionTest(Connection connection, List<Connection> pool) { this.connection = connection; this.pool = pool; } @Override public void close() throws SQLException { this.pool.add(this); } @Override public Statement createStatement() throws SQLException { return this.connection.createStatement(); } ...... }
|