JDBC基本概述

JDBC是Java连接数据库的桥梁,包括驱动管理、Connection、Statement、ResultSet等组件。PreparedStatement能预编译SQL,提高效率并防止SQL注入。文章介绍了JDBC的基本操作,如增删改查,并展示了面向过程和面向对象两种实现方式。
摘要由CSDN通过智能技术生成

JDBC概述

JDBC(Java DataBase Connectivity)是一种用于执行SQL语句的 Java API,是Java数据库之间的一个桥梁,是一个规范而不是一个实现,能够交给数据库执行SQL语句。

JDBC的组成

JDBC是由一组用Java语言编写的类和接口组成,主要有如下几个部分

  • 驱动管理;

  • Connection接口;

  • Statement接口;

  • ResultSet接口;

Connection 接口

定义:在 JDBC 程序中用于代表数据库的连接,是数据库编程中最重要的一个对象,客户端与数据库所有的交互都是通过connection 对象完成的

Connection conn = DriverManager.getConnection(url,user,password);
常见方法:
  • createStatement() :创建向数据库发送的sql的statement对象。

  • prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。

  • prepareCall(sql) : 创建执行存储过程的callableStatement对象。(常用)

  • setAutoCommit(boolean autoCommit) : 设置事务是否自动提交。

    //关闭自动提交事务  
    setAutoCommit(false);  
    //关闭后需要手动打开提交事务
    
  • commit() : 在链接上提交事务。

  • rollback() : 在此链接上回滚事务。

Statement 接口
  • statement: 由createStatement创建,用于发送简单的SQL语句(不带参数).
Statement st = conn.createStatement();
  • PreparedStatement :继承自Statement接口,是Statement的子类,可发送含有参数的SQL语句。效率更高,并且可以防止SQL注入,建议使用
PreparedStatement ps = conn.prepareStatement(sql语句);

PreparedStatement 的优势:

  1. Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。
  2. 并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写,可以避免SQL注入的问题。
  • CallableStatement:继承自PreparedStatement接口,由方法 prepareCall创建,用于调用存储过程。
常见方法:
  • executeQuery(String sql) :用于向数据发送查询语句

  • executeUpdate(String sql) :用于向数据库发送insert、update或delete语句。

  • execute(String sql):用于向数据库发送任意sql语句。

  • addBatch(String sql):把多条sql语句放到一个批处理中。

    executeBatch():向数据库发送一批sql语句执行

ResultSet 接口

ResultSet:用于代表Sql语句的执行结果。

Resultset封装执行结果时,采用的类似于表格的方式,ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。

常用方法:
  • ResultSet.next() :移动到下一行;
  • ResultSet.Previous() :移动到前一行
  • ResultSet.absolute(int row):移动到指定行
  • ResultSet.beforeFirst():移动resultSet的最前面
  • ResultSet.afterLast():移动resultSet的最后面

面向过程的实现过程

1.在pom.xml中引入mysql的驱动文件

<!-- 引入MySql的驱动文件 -->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
   <version>8.0.32</version>

2.加载驱动类

Class.forName("com.mysql.cj.jdbc.Driver");

3.建立Java同数据库中间的连接通道

String url = "jdbc:mydql://locallhost:3306/test";//test是数据库名称
String user  = "root";
String password = "root";
Connection conn = DriverManager.getConnection(url,user,password);

4.产生负责’传递命令’的‘传令官’对象

String sql ="insert into emp values(null,"苏醒","歌手",7956,now(),79429,6799,30,1)";
PrepareStement ps = conn.prepareStement(sql);

5.接收结果集(只有查询有结果集)

int row = ps.excuteUpdate();//交由MySQL执行命令
System.out.println(row + "行受到影响!");

6.关闭连接通道

ps.close();
conn.close(); 

参数的传递方式

//键盘赋值 
private static Scanner scan;
	static{
        scan = new Scanner(System.in); 
    } 
