JDBC(Java Data Base Connectivity,java数据库连接)是java数据可连接技术的简称,提供连接各种常用数据库的能力。让java程序员可以直接通过java程序操作数据。jdbc是标准,它是由类与接口组成,对于程序员只需要知道标准(Connection Statement PreparedStatement ResultSet)不需要了解具体的实现就可以操作数据库
=====
DriverManager:这是一个实现类,它是一个工厂类,用来生产Driver对象这个类的结构设计模式为工厂方法;
Driver:这是驱动程序对象的接口,它指向一个实实在在的数据库驱动程序对象,那么这个数据库驱动是从哪里来的呢?
- DriverManager中有个方法:getDriver(String URL),通过这个方法可以得到驱动程序对象,这个方法是在各个数据库厂商按JDBC规范设计的数据库驱动程序包里的类中静态实现的,也就是在静态块中。
Connection:这个接口可以指向一个数据库连接对象,那么如何得带这个连接对象呢?
- 是通过DriverManager工厂中的getConnection(String URL)方法得到的
Statement:用于执行静态的SQL语句的接口,通过Connection中的createStatement方法得到的
ResultSet:用于指向结果集对象的接口,结果集对象是通过Statement中的execute等方法得到的
创建一个关于JDBC项目
1. 导入jar包
2. 注册驱动
- 反射
- Class.forName("com.mysql.jdbc.Driver");
3. 获取连接(Connection)
- Connection con = DriverManager.getConnection(String url, String username, String password);
4. 获取操作sql对象 (Statement)
- Statement st = con.createStatement();
如果要获取滚动结果集,可以使用createStatement(int, int);
5. 操作sql
- DQL 语句
ResultSet rs = st.executeQuery(String sql); - DML 语句
int row = st.executeUpdate(String sql);
6. 遍历结果集
- while(rs.next()) {
rs.getInt(int columnIndex);
rs.getString(String columuName);
}
7. 释放资源
- rs.close();
- st.close();
- con.close();
PreparedStatement
- 怎样获取?
PreparedStatement pst = con.prepareStatement(String sql); - 怎样给占位符“?”赋值
pst.setXxx(int,value); - 执行
pst.executeQuery();
pst.executeUpate();
Statement和PreparedStatement的区别
Statement每次执行sql语句,数据库都要执行sql语句的编译,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.但存在sql注入风险。PreparedStatement是预编译执行的。在执行可变参数的一条SQL时,PreparedStatement要比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率高。安全性更好,有效防止SQL注入的问题。对于多次重复执行的语句,使用PreparedStatement效率会更高一点。执行SQL语句是可以带参数的,并支持批量执行SQL。由于采用了Cache机制,则预编译的语句,就会放在Cache中,下次执行相同的SQL语句时,则可以直接从Cache中取出来。
PreparedStatement: 数据库会对sql语句进行预编译,下次执行相同的sql语句时,数据库端不会再进行预编译了,而直接用数据库的缓冲区,提高数据访问的效率(但尽量采用使用?号的方式传递参数),如果sql语句只执行一次,以后不再复用。
从安全性上来看,PreparedStatement是通过?来传递参数的,避免了拼sql而出现sql注入的问题,所以安全性较好。
在开发中,推荐使用 PreparedStatement
Statement 接口提供了执行语句和获取结果的基本方法。PreparedStatement 接口添加了处理 IN 参数的方法;而CallableStatement 添加了处理 OUT 参数的方法,用来调用存储过程。
CallableStatement
CallableStatement cstmt = con.prepareCall("call getTestData(?, ?)");
cstmt.setInt(1, sc.nextInt());
cstmt.registerOutParameter(2, Types.INTEGER);
cstmt.execute();
int result = cstmt.getInt(2);
什么是SQL注入,怎么防止SQL注入?
SQL注入就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意)的SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
那么,如何防止SQL注入?不相信用户输入,检查用户输入的合法性;将用户的登录名、密码等数据加密保存;不使用动态拼接sql,可以使用参数化或直接使用存储过程来执行所有的查询;不使用管理员权限的数据库连接,为每个应用创建单独的、有限的权限连接数据库用户。