JDBC编程(上)

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(); } }
-------------------------------------------
10 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

 

上一篇:洛谷 P6082 [JSOI2015]salesman


下一篇:[bzoj4472][树形DP] Salesman