拼接字符串方式
String sql = "insert into emp values(null ,'" + ename + "','" + job + "'," + mgr + ",now()," + sal + "," + comm + "," + deptNo + ",1)";
PrepareStement ps = conn.prepareStement(sql);
//接收结果集
int row = ps.excuteUpdate();//交由MySQL执行命令
System.out.println(row + "行受到影响!");
ps.close();
conn.close(); 
占位符方式 ‘?’
//插入 
String sql = "insert into emp values(null,?,?,?,now(),?,?,?,1)";
PrepareStement ps = conn.prepareStement(sql);
//给 ? 占位符赋值,  从1开始   具体数据类型,具体赋值  int String double
ps.setString(1,需要赋值的列);//需要几个列,附几个值
//接收结果集
int row = ps.excuteUpdate();//交由MySQL执行命令
System.out.println(row + "行受到影响!");
ps.close();
conn.close(); 
//注意异常处理
使用占位符的好处:
  • 可以有效避免SQL注入问题
  • 可以自动根据复制时的数据类型来决定是否引入"

删除:

物理删除
//完全删除,不可恢复
Connection conn = DriverManager.getConnection(url, user, password);
        //删除语句
        //开始产生运行处理MySQl命令的对象
        String sql = "delete  from emp where empno =" + 4;
        PreparedStatement ps = conn.prepareStatement(sql);
逻辑删除
//修改(update)状态,不会完全删除信息,可以恢复
String sql = "update  emp set state =0 where empno =?";
PreparedStatement ps = conn.prepareStatement(sql);
        ps.setInt(1, 7953);

查询操作

全查询
String sql = "select * from emp where state=1";
 PreparedStatement ps = conn.prepareStatement(sql);

        // 查询会返回结果集 rs就是查询出来的那张虚拟表
        ResultSet rs = ps.executeQuery();

        // 虚拟表格遍历出来
        while (rs.next()) { // 是否有下一行
            // 如果有下一行,就会执行这里的代码 rs就是下一行
            // 获取到当前行(rs)的每一列信息

            int empNo = rs.getInt(1);
            String ename = rs.getString(2);
            String job = rs.getString(3);
            int mgr = rs.getInt(4);
            String hireDate = rs.getString("hireDate");
            double sal = rs.getDouble(6);
            double comm = rs.getDouble(7);
            int deptNo = rs.getInt("deptNo");

            System.out.print("编号:" + empNo+"、");
            System.out.print("姓名:" + ename+"、");
            System.out.print("职位:" + job+"、");
            System.out.print("上司ID:" + mgr+"、");
            System.out.print("入职时间:" + hireDate+"、");
            System.out.print("工资:" + sal+"、");
            System.out.print("奖金:" + comm+"、");
            System.out.println("部门编号:" + deptNo);
        }

        rs.close();
        ps.close();
        conn.close();

    }
按ID查询
 String sql = "select * from emp where state=1 and empno=" + id;
        PreparedStatement ps = conn.prepareStatement(sql);

        ResultSet rs = ps.executeQuery();

        if (rs.next()) {
            int empNo = rs.getInt(1);
            String ename = rs.getString("ename");
            String job = rs.getString("job");
            int mgr = rs.getInt(4);
            String hireDate = rs.getString(5);
            double sal = rs.getDouble("sal");
            double comm = rs.getDouble(7);
            int deptNo = rs.getInt(8);

            //存放在容器中
            Map<String, Object> map = new HashMap<>();
            map.put("empNo", empNo);
            map.put("ename", ename);
            map.put("job", job);
            map.put("mgr", mgr);
            map.put("hireDate", hireDate);
            map.put("sal", sal);
            map.put("comm", comm);
            map.put("deptNo", deptNo);

            return map;
        }

        return null;

    }

面向对象(JDBC)的实现方式

面向对象是指将多个功能查分成多个包进行对数据库的增删改查(CRUD)操作。

db包作用

db包中只需要一个类–>DBManager类,这个类的主要作用就是负责管理数据的的连接

//负责管理数据库的连接
public class DBManager{
    /*
    
    
    
    */
    
