0603 JDBC 、开发步骤、注入问题、预处理executeupdate、executequery方法、工具类

 JDBC概述

JDBC(Java Data Base Connectivity,java数据库连接)执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范

JDBC原理

JDBC需要连接驱动,驱动是两个设备要进行通信,满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信

 

理解:

java与数据库连接的一种类,jdk提供的接口叫JDBC,数据库的厂商提供的实现类叫驱动,驱动就是实现类,JDBC需要6个步骤,有两种不同的增删改查,反之拼串出现异常,用 PreparedSttement预处理方法,减少更多的代码量,将重复的代码封装在一个类里。

JDBC开发步骤

1.注册驱动.:告知JVM使用的是哪一个数据库的驱动

2.获得连接.使用JDBC中的类,完成对MySQL数据库的连接

3获得语句执行平台:通过连接对象获取对SQL语句的执行者对象

4执行sql语句:使用执行者对象,向数据库执行SQL语句,获取到数据库的执行后的结果

处理结果.放到容器,ArraList

6.释放资源.   调用一堆close()方法,释放内存

导入驱动jar包

解压L:mysql-connector-java-5.1.37

目录

docs:文档手册

src:放源码

倒数第三:驱动包

1.md lib目录

1:(项目文件夹new-Folder起名 lib),复制jar包粘贴到lib目录,存放当前项目需要的所有jar包

2:选择jar包,右键build path / Add to Build Path(添加到环境)牛奶瓶

 

 2.API详解:注册驱动 

3.获得连接对象:类名:Connection

jdbc:mysql://localhost:3306/mydb

 

代码:Connection con = DriverManager.getConnection
(“jdbc:mysql://localhost(or 127.0.0.1):3306/mydb”,”root”,”root”);

 

JDBC的url的格式三部分,部分中间使用冒号分隔

第一部分 JDBC 固定的

第二部分  数据库名称,连接mysql数据库,第二部分当然是mysql了

第三部分 locanhost  =127.0.0.1,端口 3306  和DATABASE名称 (mysql组成)  

  

Connection conn  接口  ,DriverManager。。是实现类:多态形式    导包 全导sql包 

 4.获得语句执行平台:Statement

格式:

String sql = "某SQL语句";
获取Statement语句执行平台:Statement stmt = con.createStatement();

常用方法:

1、int int:executeUpdate(String sql); --执行 insert、update、delete 返回执行 int(返回行数)  增、删、改、查都用它

2、Result   executeQuery(String sql);--执行select语句,返回resultset结果集对象,(二维表格)放到ArrayList

3、boolean  execute(String sql);执行select 返回true 执行其他 返回false

5处理结果集:(执行 inset 、update、delete无序处理)

ResultSet 就是一张二维表格,可以调用boolean next() 方法指向某行记录,当第一次调用next()方法时,便指向第一行记录的位置,可以使用ResultSet提供的getXXX(int col)方法(与索引不同,列从1开始)来获取指定列的数据

6、释放资源close (关闭顺序:先开的后关 ,反之)

package com.oracle.demo01;
//数据的增删改,把红色的部分替换
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Add新增 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");//静态方法  "" 里面放包名加类名
        //2.获取链接对象 (报异常:因为用户输入的串可能写错)后面设置下数据格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插这句=红娘
        String user="root";
        String password="123456";
     //Connection:接口   Driver:实现类型  多态形式    全导 sql包 Connection conn
=DriverManager.getConnection(url,user,password); //System.out.println(conn);//打印conn测试,如果sql服务关了,会报错 //3.获得执行语句平台  Statement Statement sta=conn.createStatement(); //4.执行sql语句 新增:一套语句执行一句sql语句 String sql="insert into sort(sname) values('口红')";//外面双引号 里面必须单引号
     String sql="update sort set sname='金箍棒' where sid=4"; //数据的改
     String sql="delete from sort where sid=1";//数据的删 int row=sta.executeUpdate(sql);//执行语句 返回值int 是行数 System.out.println(row); //6.释放资源(先开的后关)关的是变量名 sta.close();//sta在conn的后面 conn.close(); } }

 看异常

最顶上:信息,异常类,位置(找认识的位置)

1.com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column

原因:Sting类型没有加单引号

2.Duplicate entry '1' for key 'PRIMARY'

原因,主键值存在或混乱,要先删除数据或者清空表

3.com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'password' in

原因:可能输入的值的类型不对,确定是否插入的元素时对应的值的类型正确

4.Data truncated for column 'Prices' at row 1

原因:数据过长导致被截断,注意对应值的类型与长度限制——一般把长度调高一点就可以

 pm

API详解:处理结果集(执行insert、update、delete无需处理)

rs.next();//指向第一行
rs.getInt(1);//获取第一行第一列的数据
package com.oracle.demo01;
//查询 Query
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;

public class Query {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");//静态方法    
        //2.获取链接对象
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插这句=红娘
        String user="root";        
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //3.获得语句执行平台
        Statement sta=conn.createStatement();
        //4.执行SQL
        String sql="select * from sort";
        ResultSet rs=sta.executeQuery(sql);//结果集对象装的二维表格
        //5.处理结果集:所有查询才有第五步 (括号里一般是第1列、第2列,但是可以写字段名)
        ArrayList<Sort> arr=new ArrayList<Sort>();//容器要放在 while外面
        while(rs.next()){
            //System.out.println(rs.getInt(1)+"..."+rs.getString(2));//()里的1 和2可以改为 sid和 sname
            Sort sort=new Sort();
            sort.setSid(rs.getInt("sid"));
            sort.setSname(rs.getString("sname"));
            arr.add(sort);//循环一次就放一次
        }
        System.out.println(arr);
        //6.释放资源
        rs.close();
        sta.close();
        conn.close();
    }
}

 

