JDBC
1、概述
基本概念:
- JDBC,Java DataBase Connectivity,Java数据库连接
- Java语言 操作数据库
- 定义了操作所有关系型数据库的规则(接口)
JDBC本质:官方(sun)公司定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口编程(JDBC),真正执行的代码是驱动jar包中的实现类。
2、JDBC 编程步骤
1、导入驱动jar包
mysql-connector-java-5.1.37-bin.jar
2、注册驱动(将这个类的字节码文件加载进内存)
Class.forName("com.mysql.jdbc.Driver")
3、获取数据库连接对象Connection
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc_demo","root","123456")
4、定义sql
String sql = "";
5、获取执行sql语句的对象Statement
Statement stat = conn.createStatement();
6、执行sql,接收返回结果
7、处理结果
8、释放资源
3、JDBC各个接口和类 详解
1、DriverManager
驱动管理对象 类
功能:
1、注册驱动:static void registerDriver(Driver driver);
写代码使用语句:
Class.forName("com.mysql.jdbc.Driver");
查看源码发现这个类存在静态代码块
static{ try{ java.sql.DriverManager.registerDriver(new Driver()); } catch(SQLException e){ throw new RuntimeException("can't register driver!"); } }
mysql5之后的驱动jar包可以省略注册驱动的步骤 -> 可以自动帮你去注册驱动
2、Connection 数据库连接对象
获取数据库连接
Static Connection getConnection(String url, String user, String password)
参数说明:
- url:指定连接的路径
jdbc:mysql://ip地址(域名):端口号/数据库名称
如果连接的是本机mysql服务器,并且mysql服务默认服务器端口为3306,url可以简写为
jdbc:mysql:///数据库名称
功能:
- 获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
- 管理事务
- 开启事务
void setAutoCommit(boolean autoCommit)
调用该方法设置参数false,即开启事务
- 管理事务
commit()
- 回滚事务
rollback()
- 注意:若想事务处理功能开启,需要在navicate设计表中选择引擎InnoDB
3、Statement 执行SQL的对象 (interface)
静态SQL:在执行SQL语句之前所有字符串都是拼接好的。静态SQL容易产生注入的问题
功能:执行SQL
boolean execute(String sql) // 不常用,了解即可 int executeUpdate(String sql) /* 执行DML语句(insert/update/delete) 执行DDL语句(create/alter/drop) -> 一般不经常执行 返回值:int 影响的行数,可以通过影响的行数判断DML语句是否执行成功 */ ResultSet executeQuery(String sql) // 执行DQL语句(select)
4、ResultSet 结果集对象,封装查询的结果
boolean next() // 游标向下移动一行,判断当前行是否是最后一行末尾,如果是,则返回false,否则,返回true getXxx() // 获取数据(某一列),Xxx代表数据类型
5、PreparedStatement 执行SQL的对象(功能比Statement更强大)
SQL注入问题:在拼接sql时,有一些sql的特殊关键字与字符串的拼接,会造成安全问题
解决SQL注入问题:使用PreparedStatement对象来解决
预编译SQL:参数使用?
占位符步骤:
…(省略1234步骤)
5、获取执行sql语句的对象PreparedStatementConnection.prepareStatment(String sql)
给
?
赋值的方法:
setXxx(参数1, 参数2…)
参数1为?
的位置编号,从1开始;参数2为?
的值后期都会使用PreparedStatement来完成增删改查的所有操作:
- 可以防止SQL注入
- 效率更高
4、JDBCUtils 抽取JDBC工具类
目的:简化书写
编写类分析:
1、注册驱动也要抽取
2、抽取一个方法获取连接对象
需求:不想传递参数(麻烦),还得保证工具类的通用性
-> 配置文件jdbc.properties
包含url
,user
,password
参数信息
3、抽取一个方法释放资源
实现:功能:获取连接,释放资源
public class JDBCUtils{...}
成员变量:
private static String url; private static String user; private static String pwd; private static String Driver;
静态代码块:
static{ // 读取资源文件,获取值 try{ // 1.创建Properties集合类 Properties pro = new Properties(); // 获取src路径下的文件的方式 -> ClassLoader 类加载器 ClassLoader classLoader = JDBCUtils.class.getClassLoader(); URL resource = classLoader.getResource("jdbc.properties"); // 2.加载文件 pro.load(new FileReader(path); // 3.获取数据,赋值 url = pro.getProperty("url") user = pro.getProperty("user") pwd = pro.getProperty("password") // 4.注册驱动 Driver = pro.getProperty("driver"); Class.forName(Driver); } catch(IOException e) { e.printStackTrace(); } catch(ClassNotFoundException e) { e.printStackTrace(); } }
获取连接 getConnection():
public static Connection getConnection(){ Connection conn = null; try{ conn = DriverManager.getConnection(url, user, pwd); } catch (SQLException throwables) { throwables.printStackTrace(); } return conn; }
释放资源 close(Connection conn, Statement stat):
public static void close(Connection conn, Statement stat){ if(stat != null){ try{ stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if(conn != null){ try{ conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }
重写释放资源 close(Connection conn, Statement stat, ResultSet res):
public static void close(Connection conn, Statement stat){ if(res != null){ try{ res.close(); } catch (SQLException e) { e.printStackTrace(); } } close(conn,stat); }