JDBC连接数据库

什么是JDBC

JDBC(Java Database Connectivity)是Java语言中用于连接和操作数据库的一组API。它允许Java程序通过标准的数据库连接方式,与不同种类的关系型数据库进行通信和交互。

JDBC提供了一种统一的编程接口,使得开发人员可以使用相同的代码来访问不同的数据库。它提供了一组类和接口,用于建立数据库连接、执行SQL查询和更新语句、处理事务以及处理数据库结果集等操作。

通过JDBC,开发人员可以使用Java程序连接各种数据库系统,如MySQL、Oracle、SQL Server等,并执行各种数据库操作,如查询数据、插入、更新和删除数据等。JDBC还提供了对事务处理的支持,可以确保数据库操作的原子性、一致性、隔离性和持久性。


JDBC的使用

导入依赖

创建Maven项目并在pom.xml导入MySQL连接依赖

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.26</version>
        </dependency>

连接数据库的6个步骤

1.加载驱动

        //1-加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");

2.创建连接

        //2-创建连接
        String url="jdbc:mysql://localhost:3306/easydata";
        String username="root";
        String userpass="123456";
        Connection con= DriverManager.getConnection(url,username,userpass);

3.获取执行对象

        //3-获取执行对象
        Statement sta=con.createStatement();

4.执行SQL语句

        //4-执行SQL语句
        String sql="select * from staff";
        ResultSet set = sta.executeQuery(sql);

5.解析处理结果

        //5-解析处理结果
        while (set.next()){
            //获取每一行数据
            //1.通过列名获取 2.通过列的位置获取
            int id = set.getInt(1);
            System.out.print(id+" ");
            String name= set.getString("name");
            System.out.println(name);
        }

6.关闭资源

        //6-关闭资源
        set.close();
        sta.close();
        con.close();

完整代码:

public class EasyJDBC {
    //JDBC
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1-加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2-创建连接
        String url="jdbc:mysql://localhost:3306/easydata";
        String username="root";
        String userpass="123456";
        Connection con= DriverManager.getConnection(url,username,userpass);
        //3-获取执行对象
        Statement sta=con.createStatement();
        //4-执行SQL语句
        String sql="select * from staff";
        ResultSet set = sta.executeQuery(sql);
        //5-解析处理结果
        while (set.next()){
            //获取每一行数据
            //1.通过列名获取 2.通过列的位置获取
            int id = set.getInt(1);
            System.out.print(id+" ");
            String name= set.getString("name");
            System.out.println(name);
        }
        //6-关闭资源
        set.close();
        sta.close();
        con.close();
    }
}


JDBC封装

JDBC的操作通常包括加载驱动程序、建立连接、创建Statement对象、执行SQL语句、处理结果集和关闭连接六个步骤。为了避免在操作数据库时出现大量的重复代码,对JDBC进行封装是一个非常常见的做法。通过对JDBC进行封装,可以大大简化数据库操作的代码,提高代码的可读性和可维护性,使代码更符合面向对象的设计原则。

创建一个JDBC封装工具类:

1.封装获取连接

    public static Connection getCon() throws ClassNotFoundException, SQLException {
        //1-加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2-创建连接
        String url="jdbc:mysql://localhost:3306/easydata";
        String username="root";
        String userpass="123456";
        Connection con= DriverManager.getConnection(url,username,userpass);
        return con;
    }

2.封装执行对象

    public static Statement getStatement(Connection con) throws SQLException {
        Statement sta=con.createStatement();
        return sta;
    }

3.反射处理数据

