JDBC:Java和数据库链接的技术
核心类和接口:
两个类:
DriverManager:负责加载驱动
SQLException:和数据库交互过程中可能产生的异常
接口:
Connection:与特定数据库的连接,在连接上下文中执行SQL语句并返回结果
Statement:用于执行静态SQL语句并返回它所生成结果的对象
PreparedStatement:表示执行预编译的SQL语句的对象,继承并扩展了Statement接口
CallableStatement:用于执行SQL存储过程的接口,继承并扩展了PreparedStatement接口(暂时不用)
ResultSet:装载数据库结果集的接口,存放执行结果的对象
创建JDBC应用:
先引入jar包
右键项目文件夹-->Build Path-->Configure Build Path...-->Libraries-->Add External JARs...
1.加载驱动
2.建立于数据库的链接
3.创建Statement对象
4.和数据库交互 增删改查
5.从resultSet中获取查询结果
6.关闭资源,从里往外
//查询单条记录 //根据部门编号查询部门数据 //1.加载驱动 参数是驱动名称 Connection conn = null; Statement st = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); //2.建立于数据库的链接 conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/scott", "root", "root"); /* * 第一个参数:链接路径 * 第二个参数:数据库的用户名 root * 第三个参数:数据库用户的密码 root */ //3.创建Statement对象 st = conn.createStatement(); /* * 4.和数据库交互 增删改查 * executeQuery:执行查询功能 */ rs = st.executeQuery("select * from dept where deptno = 10"); /* * 5.从resultSet中获取查询结果 * 使用的方法必须和结果列的数据类型完全匹配 */ if(rs.next()){ System.out.println(rs.getInt("deptno")+" "+rs.getString("dname")+" "+rs.getString("loc")); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ //6.关闭资源,从里往外 try { rs.close(); st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } ------------------------------------------- ACCOUNTING NEW YORK
//查询多条记录 //查询emp表的所有数据 Connection conn = null; Statement st = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/scott", "root", "root"); st = conn.createStatement(); rs = st.executeQuery("select * from emp "); //多条记录循环遍历取结果 //指定列值参数也可以是列的索引 while(rs.next()){ System.out.println(rs.getInt("empno")+" "+rs.getString("ename")+" "+rs.getDate("hirdate")); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ try { rs.close(); st.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } -------------------------------------- 1 jerry 1990-01-01 7369 SMITH 1980-12-17 7499 ALLEN 1981-02-20 7521 WARD 1981-02-22 7566 JONES 1981-04-02 7654 MARTIN 1981-09-28 7698 BLAKE 1981-05-01 7782 CLARK 1981-06-09 7788 SCOTT 1987-04-19 7839 KING 1981-11-17 7844 TURNER 1981-09-08 7876 ADAMS 1987-05-23 7900 JAMES 1981-12-03 7902 FORD 1981-12-03 7934 MILLER 1982-01-23
sql注入问题:
【例】登录功能SQL注入示例。 import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class SqlInject { public static void login (String name,String pwd) throws SQLException{ Connection conn = null; Statement st = null; ResultSet rs = null; try{ conn = DBUtil.getConnection(); st = conn.createStatement(); String sql = "SELECT * FROM t_user WHERE NAME='"+name+"' AND PWD='"+pwd+"'"; rs = st.executeQuery(sql); if(rs.next()){ System.out.println("登录成功.."); }else{ System.out.println("登录失败.."); } }finally{ DBUtils.close(rs, st, conn); } } public static void main(String[] args) throws SQLException { login("123123", "sadfsdf or 1=1");//注入SQL } --------------------------------------------- 程序分析:上例中若传入的用户名为sadfsdf or 1=1,则不管用户名和密码是否正确,都能成功登录,因为1=1永远为真,和其它条件进行or操作,也永远为真,所以不管用户名和密码是否正确,都能成功登录,这就是SQL注入问题。
PreparedStatement接口
为解决Statement静态拼接所产生的SQL注入问题,引入了PreparedStatement接口。PreparedStatement接口是Statement接口的子接口。
//根据用户名查询用户信息,要求用户名从控制台输入 Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { Class.forName("com.mysql.jdbc.Driver"); conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/scott", "root", "root"); System.out.println("请输入要查询的用户名:"); String ename = new Scanner(System.in).nextLine(); ps = conn.prepareStatement("select * from emp where ename=?"); /*给参数赋值 使用的方法数据类型要和参数匹配 第一个参数是?的索引 第二个参数是实际的值*/ ps.setString(1, ename); //执行SQL rs = ps.executeQuery(); //多条记录循环遍历取结果 //指定列值参数也可以是列的索引 while(rs.next()){ System.out.println(rs.getInt("empno")+" "+rs.getString("ename")+" "+rs.getDate("hiredate")); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ try { rs.close(); ps.close(); conn.close(); } catch (SQLException e) { e.printStackTrace(); } } ----------------------------------------------------------------- 请输入要查询的用户名: JONES 7566 JONES 1981-04-02
--2021.4.19