package com.oracle.demo01;

public class Sort {
    //字段对应属性
    private int sid;
    private String sname;
    //get set toString方法
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    @Override
    public String toString() {
        return "Sort [sid=" + sid + ", sname=" + sname + "]";
    }    
}
-------------------------------------------
package com.oracle.demo01;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");//静态方法
        //2.获取链接对象
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插这句=红娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);
        //3.获得执行语句平台
        Statement sta=conn.createStatement();    
        //4.执行sql
        String sql="select count(*) from sort";
        ResultSet rs=sta.executeQuery(sql);
        //5.处理结果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);
        }
        System.out.println(count);
        //6.释放资源(先开的后关)
        rs.close();
        sta.close();
        conn.close();        
    }
}

四、注入问题:

  假设有登录案例SQL语句如下:

  SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;

  此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’  OR ‘a’=’a时,则真正执行的代码变为:

  SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’  OR ’a’=’a’;

查询语句时永远可以查询出结果的。用户就直接登录成功了,这便是SQL注入问题

使用PreparedStatement来解决对应的问题。

package com.oracle.demo01;
//登录功能 sql注入问题
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Demo05 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");//静态方法
        //2.获取链接对象 (导包都导sql的,不选JDBC的;多态!报异常是因为用户输入的串可能写错)后面设置下数据格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插这句=红娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);//打印conn测试,如果sql服务关了,会报错
        //System.out.println(conn);
        //3.获得执行语句平台
        Statement sta=conn.createStatement();    
        //4.执行sql
        //让用户输入用户名
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名");
        String uname=sc.next();
        //用户输入密码
        System.out.println("请输入密码");
        String pwd=sc.next();
        String sql="select count(*) from "
                + "user where uname='"+uname+"' and pwd='"+pwd+"'";
        ResultSet rs=sta.executeQuery(sql);
        //5.处理结果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);
        }
        System.out.println(count);
        //6.释放资源(先开的后关)
        rs.close();
        sta.close();
        conn.close();        
    }
}

 

预处理对象    PreparedStatement

  使用PreparedStatement预处理对象时,建议每条sql语句所有的实际参数,都使用逗号分隔。

String sql = "insert into sort(sid,sname) values(?,?)";;

PreparedStatement预处理对象代码:

PreparedStatement psmt = conn.prepareStatement(sql)

常用方法:

执行SQL语句:

 int executeUpdate(); --insert update delete语句.增删改

 ResultSet executeQuery(); --select语句.查询

 boolean execute(); --执行select返回true 执行其他的语句返回false.

实际参数

void setXxx(int index, Xxx xx) 指定参数设置为xx值,将此值发送到数据库时,驱动程序将它转换成一个 SQL Xxx类型

 

举例:setString(2, "家用电器") 把SQL语句中第2个位置的占位符? 替换成实际参数 "家用电器"

 

package com.oracle.demo01;
//预处理对象executeQuery方法

通过预处理对象的executeQuery方法,完成记录的select语句的执行。格式

 1. 注册驱动 2. 获取连接 3. 获取预处理对象4. SQL语句占位符设置实际参数5. 执行SQL语句6. 处理结果集(遍历结果集合)7. 释放资源
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class PrepareStatement {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");//静态方法
        //2.获取链接对象 (导包都导sql的,不选JDBC的;多态!报异常是因为用户输入的串可能写错)后面设置下数据格式
        String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";//0603后面插这句=红娘
        String user="root";
        String password="123456";
        Connection conn=DriverManager.getConnection(url,user,password);
        //System.out.println(conn);//打印conn测试,如果sql服务关了,会报错
        //System.out.println(conn);
        //3.获取语句执行平台对象
        String sql="select count(*) from user where"
                + " uname=? and pwd=?";
        PreparedStatement pst=conn.prepareStatement(sql);
        //4.执行sql
        Scanner sc=new Scanner(System.in);
        //让用户输入用户名
        System.out.println("请输入用户名: ");
        String uname=sc.next();
        //让用户输入密码
        System.out.println("请输入密码:");
        String pwd=sc.next();
        //给sql语句的? 赋值
        pst.setString(1,uname);
        pst.setString(2, pwd);
        ResultSet rs=pst.executeQuery();//调query的方法 ()里不用写SQL
        //5.处理结果集
        int count=0;
        while(rs.next()){
            count=rs.getInt(1);
        }
        System.out.println(count);
        //6.释放资源(先开的后关)
        rs.close();
        pst.close();
        conn.close();        
    }
}

JDBC工具类

获得数据库连接”,将在以后的增删改查所有功能中都存在,可以封装工具类JDBCUtils。提供获取连接对象方法,达到代码的重复利用

package com.oracle.demo01;
//JDBC工具类
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtils {
    //获取连接对象的方法(静态的)
    public static  Connection getConn(){
        Connection conn=null;
                try {
                    //1.注册驱动(静态方法)(包名+类名)
                    Class.forName("com.mysql.jdbc.Driver");
                    //2.获取连接对象(导包都导sql里面的,不导jdbc里的;多态!报异常是因为用户输入的串可能写错)后面设置下数据格式
                    String url="jdbc:mysql://localhost:3306/java0603?useUnicode=true&characterEncoding=UTF-8";
                    String user="root";
                    String password="123456";
                    conn=DriverManager.getConnection(url,user,password);
                } catch (ClassNotFoundException | SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                return conn;    
    }
    //释放资源
    public static void close(Connection conn,Statement sta){
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
    //释放资源2
    public static void close(Connection conn,Statement sta,ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 PreparedStatement 新增功能:

package com.oracle.demo01;
//PreparedStatement 新增功能
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class Demo08 {
    public static void main(String[] args) throws SQLException {
        add();
    }
    //新增分类Sort
    public static void add() throws SQLException{
        //1.获得连接对象
        Connection conn=JDBCUtils.getConn();
        //测试一下地址 System.out.println(conn);
        //2.获取语句执行平台
        String sql="insert into sort (sname) values(?)";
        PreparedStatement pst=conn.prepareStatement(sql);
        //3.执行sql
        pst.setString(1, "打火机");
        int row=pst.executeUpdate();
        System.out.println(row);
        //4.释放资源
        JDBCUtils.close(conn, pst);
    }
}

 

posted @ 2019-06-03 11:08  zhansen521  阅读(1140)  评论(0编辑  收藏  举报