    private satic Connection getConnection(){
        Connection conn = null;
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "root";
        conn = DriverManager.getConnection(url,uesr,password);
        
    }
}

bean包作用

一般和数据库中的表对应,bean包中的类一般都和表名相同,首字母大写,驼峰命名。

@Data
//模拟数据库中表的操作
//定义属性:成员变量:封装类,局部变量:原始数据类型
public class Emp {

    private Integer empNo;
    private String ename;
    private String job;
    private Integer mgr;
    private String hireDate;
    private Double sal;
    private Double comm;
    private Integer deptNo;
    private Integer state;

    //多表联查
    //方法一:
    private String dname;
    private String loc;


    //另一种写法
    private Dept dept;

}

dao包作用

DAO是Data Access Object数据访问接口,一般以bean包的类名为前缀,以DAO结尾,负责执行CRUD操作,一个dao类负责一个表的CRUD,也可以说成是对一个bean类的CRUD(增删改查)

public class EmpDAO(){
    
    
    // 一般对于删除操作,都是进行更新状态将之隐藏
    public void delete(int id){
        try{
        	conn = DBManager.getConnection();
       	 	String sql = "update  emp set state = 0 where empNo = "+ id;
        	ps = conn.prepareStatement(sql);  
        	ps.executeUpdate();
        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }catch(SQLException e){
            e.printStackTrace();
        }finally{
           DBManager.closeConn(conn, ps);
        }                
    }
    
    //存储
    public void save(Emp emp) {

        try {
            conn = DBManager.getConnection();
            String sql = "insert into emp values(null,?,?,?,now(),?,?,?,1)";
            ps = conn.prepareStatement(sql);

            ps.setString(1, emp.getEname());
            ps.setString(2, emp.getJob());
            ps.setInt(3, emp.getMgr());
            ps.setDouble(4, emp.getSal());
            ps.setDouble(5, emp.getComm());
            ps.setInt(6, emp.getDeptNo());
            ps.executeUpdate();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {

            DBManager.closeConn(conn, ps);
        }
    }
    
     //更新--修改
    public void update(Emp emp) {
        try {
            conn = DBManager.getConnection();
            String sql = "update emp set ename=?,job=?,mgr=?,sal=?,comm=?,deptNo=? where empNo=?";
            ps = conn.prepareStatement(sql);
            ps.setString(1, emp.getEname());
            ps.setString(2, emp.getJob());
            ps.setInt(3, emp.getMgr());
            ps.setDouble(4, emp.getSal());
            ps.setDouble(5, emp.getComm());
            ps.setInt(6, emp.getDeptNo());
            ps.setInt(7, emp.getEmpNo());
            ps.executeUpdate();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            DBManager.closeConn(conn, ps);
        }
    }
 	//单条信息查询--按ID查询--将填写的信息填写在emp属性里中,然后将emp
    public Emp findEmpByNo(int id) {
        Emp emp = new Emp();

        try {
            conn = DBManager.getConnection();
            String sql = "select * from emp where empno=? and state = 1";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, id);
            rs = ps.executeQuery();
            if (rs.next()) {
                //取出第一列的值赋给empNO
                emp.setEmpNo(rs.getInt(1));
                emp.setEname(rs.getString(2));
                emp.setJob(rs.getString(3));
                emp.setMgr(rs.getInt(4));
                emp.setHireDate(rs.getString(5));
                emp.setSal(rs.getDouble(6));
                emp.setComm(rs.getDouble(7));
                emp.setDeptNo(rs.getInt(8));
                emp.setState(1);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {

            DBManager.closeConn(conn, ps);
        }
        return emp;
    }

    //全表查询--集合
    public List<Emp> findAllEmp() {
        List<Emp> list = new ArrayList<>();

        try {
            conn = DBManager.getConnection();
            String sql = "select * from emp where state  = 1";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                Emp emp = new Emp();//每循环一次new一个新对象,给对象付一次值
                emp.setEmpNo(rs.getInt(1));
                emp.setEname(rs.getString(2));
                emp.setJob(rs.getString(3));
                emp.setMgr(rs.getInt(4));
                emp.setHireDate(rs.getString(5));
                emp.setSal(rs.getDouble(6));
                emp.setComm(rs.getDouble(7));
                emp.setDeptNo(rs.getInt(8));
                emp.setState(1);
                list.add(emp);//循环一次在集合中增加一条数据
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBManager.closeConn(conn, ps);
        }

        return list;

    }
}

多表联查

//多表联查
    //方法一:
    public List<Emp> findAllEmp2(){
        List<Emp> list = new ArrayList<>();
        try {
            conn = DBManager.getConnection();
            String sql = "select * from emp e left join Dept d on e.deptNo = d.deptNo where state =1";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()){
                Emp emp = new Emp();
                emp.setEmpNo(rs.getInt(1));
                emp.setEname(rs.getString(2));
                emp.setJob(rs.getString(3));
                emp.setMgr(rs.getInt(4));
                emp.setHireDate(rs.getString(5));
                emp.setSal(rs.getDouble(6));
                emp.setComm(rs.getDouble(7));
                emp.setDeptNo(rs.getInt(8));
                emp.setState(1);
                emp.setDname(rs.getString(11));
                emp.setLoc(rs.getString(12));
                list.add(emp);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBManager.closeConn(conn, ps,rs);
        }
        return list;
    }

    //方法二:
    public List<Emp> findAllEmp3(){
        List<Emp> list = new ArrayList<>();

        try {
            conn = DBManager.getConnection();
            String sql = "select * from emp e left join Dept d on e.deptNo = d.deptNo where state =1";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()){
                Emp emp = new Emp();
                emp.setEmpNo(rs.getInt(1));
                emp.setEname(rs.getString(2));
                emp.setJob(rs.getString(3));
                emp.setMgr(rs.getInt(4));
                emp.setHireDate(rs.getString(5));
                emp.setSal(rs.getDouble(6));
                emp.setComm(rs.getDouble(7));
                emp.setDeptNo(rs.getInt(8));
                emp.setState(1);
                Dept dept = new Dept();
                dept.setDeptNo(rs.getInt(10));
                dept.setDname(rs.getString(11));
                dept.setLoc(rs.getString(12));
                emp.setDept(dept);//引入dept表
                list.add(emp);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            DBManager.closeConn(conn, ps,rs);
        }

        return list;
    }
}

App运行代码

public class App {

