java--JDBC与类、接口

本文详细介绍了Java中JDBC的概念,包括JDBC的接口、类、操作步骤和代码实例。内容涵盖加载驱动、获取连接、创建Statement和PreparedStatement对象、执行SQL语句以及释放资源的方法。此外,还展示了通过学生姓名、编号查询数据以及获取自增主键值的代码演示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

JDBC概述

JDBC(Java Database Connectivity )是java语言操作数据库的API(应用程序接口),它在java.sql.*包下。要在你的IDE中导入相关的数据库jar包,我用的是MySQL数据库和idea编译器,导入的是这个https://pan.baidu.com/s/1u793mqxk_U2FwzsiDa27gAjar包

常用的接口

Connection 连接 代表了java和数据之间的通道,桥梁
Statement  语句 可以用来执行 insert, update, delete , select ...
ResultSet  结果集 代表的是查询的结果

常用的类

DriverManager 工具类,获取连接对象
SQLException  异常对象 是 Exception的子类型,属于检查异常 

操作步骤顺序

1、加载驱动 (Driver) jdbc的驱动就是一个连接工厂,生成的产品是连接对象

  • com.mysql.jdbc.Driver 是Driver的mysql实现类
  • oracle.jdbc.Driver    是Driver的oracle实现类

  格式: Class.forName("驱动类名");
  例如:Class.forName("com.mysql.jdbc.Driver");// jdbc 3.0 以上版本都可以省略加载驱动这一步
 2、获取连接对象

  • DriverManager.getConnection(url, 用户名, 密码); // 内部调用了  Driver 对象获取数据库连接,其中url的格式:jdbc:mysql://ip地址:端口号/数据库名?参数

  例如:mysql数据库
  Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");

3、创建语句对象

  • Statement stmt = conn.createStatement();

4、执行sql

  • int rows = stmt.executeUpdate(String sql); // 用来执行 insert , update, delete , DDL , 返回值代表影响行数
  • ResultSet rs = stmt.executeQuery(String sql); // 用来执行 select
  • boolean moreRows = rs.next() //取得下一条记录, moreRows 是true ,表示有下一条记录, false 表示没有了

5、释放资源( 先打开的资源后关闭 )

上述的第三步和第四步可以用另一个语法创建对象也就是用PreparedStatement (预编译语句)创建对象,它与Statement创建对象不同,它是把sql语句在创建对象是就放入的,也可以用“?”符号来对SQL语句进行占位,并给这个位置赋值,如下:

1.、需要预先提供sql语句

  • PreparedStatement psmt = conn.prepareStatement(String sql);

2、可以在sql中用?占位某个值

  • 如:String sql ="insert into student(sid,sname,birthday,sex) values(null, ?, ?, ?)" ;
  •         PreparedStatement psmt = conn.prepareStatement(sql);

3、给?赋值,使用PreparedStatement中一系列以 set开头的方法(位置1开始),有很多例举几个常用,如下 

  • setString(?的位置, 值)//给类型为String类型的变量赋值,从位置1开始
  • setInt(?的位置, 值)//给类型为Int类型的变量赋值,从位置1开始
  • setDate(?的位置, 值)//给类型为Date类型的变量赋值,从位置1开始

4、执行sql

  • int rows = psmt.executeUpdate();//用来执行 insert , update, delete , DDL , 返回值代表影响行数
  • ResultSet rs = psmt.executeQuery();//用来执行 select
  • boolean moreRows = rs.next() //取得下一条记录, moreRows 是true ,表示有下一条记录, false 表示没有了

代码演示

student表

1、编写一个方法,以学生的姓名作为条件查询,返回集合

创建一个类,该类中创建一个方法返回数据库连接

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

public class SqlConnection {
    //url格式:jdbc:mysql://ip地址:端口号/数据库名?参数
    private static final String URL="jdbc:mysql://localhost:3306/school";
    //数据库用户名
    private static final String USERNAME="root";
    //数据库密码
    private static final String PASSWORD="root";
    //私有构造方法是为了不需要new对象直接调用静态方法,方便
    private SqlConnection() {

    }
    //该方法返回与数据库的连接
    public static Connection con() throws SQLException {
        //返回与数据库连接
        return DriverManager.getConnection(URL,USERNAME,PASSWORD);
    }
}

Studnet用来存储表里列的值

import java.sql.Date;

