JDBC三种编译
来源:互联网 发布:阜阳市工商局网络监管 编辑:程序博客网 时间:2024/06/06 14:16
JDBC中有三个主要用于编译的API,分别是Statement接口、PrepareStatement接口以及CallableStatement接口。
1、Statement接口编译
手动连接数据库,创建一个表
package com.wk.jdbc;import java.sql.Connection;import java.sql.DriverManager;import java.sql.SQLException;import java.sql.Statement;import org.junit.Test;/* * 使用jdbc执行sql语句 * */public class JDBC2 { private String user = "wk"; private String psw = "199645"; //连接数据库的url private String url = "jdbc:mysql://localhost:3306/myfirst"; @Test public void test1(){ Statement state = null; //com.sql.Statement Connection conn = null; //加载驱动 //发送sql语句 String sql = "create table teacher("+ "id int primary key auto_increment,"+ "name varchar(10),"+ "class varchar(20));"; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection(url,user,psw); state = conn.createStatement(); //更新行数 int count = state.executeUpdate(sql); System.out.println(count); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { if(state != null) state.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } try { if(conn != null) conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
2、PrepareStatement预编译,该接口是Statement的子接口,在编译sql语句时用占位符?作为参数,在执行前设置参数。
这里使用JdbcUtil工具连接数据库,新增一条记录(可参考——-——JDBC技术)
package com.wk.jdbc;import java.sql.Connection;import java.sql.SQLException;import org.junit.Test;import java.sql.PreparedStatement;import com.wk.jdbc_util.JdbcUtil;/* * 使用预编译PrepareStatement执行sql语句 * */public class JDBC4 { @Test public void test(){ Connection conn = null; PreparedStatement pst = null; try { conn = JdbcUtil.getConnection(); String sql = "UPDATE STUDENT SET NAME = ? WHERE id = ?"; pst = conn.prepareStatement(sql); //设置参数,参数索引从1开始 pst.setString(1, "张三"); pst.setInt(2, 1); int count = pst.executeUpdate(); System.out.println(count); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JdbcUtil.close(conn, pst); } }}
3、前两种是增删改操作,只返回一个更新记录的行数,如果用于查询则返回一个结果集封装在ResultSet对象中。查询一个表操作如下
package com.wk.jdbc;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import org.junit.Test;import com.wk.jdbc_util.JdbcUtil;/* * jdbc执行DQL查询语句 * */public class JDBC3 { @Test public void test1(){ Connection conn = null; Statement state = null; ResultSet result = null; try { conn = JdbcUtil.getConnection(); state = conn.createStatement(); //查询语句 String sql = "select *from student"; //执行sql,返回数据保存在ResultSet对象中 result = state.executeQuery(sql); while(result.next()){ //列索引取法 //注意这里的游标从1开始,代表表中的第一个字段,getXXX()获取相应数据类型 int id = result.getInt(1); String name = result.getString(2); int age = result.getInt(3); String addr = result.getString(4); System.out.println(id+"-"+name+"-"+"-"+age+"-"+addr); } } catch (SQLException e) { e.printStackTrace(); }finally{ JdbcUtil.close(conn, state, result); } } }
4、CallableStatement编译结果集。属于PrepareStatement接口的子接口,首先在数据库中创建一个存储过程(可参考——-——JDBC技术)
DELIMITER $CREATE PROCEDURE insertAndQuery()BEGIN INSERT INTO student (NAME,age,address) VALUES ('李明',20,'英语教材'); SELECT *FROM student WHERE NAME='李明';END $
然后在程序中只需要调用SQL语句“CALL insertAndQuery()”即可,这是无参数的存储过程,下面看一个带有输入输出参数的存储过程
DELIMITER $CREATE PROCEDURE pro_findById(IN sid INT,OUT sname VARCHAR(20))BEGIN SELECT NAME INTO sname FROM student WHERE id=sid; -- 表示根据id找姓名END$
使用CallableStatement来调用存储过程
package com.wk.jdbc;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.SQLException;import org.junit.Test;import com.wk.jdbc_util.JdbcUtil;/* * * 使用CallableStatement对象调用存储过程 */public class JDBC6 { @Test public void test(){ Connection conn = null; CallableStatement cs = null; try { conn = JdbcUtil.getConnection(); //第一个占位符为输入参数,第二占位符为输出参数 String sql = "CALL pro_findById(?,?)"; cs = conn.prepareCall(sql); //设置输入参数 cs.setInt(1, 2); //注册输出参数 cs.registerOutParameter(2, java.sql.Types.VARCHAR); //执行查询 cs.executeQuery(); //用变量接收输出参数的值,调用getXXX()方法,参数和占位符所在位置对应 String result = cs.getString(2); System.out.println(result); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ JdbcUtil.close(conn, cs); } }}
5、Statement中的注入问题
这是一个用Statement查询的例子,当输入正确的用户名和密码会返回succeed,否则返回failed,与数据库比较没有该记录,所以返回的是failed
package com.wk.jdbc;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import org.junit.Test;import com.wk.jdbc_util.JdbcUtil;/* * * Statement的注入问题 */public class JDBC5 { private String name = "liming"; private String passward = "13456"; @Test public void test(){ Connection conn = null; Statement stat = null; ResultSet rs = null; try { conn = JdbcUtil.getConnection(); stat = conn.createStatement(); String sql = "SELECT *FROM admin WHERE userName='"+name+"' AND password='"+passward+"'"; rs = stat.executeQuery(sql); if(rs.next()){ System.out.println("successed"); }else{ System.out.println("failed"); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ try { if(rs!=null) rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } JdbcUtil.close(conn, stat); } }}
failed //返回值
如果输入一个已存在用户
private String name = "小明";private String passward = "123456";succeed//返回值
如果再次进行修改
private String name = "小明' OR 1=1 -- ";private String passward = "3456";succeed //密码错误依然可以验证成功
这就是Statement中的注入问题,因为“1=1”在sql中是恒成立的,并且后面内容被注释所以输入任何内容都可以访问数据库,所以应该选择PrepareStatement进行预编译比较安全
阅读全文
0 0
- JDBC三种编译
- oracle 三种JDBC驱动
- JDBC三种连接方式
- JDBC (三)
- JDBC(三)
- JDBC(三)
- 注册JDBC驱动的三种方式
- 注册Jdbc驱动程序的三种方式
- jdbc链接数据库的三种方式
- Jdbc注册驱动的三种方式
- 注册jdbc驱动程序的三种方式
- 注册Jdbc驱动程序的三种方式
- 注册JDBC驱动的三种方式
- JDBC驱动注册的三种方式
- 注册JDBC驱动的三种方式
- JDBC的批处理操作三种方式
- JDBC的批处理操作三种方式
- 注册jdbc驱动程序的三种方式
- sed 工具基本使用方法
- python异常处理
- ApplicationContext 接口容器和BeanFactory 接口容器
- C++ 视频课笔记3
- mybatis数据库查询
- JDBC三种编译
- 2017.7.26学习总结
- python中的继承
- android值制作简易的闹钟和通知栏信息
- C++ 视频课笔记4
- java Iterator
- HDOJ 5098 Smart Software Installer【拓扑排序】
- SQL语句
- 红黑树java实现