    //删除
    private static void a(){
        EmpDAO edao = new EmpDAO();
        edao.delete(7935);
    }

    //传入参数
    private static void b(){
        EmpDAO edao = new EmpDAO();
        Emp emp = new Emp();
        emp.setEname("王铮亮");
        emp.setJob("歌手");
        emp.setMgr(7960);
        emp.setDeptNo(30);
        emp.setSal(36785.0);
        emp.setComm(123.4);
        edao.save(emp);
    }



    private static void c(){
        EmpDAO edao = new EmpDAO();
        Emp emp = new Emp();
        emp.setEname("陈na");
        emp.setMgr(7943);
        emp.setJob("页面设计");
        emp.setDeptNo(30);
        emp.setComm(123.4);
        emp.setSal(4788.8);
        emp.setEmpNo(7945);
        edao.update(emp);
    }


    private static void d(){

        //查询ID = 7956的员工的信息
        EmpDAO edao = new EmpDAO();
        Emp emp = edao.findEmpByNo(7956);
        System.out.println(emp);

    }

    private static void e(){
        EmpDAO edao = new EmpDAO();
        List<Emp> list = edao.findAllEmp();
        list.forEach(System.out::println);
    }

    private static void f1(){
        EmpDAO edao = new EmpDAO();
        List<Emp> list = edao.findAllEmp2();
        list.forEach(System.out::println);
    }

    private static void f2(){
        EmpDAO edao = new EmpDAO();
        List<Emp> list = edao.findAllEmp3();
        list.forEach(System.out::println);
    }


    public static void main(String[] args) {
        f2();
    }
}
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值