JDBC的基本介绍

1、概述:jdbc是使用Java访问各种数据库的一种技术

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。

(1)jdbc工作原理

JDBC——连接数据库 随笔 第1张

2、jdbc核心Java类(API)

(1)DriverManager类

作用:管理各种数据库的驱动(JDBC的驱动),可以用它来获取数据库连接。根据所给的驱动去获取对应数据库的链接

(2)Connection接口

负责连接数据库,并担任传输数据的任务

(3)Statement接口

由Connection产生,负责执行SQL语句

(4)ResultSet接口

负责保存Statement执行后所产生的查询结果(数据库中查询出来的数据保存在ResultSet中)

3、使用JDBC的步骤

(1)建立Java与数据库之间的链接,将数据库的驱动包,复制到项目的lib目录中,复制完毕以后鼠标右键jar包,选择build path ,再选择 add to build path

JDBC——连接数据库 随笔 第2张

(2)新建一个专门负责连接数据库的工具类DBUtil,并准备连接数据库的数据

连接数据库需要知道数据库的地址url,用户名 user,密码 password,以及数据库对应的驱动。如果需要连接数据库需要先将这些数据准备好。参考代码如下:

/**
 * 连接数据库的工具类
 */
public class DBUtil {
    //1.准备连接数据库的数据
    // 数据库服务器的地址
    // jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库
    // localhost: 本机的ip地址 可以写成 127.0.0.1
    // 3306 : mysql 的默认端口号
    static String url = "jdbc:mysql://localhost:3306/myschool";
    // 数据库的用户名 :mysql的默认用户名是root
    static String user = "root";
    // 数据库的密码: 填写自己的mysql 密码
    static String password = "root";
    // 数据库的驱动
    static String driver = "com.mysql.jdbc.Driver";
    
}

(3)在DBUtil类中,添加获取数据库的工具方法

在一个项目中,会频繁使用,所以将它封装成一个工具方法,参考代码如下:

/**
     * 负责获取数据库连接的工具方法
     * @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库)
     */
    public static Connection getCon(){
        //1.安装数据库驱动(加载驱动类)
        try {
            Class.forName(driver);
            //2.根据url,user,password获取数据库连接
            Connection con = 
                DriverManager.getConnection(url, user, password);
            return con;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

(4)添加main方法测连接,参考代码如下:

public static void main(String[] args) {
        System.out.println(getCon());
}

运行结果:

JDBC——连接数据库 随笔 第3张

(5)DBUtil完整代码

package jdbc;

import java.sql.Connection;
import java.sql.DriverManager;

/**
 * 连接数据库的工具类
 */
public class DBUtil {
    //1.准备连接数据库的数据
    // 数据库服务器的地址
    // jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库
    // localhost: 本机的ip地址 可以写成 127.0.0.1
    // 3306 : mysql 的默认端口号
    static String url = "jdbc:mysql://localhost:3306/myschool";
    // 数据库的用户名 :mysql的默认用户名是root
    static String user = "root";
    // 数据库的密码: 填写自己的mysql 密码
    static String password = "root";
    // 数据库的驱动
    static String driver = "com.mysql.jdbc.Driver";
    
    /**
     * 负责获取数据库连接的工具方法
     * @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库)
     */
    public static Connection getCon(){
        //1.安装数据库驱动(加载驱动类)
        try {
            Class.forName(driver);
            //2.根据url,user,password获取数据库连接
            Connection con = 
                DriverManager.getConnection(url, user, password);
            return con;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    
    public static void main(String[] args) {
        System.out.println(getCon());
    }
    
}

3、使用JDBC实现对数据库表的增删改查

(1)向指定数据库表中插入数据

案例:使用jdbc向subject表中插入数据,参考代码如下:

① 创建一个实体类与数据库中中的表对应起来

package jdbc;
/**
 * 创建一个实体类 与数据库中中的表对应起来
 * 实体类:Subjet   对应  数据库表 subject
 * 实体类的属性              对应  数据库表中的字段
 * @author xp
 *
 */
public class Subject {
    private int subjectNo;// 对应subject表中的subjectNo 字段
    private String subjectName;//对应subject表中的subjectName字段
    private int classHour;//对应subject表中的classHour字段
    private int gradeId;//对应subject表中的gradeId字段
    public int getSubjectNo() {
        return subjectNo;
    }
    public void setSubjectNo(int subjectNo) {
        this.subjectNo = subjectNo;
    }
    public String getSubjectName() {
        return subjectName;
    }
    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }
    public int getClassHour() {
        return classHour;
    }
    public void setClassHour(int classHour) {
        this.classHour = classHour;
    }
    public int getGradeId() {
        return gradeId;
    }
    public void setGradeId(int gradeId) {
        this.gradeId = gradeId;
    }
    
}

② 新建一个Dao类,来操作数据库表,参考代码如下:

package jdbc;

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

/**
 * 操作数据库表 subject
 *
 */
public class SubjectDao {
    /**
    *向数据库表subject中插入数据的方法
    */
    public static void insert(Subject sub){
        //获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        // id是自增涨的,所以这里不需要插入id,插入数据时会自动生成id
        String sql = "insert into subject("
                + "subjectName,classHour,gradeId)"
                + " values('"+sub.getSubjectName()
                + "',"+sub.getClassHour()
                + ","+sub.getGradeId()+")";
        System.out.println(sql);
    
        //3.构建sql语句
        Statement st = null;
        try {
            st = con.createStatement();
            //4.执行sql语句
            st.execute(sql);
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            //5.关闭连接
            try {
                st.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            
        }
    }

    public static void main(String[] args) {
        //测试插入方法
        Subject sub = new Subject();
        //只设置课程名称,表示只向数据库表中插入课程名称
        sub.setSubjectName("布丁制作");
        insert(sub);
    }
}

(2)查询指定表中的数据

例如:查询某一个表中的所有数据, 在dao中添加查询所有数据的方法

public static List<Subject> findAll(){           
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        String sql = "select * from subject";
        //3.构建sql语句
        Statement st = null;
        try {
            st = con.createStatement();
            //4.执行sql语句
            //ResultSet 用来封装查询出的结果集 类似于集合中的iterator迭代器
            ResultSet rs = st.executeQuery(sql);
            List<Subject> subs = new ArrayList<Subject>();
            // rs.next()判断结果集中是否有下一个元素,如果有就取出
            while(rs.next()){
                //创建课程对象
                Subject sb = new Subject();
                //取出结果中subjectNo,并存入到课程中
                // rs.get字段类型(字段名) 获取字段中对应的值
                sb.setSubjectNo(rs.getInt("subjectNo"));
                sb.setSubjectName(rs.getString("subjectName"));
                sb.setClassHour(rs.getInt("classHour"));
                sb.setGradeId(rs.getInt("gradeID"));
                
                //将封装好的课程对象加入到集合中
                subs.add(sb);
            }
            //将封装好的课程集合返回
            return subs;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                st.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

(3)execute,executeUpdate,executeQuery的区别

4、修改数据表中的数据

(1)根据subjectNo查询出数据,参考代码如下:

/**
*根据subjectNo查询出数据
*/
public static Subject findSubjectByNo(int subjectNo){
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        String sql = "select * from subject where subjectNo="+subjectNo;
        //3.构建sql语句
        Statement st = null;
        try {
            st = con.createStatement();
            //4.执行sql语句
            ResultSet rs = st.executeQuery(sql);
            //Subject sb = new Subject();
            Subject sb = null;
            while(rs.next()){
                sb = new Subject();
                sb.setSubjectNo(rs.getInt("subjectNo"));
                sb.setSubjectName(rs.getString("subjectName"));
                sb.setClassHour(rs.getInt("classHour"));
                sb.setGradeId(rs.getInt("gradeID"));
            }
            return sb;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                st.close();
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    
    }

(2)修改数据的方法

/**
* 修改数据
**/
public static void update(Subject sub){
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        String sql = "update subject set "
                + " subjectName='"+sub.getSubjectName()+"' ,"
                + " classHour="+sub.getClassHour()+" ,"
                + " gradeID="+sub.getGradeId()
                + " where subjectNo="+sub.getSubjectNo();
        System.out.println(sql);
        //3.构建sql语句
        Statement st = null;
        try {
            st = con.createStatement();
            st.executeUpdate(sql);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                st.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

(3)测试方法

//根据subjectNO 修改数据
        //1. 根据subjectNO 查询出数据
        Subject sub = findSubjectByNo(10);
        //sub.setSubjectNo(10);
        //2. 设置想要修改的数据
        sub.setSubjectName("如何养生");
        update(sub);

5、sql注入:使用拼接字符串的形式,向sql语句中注入代码片段

现有代码如下:

public static Master findMasterByNameAndPwd(String name ,String pwd ){
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        String sql = "select * from master where name='"+name+"' and password='"+pwd+"'";
        //3.构建sql语句
        Statement st = null;
        try {
            st = con.createStatement();
            ResultSet rs = st.executeQuery(sql);
            Master master = null;
            while(rs.next()){
                master = new Master();
                  master.setId(rs.getInt("id"));
                master.setName(rs.getString("name"));
                master.setPassword(rs.getString("password"));
                master.setMoney(rs.getInt("money"));
            }
            return master;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                st.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        
        return null;
    }

如果这种方式登录,那么我们可以采用sql注入的形式,就算不知道用户名和密码,我们同样可以登录成功具体操作如下:

JDBC——连接数据库 随笔 第4张

注意:Statement 构建sql语句需要用+拼接值,容易造成SQL。

(1)避免sql注入,使用PreparedStatement

概述:预编译的sql语句,继承Statement接口,比Statement更加灵活,效率更高,提高了sql语句的可读性,提高了sql语句的执行性能,提高了安全性

例如:

public static void  insert(Dog dog){
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        // ? 问号,占位符,表示此处需要设置一个值
        String sql = "insert into dog (name,health,love,strain) values (?,?,?,?)";
        //3.编译sql语句
        PreparedStatement pst =  null;
        try {
            pst = con.prepareStatement(sql);
            //4.如果sql语句中有? ,就需要给?设置值
            //pst.set类型(第几个问号,要设置给?号的值)
            pst.setString(1, dog.getName());
            pst.setInt(2, dog.getHealth());
            pst.setInt(3, dog.getLove());
            pst.setString(4, dog.getStrain());
            
            //5.执行sql语句
            int num = pst.executeUpdate();
            if(num!=0){
                System.out.println("数据插入成功");
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
    } 

注意:使用PreparedStatement时在sql语句中需要设置值时,用?,有几个?,就设置几个值

例如:setString(1,name);

表示给第一个?,设置name值

(2)将Statement替换成PrepareStatemen

public static Master findMasterByNameAndPwd(String name ,String pwd ){
        //1.获取数据库连接
        Connection con = DBUtil.getCon();
        //2.编写sql语句
        //String sql = "select * from master where name='"+name+"' and password='"+pwd+"'";
        String sql = "select * from master where name=? and password=? ";
        System.out.println(sql);
        //3.构建sql语句
        //Statement st = null;
        PreparedStatement pst = null;
        try {
            //st = con.createStatement();
            pst = con.prepareStatement(sql);
            pst.setString(1, name);
            pst.setString(2, pwd);
            //ResultSet rs = st.executeQuery(sql);
            ResultSet rs = pst.executeQuery();
            Master master = null;
            while(rs.next()){
                master = new Master();
                
            }
            return master;
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                pst.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return null;
    } 

运行结果:

JDBC——连接数据库 随笔 第5张

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