通过反射将获取的数据注入到对象中可以实现数据库与Java对象之间的转换,使得程序在处理数据库数据时更加灵活、高效。

    //反射处理数据
    public static <T> List<T> dataToObj(ResultSet rs,Class<T> clazz){
        //声明一个结果集合,如果rs中一行数据也没有 返回null
        List<T> result=null;

        T obj=null;
        //存放所有属性的名称
        List<String> fnameList=new ArrayList();
        //所有属性的对象
        Field[] f_arr=clazz.getDeclaredFields();
        for (Field fitem:f_arr){
            //获取属性名存入链表
            fnameList.add(fitem.getName());
            //设置属性可访问
            fitem.setAccessible(true);
        }

        try {
            while (rs.next()) {
                if (result == null) {
                    result = new ArrayList();
                }
                //通过类对象实例化一个该类的对象
                obj=clazz.newInstance();
                //约束属性名和列名一样就映射
                //遍历所有属性
                //从rs中取出对应属性名的数据存入obj对象中
                for(int i=0;i<fnameList.size();i++){
                    //属性名==列名
                    String fname=fnameList.get(i);
                    //检查类中的属性 是什么类型  int String Object
                    if (int.class==f_arr[i].getType()){
                        int val=rs.getInt(fname);
                        //将val设置到obj对象上
                        f_arr[i].set(obj,val);
                    }else if (String.class==f_arr[i].getType()){
                        String val=rs.getString(fname);
                        //将val设置到obj对象上
                        f_arr[i].set(obj,val);
                    }else {
                        Object val=rs.getObject(fname);
                        //将val设置到obj对象上
                        f_arr[i].set(obj,val);
                    }
                }
                result.add(obj);


            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

4.封装关闭资源

    public static void close(Connection con,Statement sta,ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(sta!=null){
            try {
                sta.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(con!=null){
            try {
                con.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }

5.封装查询过程

    public static <T> List<T> query(String sql,Class<T> clazz) throws SQLException {
        Connection con=null;
        Statement sta=null;
        ResultSet rs=null;
        //解析结果
        List<T> result=null;

        try {
            con=getCon();
            sta=getStatement(con);
            rs=sta.executeQuery(sql);
            result=dataToObj(rs,clazz);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭资源
            close(con,sta,rs);
        }

        return result;
    }

测试类

public class EasyJDBCTest {
    public static void main(String[] args) throws SQLException {
        List<Staff> list=JDBC.query("select * from staff",Staff.class);
        for (Staff staff:list){
            System.out.println(staff);
        }
    }
}

class Staff{
    private int id;
    private String code;
    private String name;
    private BigDecimal salary;

    @Override
    public String toString() {
        return "Staff{" +
                "id=" + id +
                ", code='" + code + '\'' +
                ", name='" + name + '\'' +
                ", salary=" + salary +
                '}';
    }
}


预编译执行对象

SQL执行过程分为编译和执行,使用PreparedStatement的作用:预编译SQL语句并执行

1.可以加快批处理        2.有效预防SQL注入

什么是SQL注入

SQL注入是用户向SQL传入特殊的参数导致SQL语义发生变化,从而获取非法数据,是一种通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法。

避免SQL注入主要的方式有:1.参数检查         2.预编译

    public static void query(String name) throws ClassNotFoundException, SQLException {
        //1-加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2-创建连接
        String url="jdbc:mysql://localhost:3306/easydata";
        String username="root";
        String userpass="123456";
        Connection con= DriverManager.getConnection(url,username,userpass);
        //3-获取执行对象
        Statement sta=con.createStatement();
        //4-执行SQL语句
        String sql="select * from staff where name='"+name+"'";
        System.out.println(sql);
        ResultSet set = sta.executeQuery(sql);
        //5-解析处理结果
        while (set.next()){
            //获取每一行数据
            //1.通过列名获取 2.通过列的位置获取
            int id = set.getInt(1);
            System.out.print(id+" ");
            String staffname= set.getString("name");
            System.out.println(staffname);
        }
        //6-关闭资源
        set.close();
        sta.close();
        con.close();
    }

正常传入一个姓名查询:

SQL注入示例:

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        //query("李思思");
        query("' or '1'='1");
    }


使用预编译执行

使用预编译执行对象,在SQL语句中使用问号 作为占位符,传入时指定第几个占位符赋值

//        Statement sta=con.createStatement();
//        String sql="select * from staff where name='"+name+"'";
//        System.out.println(sql);

        PreparedStatement sta=con.prepareStatement("select * from staff where name=?");
        sta.setString(1,name);
        ResultSet set = sta.executeQuery();
  • 20
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值