使用jdbc操作数据库

jdbc概念

jdbc:Java数据库连接技术(Java DataBase Connectivity)
能实现java程序对各种数据库的访问
由一组使用Java语言编写的接口(java api)和类组成,位于java.sql和javax.sql包
面向接口编程
常用类:DriverManager
常用接口:Connection PrepareStatement ResultSet Statement
mysql、oracle、sqlserver厂商提供jar包来具体实现jdbc的接口

通过jdbc连接数据库

jdbc的优点
不必为不同的数据库专门编写不同的程序,而只需要加载不同的数据库驱动即可
前提:导包
1、Class.forName(String)加载驱动
2、获得数据库连接(Connection)
3、创建Statement/PrepareStatement对象,执行sql语句
4、返回并处理执行结果(若执行查询操作,返回ResultSet)
5、释放资源

public class Test {
    public static void main(String[] args) throws Exception {
        //导入jar包
        //1加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2获取连接 数据库地址URL 用户名 密码
        String url = "jdbc:mysql://192.168.232.234:3306/test";//虚拟机IP 库名
        //相当于登录
        Connection conn = DriverManager.getConnection(url, "root", "ok");
       //3执行增删改查等操作
        Statement stat = conn.createStatement();
        String sql = "select * from grade";
        //ResultSet 是结果集
        ResultSet rs = stat.executeQuery(sql);
        while (rs.next()) {//相当于指针 一行一行去遍历
            //如何取出每一列的值 
            //如果第一列是int类型 getInt(1)
            int gradeId = rs.getInt(1);
            //如果第二列是String类型 getString(2)
            String gradeName = rs.getString(2);
            System.out.println(gradeId + "\t|\t" + gradeName);
        }
         //但是有个问题 如果有很多列 按照第几列来遍历会不明确
        //可以根据列名来获取值 推荐使用
        while (rs.next()) {
            int gradeId = rs.getInt("GradeID");
            String gradeName = rs.getString("GradeName");
            System.out.println(gradeId + "\t|\t" + gradeName);
        }
        //4关闭资源 先使用的后关
        rs.close();
        stat.close();
        conn.close();
    }
}

在这里插入图片描述
补充说明
Class.forName(“com.mysql.jdbc.Driver”);
根据字符串找到Driver.class类,然后将类的信息加载到java虚拟机jvm,然后将驱动类实例化
与Driver d =new Driver(); 作用相同
Driver d =new Driver();先加载:先将类信息加载到java虚拟机中,然后创建对象
Class.forName(“com.mysql.jdbc.Driver”);后加载:事先不知道类的信息,在运行期间才知道要使用哪个类,去创建获取类的相关信息包括创建对象、获取类的方法、获取类的属性等(反射机制)

Connection conn = DriverManager.getConnection(url, “root”, “ok”);
将Driver实例放到DriverManager驱动管理器中,通过getConnection方法来获得数据库连接

Statement 和PreparedStatement

查看文档,PreparedStatement是Statement的子接口
Statement由方法createStatement()创建,该对象用于发送简单的SQL语句
PreparedStatement由方法prepareStatement()创建,该对象用于发送带有一个或者多个输入参数的SQL语句
SQL语句使用“?”作为数据占位符
使用setXxx()方法设置数据
PreparedStatement—预编译
效率、性能、开销
安全性
代码可读性

改一下需求
查询特定姓名的学生信息
用Statement的局限性 sql注入

public class Test {
    public static void getStudentByName(String name)throws Exception{
        //导入jar包
        //1加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2获取连接 数据库地址URL 用户名 密码
        String url = "jdbc:mysql://192.168.232.234:3306/test";//虚拟机IP 库名
        //相当于登录
        Connection conn = DriverManager.getConnection(url, "root", "ok");
        //3执行增删改查等操作
        Statement stat = conn.createStatement();
        String sql = "select * from student where stu_name='"+name+"'";
        ResultSet rs = stat.executeQuery(sql);
        while (rs.next()) {
            int i=1;
            while (rs.getMetaData().getColumnCount() >= i) {
                System.out.print(rs.getObject(i)+"\t|");
                i++;
            }
            System.out.println();
        }
        //4关闭资源
        rs.close();
        stat.close();
        conn.close();
    }
    public static void main(String[] args) throws Exception {
        getStudentByName("李白' or '1'='1");
    }
}

这里查询出全部学生的信息
在这里插入图片描述
使用PreparedStatement

public class Test {
    public static void getStudentByName(String name)throws Exception{
        //导入jar包
        //1加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2获取连接 数据库地址URL 用户名 密码
        String url = "jdbc:mysql://192.168.232.234:3306/test";//虚拟机IP 库名
        //相当于登录
        Connection conn = DriverManager.getConnection(url, "root", "ok");
        //3执行增删改查等操作
        String sql = "select * from student where stu_name=?";//占位符
        PreparedStatement stat = conn.prepareStatement(sql);//创建PreparedStatement对象时sql作为参数
        //在sql语句的第一个问号的位置填充name
        stat.setString(1,name);//填充第一个问号 值的类型是String
        System.out.println(sql);
        ResultSet rs = stat.executeQuery();
        while (rs.next()) {
            int i=1;
            while (rs.getMetaData().getColumnCount() >= i) {
                System.out.print(rs.getObject(i)+"\t|");
                i++;
            }
            System.out.println();
        }
        //4关闭资源
        rs.close();
        stat.close();
        conn.close();
    }
    public static void main(String[] args) throws Exception {
        getStudentByName("李白");
        //getStudentByName("李白' or '1'='1");
    }
}

在这里插入图片描述
拼接sql注入,没有显示
在这里插入图片描述
补充说明
Statement 是将sql语句发给数据库管理系统DBMS,然后DBMS对sql语句进行编译、语法的检查等,然后执行
PreparedStatement -预编译 将sql语句先进行语法的检查和编译,再交给DBMS执行

使用属性

public class TestPrepare {
    private static Connection conn;
    private static PreparedStatement pst;
    private static ResultSet rs;
    private static final String URL="jdbc:mysql://192.168.232.234:3306/test";
    public static void getConn(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        try {
            conn= DriverManager.getConnection(URL,"root","ok");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static void query(String sql,String...params){
        try {
            pst=conn.prepareStatement(sql);
            //遍历参数 将参数加到对应的问号位置 问号是从1开始
            for (int i = 0; i < params.length; i++) {
                pst.setObject(i+1,params[i]);
            }
            rs=pst.executeQuery();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static boolean update(String sql,String...params){
       int num=0;
        try {
            pst=conn.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                pst.setObject(i+1,params[i]);
            }
            //增删改 返回受影响的行数
            num=pst.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }
       return num>0?true:false;
    }
    public void close() {
        try {
            if (null!=rs) {
                rs.close();
            }
            if (null!=pst) {
                pst.close();
            }
            if (null!=conn) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
 }
        getConn();
        String s="update subject set subjectNo=?,GradeId=? where subjectName=? ";
        update(s,"9","2","高等数学-2");
        String s1="select * from subject where GradeId=?";
        query(s1,"2");
        while (rs.next()) {
            int i=1;
            //getMetaData 获取表结构 getColumnCount获取列数  
            while (rs.getMetaData().getColumnCount() >= i) {
                System.out.print(rs.getObject(i)+"\t|");
                i++;
            }
            //获取一行数据之后换行
            System.out.println();
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值