public class Student {
    private String sname;//姓名
    private String sex;//性别
    private Date birthday;//出生日期
    private int sid;//学号
    //重写toString方法,直接输出Student对象时不会出现地址值,会出现修改过后的值
    @Override
    public String toString() {
        return "Student{" +
                "sname='" + sname + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", sid=" + sid +
                '}';
    }
    //构造方法给上面的变量赋值
    public Student(int sid, String sname, Date birthday, String sex) {
        this.sname = sname;
        this.sex = sex;
        this.birthday = birthday;
        this.sid = sid;
    }
    //以下都是获得变量值得方法
    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

编写一个类,并在之中编写以学生的姓名作为条件查询的方法

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class SelectName {
    private SelectName() {

    }
    //该方法返回类型是集合,参数是你要查找的人名
    public static List<Student> method(String name){
        //这个try是可以在程序结束时,自动关闭资源,因此这里没有写关闭资源
        //括号里是获取连接对象(也就是获取数据库连接对象)
        try(Connection connection=SqlConnection.con()){
            //用连接好的对象调用prepareStatement,操作SQL语句,这里是以学生的姓名作为条件查询,因此在名字上占个位,这样可以当你想找谁都行,不用固定某人
            PreparedStatement psmt = connection.prepareStatement("select * from student where sname like ?");
            //给占位处赋值,name是方法的参数
            psmt.setString(1,"%"+name+"%");
            //执行sql语句,executeQuery表示执行的是select语句,,如果不是查询语句用executeUpdate()
            ResultSet resultSet = psmt.executeQuery();
            //创建集合对象list用来装Student对象
            ArrayList<Student> list = new ArrayList<>();
            //遍历数据库表(student表)中的对象,并把对象存入Student对象中,next()为true时指正会指向该处,就可以用get的一系列方法获取
            while (resultSet.next()){
            //getInt(1)取得学号,getNString(2)取得姓名,getDate(3)取得出生年月,getNString(4)取得性别,它是按列的顺序获取的,而且数据库中的列的位置是从1开始的
                Student stu = new Student(resultSet.getInt(1), resultSet.getNString(2), resultSet.getDate(3), resultSet.getNString(4));
                //加入list集合中
                list.add(stu);
            }
            //返回list集合
            return  list;
        }catch(SQLException e){
            e.printStackTrace();
            return null;
        }
    }
}

上面的get方法里面也可以写数据库中的列名,表示取该列的值,如果改名字了就写新的名字,如:getNString("sid"),sid改名字改为学号,getNString("学号")(select sid 学号 from student),set方法一样可以。

main方法

import java.util.List;

public class SelectNameTest {
    public static void main(String[] args) {
        //调用SelectName类中查询学生的方法,这里的李表示,查询所有姓李同学的信息,而且因为SelectName的构造方法私有,因此不能new对象,直接用类名调用静态方法就好了
        List<Student> list = SelectName.method("李");
        //遍历返回的集合中的元素,x表示结合中的Sdtuent对象,然后输出它,后面跟的是lamda表达式
        list.forEach(x-> System.out.println(x));
    }
}

结果

Student{sname='李四', sex='男', birthday=1981-10-10, sid=1002}

2、编写一个方法,按照学生的编号查询,返回学生对象

该类用于获取数据库连接

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

public class SqlConnection {
    //url格式:jdbc:mysql://ip地址:端口号/数据库名?参数
    private static final String URL="jdbc:mysql://localhost:3306/school";
    //数据库用户名
    private static final String USERNAME="root";
    //数据库密码
    private static final String PASSWORD="root";

    private SqlConnection() {

    }
    //返回数据库连接
    public static Connection con() throws SQLException {
        return DriverManager.getConnection(URL,USERNAME,PASSWORD);
    }
}

该类用于存储表中列的值

import java.sql.Date;

public class Student {
    private String sname;//姓名
    private String sex;//性别
    private Date birthday;//出生年月
    private int sid;//学号

    @Override
    public String toString() {
        return "Student{" +
                "sname='" + sname + '\'' +
                ", sex='" + sex + '\'' +
                ", birthday=" + birthday +
                ", sid=" + sid +
                '}';
    }

    public Student(int sid, String sname, Date birthday, String sex) {
        this.sname = sname;
        this.sex = sex;
        this.birthday = birthday;
        this.sid = sid;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }
}

该类用于编写按照学生的编号查询的方法

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class SelectSid {
    private SelectSid() {

    }
    //返回类型为Student对象,参数要查询的学号
    public static Student method(int sid){
        //连接数据库
        try(Connection connection=SqlConnection.con()){
            //操作SQL语句
            PreparedStatement psmt = connection.prepareStatement("select * from student where sid=?");
            //给?处赋值,并且是从1开始,有两个?的话就是1、2
            psmt.setInt(1,sid);
            //执行查询语句,如果不是查询语句用executeUpdate()
            ResultSet resultSet = psmt.executeQuery();
            //判断是否有下一条语句,并将指针移到该处,并用get语句获得这一行的值
            resultSet.next();
            //获得的类型根据表中的类型的顺序来
            Student stu = new Student(resultSet.getInt(1), resultSet.getNString(2), resultSet.getDate(3), resultSet.getNString(4));
            //返回一个Student对象
            return stu;
        }catch(SQLException e){
            e.printStackTrace();
            return null;
        }
    }
}

main方法

public class SelectSidTest {
    public static void main(String[] args) {
        //查询学号为1003的学生的信息
        Student student = SelectSid.method(1003);
        System.out.println(student);
    }
}

结果

Student{sname='王五', sex='女', birthday=1981-11-10, sid=1003}

3、编写一个方法,查询每个部门的员工人数

编一个获取连接的类

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

public class SqlConnection {
    private static final String URL="jdbc:mysql://localhost:3306/school";
    private static final String USERNAME="root";
    private static final String PASSWORD="root";

    private SqlConnection() {

    }

    public static Connection con() throws SQLException {
        return DriverManager.getConnection(URL,USERNAME,PASSWORD);
    }
}

编写一个类,并在其中编写查询每个部门的员工人数的方法

import java.sql.*;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

public class SelectNum {
    private SelectNum() {

    }

    public static void method(){
        //连接数据库
        try(Connection connection=SqlConnection.con()){
            //操作sql语句
            PreparedStatement psmt = connection.prepareStatement("select deptno,count(*) from emp group by deptno");
            //执行查询语句,如果不是查询语句用executeUpdate()
            ResultSet rs = psmt.executeQuery();
            //用于存储部门编号(主键)和人数(主键所对应的值),
            Map<Integer, Integer> map = new TreeMap<>();
            while (rs.next()){
                //把存储部门编号和部门人数存入map集合中
                map.put(rs.getInt("deptno"),rs.getInt("count(*)"));
            }
            //遍历map集合取出值
            Set<Map.Entry<Integer, Integer>> entries = map.entrySet();
            for (Map.Entry<Integer, Integer> entry : entries) {
                System.out.println("部门编号:"+entry.getKey()+" 员工数:"+entry.getValue());
            }
        }catch(SQLException e){
            e.printStackTrace();
        }
    }
}

main方法

public class SelectNumTest {
    public static void main(String[] args) {
        SelectNum.method();
    }
}

结果

部门编号:10 员工数:3
部门编号:20 员工数:5
部门编号:30 员工数:6

4、获取自增的主键值

import java.sql.*;

public class TestJdbc {
    private static final String URL="jdbc:mysql://localhost:3306/school";
    private static final String USENAME="root";
    private static final String PASSWORD="root";
    public static void test(){
        String sql="insert into student(sname,birthday,sex) values (?,?,?)";
        //获取连接对象
        try (Connection conn = DriverManager.getConnection(URL, USENAME, PASSWORD)){
            //tatement.RETURN_GENERATED_KEYS 是一个选项,表示要返回自增的主键值
            try (PreparedStatement psmt = conn.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)){
                psmt.setString(1,"张丽");
                //set日期值时可以是字符串对象,但get日期值时要用getDate
                psmt.setString(2,"1998-12-11");
                psmt.setString(3,"女");
                //执行SQL语句
                psmt.executeUpdate();
                //返回一个结果集,结果集中存储了刚刚生成的主键值
                ResultSet keys = psmt.getGeneratedKeys();
                //因为这里只是插入一行,因此返回的也就一个主键,就不需要循环遍历了
                keys.next();
                //获得主键
                int sid = keys.getInt(1);
                System.out.println(sid);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        test();
    }
}

结果

1008
新student表

总结

把连接数据库的语句写在一个类中,如果你想改变连接的库或者其他时,你直接修改类中的连接就行了,这样既方便也使代码变简洁了,并且把写的类构造方法私有可以不用创建对象直接调用它的静态方法,会使调用静态方法很方便。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值