当前位置:Gxlcms > 数据库问题 > JDBC--jdbc操作数据库

JDBC--jdbc操作数据库

时间:2021-07-01 10:21:17 帮助过:25人阅读

  JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

2.数据库驱动

      我们安装好数据库之后,我们的应用程序也是不能直接使用数据库的,必须要通过相应的数据库驱动程序,通过驱动程序去和数据库打交道。其实也就是数据库厂商的JDBC接口实现,即对Connection等接口的实现类的jar文件。

技术分享

3、JDBC常用接口、类介绍

DriverManager

管理JDBC驱动的服务类,主要通过它获取Connection数据库链接,常用方法如下:
public static synchronized Connection getConnection(String url, String user, String password) throws Exception;
该方法获得url对应的数据库的连接。

Connection常用数据库操作方法:

Statement createStatement throws SQLException: 该方法返回一个Statement对象。
PreparedStatement prepareStatement(String sql) throws SQLException;该方法返回预编译的Statement对象,即将SQL语句提交到数据库进行预编译。
CallableStatement prepareCall(String sql) throws SQLException:该方法返回CallableStatement对象,该对象用于存储过程的调用。
上面的三个方法都是返回执行SQL语句的Statement对象,PreparedStatement、CallableStatement的对象是Statement的子类,
只有获得Statement之后才可以执行SQL语句。
关于Connection控制事务的方法:
Savepoint setSavepoint(): 创建一个保存点
Savepoint setSavepoint(String name):创建一个带有名称的保存点
void setTransactionIsolation(int level):设置事务隔离级别
void rollback():回滚事务
void rollback(Savepoint savepoint):回滚到指定保存点
void setAutoCommit(boolean autoCommit): 关闭自动提交,打开事务
void commit():提交事务

Statement

用于执行SQL语句的API接口,该对象可以执行DDL、DCL语句,也可以执行DML语句,还可以执行SQL查询语句,当执行查询语句是返回结果集,常用方法如下:
ResultSet executeQuery(String sql) throws SQLException:该方法用于执行查询语句,并返回查询结果对应的ResultSet对象,该方法只用于查询语句。
int executeUpdate(String sql) throws SQLException:该方法用于执行DML语句,并返回受影响的行数;该方法也可以执行DDL,执行DDL返回0;
boolean execute(String sql) throws SQLException:该方法可以执行任何SQL语句,如果执行后第一个结果是ResultSet对象, 则返回true;如果执行后第一个结果为受影响的行数或没有任何结果,则返回false;

PreparedStatement

预编译的statement对象,PreparedStatement是Statement的子接口,它允许数据库预编译SQL(通常指带参数SQL)语句,以后每次只改变SQL命令参数,避免数据库每次都编译SQL语句,这样性能就比较好。而相对于Statement而言,
使用PreparedStatement执行SQL语句时,无需重新传入SQL语句,因为它已经预编译了SQL语句。但是PreparedStatement需要为编译的SQL语句传入参数值,所以它比了如下方法:
void setXxx(int index, value)根据该方法传入的参数值的类型不同,需要使用不同的方法。传入的值的类型根据传入的SQL语句参数而定。

CallableStatement

   对象为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参,    另一种形式不带结果参数。结果参数是一种输出 (OUT) 参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN 参数)、输出(OUT 参数)或输入和输出(INOUT 参数)的参数。问号将用作参数的占位符。 

ResultSet

ResultSet提供检索不同类型字段的方法,常用的有:

    • getString(int index)、getString(String columnName):获得在数据库里是varchar、char等类型的数据对象。
    • getFloat(int index)、getFloat(String columnName):获得在数据库里是Float类型的数据对象。
    • getDate(int index)、getDate(String columnName):获得在数据库里是Date类型的数据。
    • getBoolean(int index)、getBoolean(String columnName):获得在数据库里是Boolean类型的数据。
    • getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。

  ResultSet还提供了对结果集进行滚动的方法:

    • next():移动到下一行
    • Previous():移动到前一行
    • absolute(int row):移动到指定行
    • beforeFirst():移动resultSet的最前面。
    • afterLast() :移动到resultSet的最后面。
注意:在JDK1.4以前只支持next移动,且每次移动一个位置。到JDK1.5就可以随意定位。

4、使用JDBC的步骤

    加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源

    

2.建立连接

  URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:

  技术分享

     常见参数:

                                             user                       用户名

                                             password                  密码

                                            autoReconnect                  联机失败,是否重新联机(true/false)

                                             maxReconnect              尝试重新联机次数

                                           initialTimeout               尝试重新联机间隔

                                          maxRows                   传回最大行数

                                         useUnicode                 是否使用Unicode字体编码(true/false)

                                        characterEncoding          何种编码(GB2312/UTF-8/…)

                                        relaxAutocommit            是否自动提交(true/false)

                                         capitalizeTypeNames        数据定义的名称以大写表示

5、JDBC事务

1、 事务介绍

事务是一步或多步组成操作序列组成的逻辑执行单元,这个序列要么全部执行,要么则全部放弃执行。
事务的四个特性:原子性(Atomicity)、一致性(Consistency)、隔离性(IsoIation)和持续性(Durability)

原子性(Atomicity:事务应用最小的执行单元,不可再分。是事务中不可再分的最小逻辑执行体。

一致性(Consistency:事务的执行结果,必须使数据库的从一个一致性的状态变到另一个一致性的状态。

隔离线(IsoIation:各个事务的执行互不干扰,任意一个事务的内部操作对其他并发的事务,都是隔离的。也就是:并发执行的事务之间不能看到对方的中间状态,并发执行的事务之间不能互相影响。

持续性(Durability:持续性也称为持久性(Persistence),指事务一旦提交,对数据所做的任何改变,都要记录到永久存储器中,通常就是保存在物理数据库中。

通常数据库的事务涉及到的语句有:
一组DML(Data Munipulation Language,数据操作语言)语句,这组DML语句修改后数据将保持较好的一致性; 操作表的语句,如插入、修改、删除等;
一个DDL(Data Definition Language,数据定义语言)语句,操作数据对象的语言,有create、alter、drop。
一个DCL(Data Control Language,数据控制语言)语句,主要有grant、revoke语句。
DDL和DCL语句最多只能有一个,因为它们都会导致事务的立即提交。当事务所包含的全部数据库操作都成功执行后,应该提交事务,使这些修改永久生效。
事务提交有两种方式:显示提交和自动提交。显示提交:使用commit提交  自动提交:执行DLL或DCL,或者程序正常退出
当事务包含的任意一个数据库操作执行失败后,应该回滚(rollback)事务,使该事务中所作的修改全部失效。
事务的回滚方式有两种:显示回滚和自动回滚。显示回滚:使用rollback    自动回滚:系统错误或强行退出
6.代码区


技术分享
package com.dao;

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

/**
 * 链接数据库工具类
 * @author Administrator
 *
 */
public class BaseDao {
    public static final String DRIVER="com.mysql.jdbc.Driver";
    public static final String URL="jdbc:mysql://127.0.0.1:3306/tb47";
    public static final String USER="root";
    public static final String PASSWORD="ok";
    
    public Connection conn=null;
    public CallableStatement cs=null; //该执行者调用存储过程
    public ResultSet rs=null;
    
    static{
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            System.out.println("driver 有问题");
            e.printStackTrace();
        }
    }
    
    public Connection getConnection(){
        try {
            conn=DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            System.out.println("URL, USER, PASSWORD 有问题");
            e.printStackTrace();
        }
        return conn;
    }
    

    public void closeAll(ResultSet rs, CallableStatement cs, Connection conn) {
        try {
            if(rs!=null){
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(cs!=null){
                cs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
    }
    

    

}
BaseDao  调用存储过程 技术分享
package com.dao;

import java.util.List;

import com.entity.Student;

/**
 * 
 * @author Administrator
 *
 */
public interface StudentDao {
    /**、
     * 查询所有
     * @return
     */
    List<Student> findAll();  //没有参数存储过程
   /**、
    * 查询单条
    * @param sid
    * @return
    */
    Student findById(int sid); //有输入参数存储过程
    /**
     * 统计所有数据条数
     * @return
     */
    int totalCount(); //有输出参数的存储过程
    /**
     * 统计某个年龄段的人数
     * @param age
     * @return
     */
    int totalCountAge(int age); //有输入参数和输出参数的存储过程
    
    
}
StudentDao 技术分享
package com.dao.impl;

import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
import java.util.List;

import com.dao.BaseDao;
import com.dao.StudentDao;
import com.entity.Student;

public class StudentDaoImpl extends BaseDao implements StudentDao{
    /**
     * 1.查询所有:调用没有参数的存储过程
     */
    @Override
    public List<Student> findAll() {
        List<Student> list=new ArrayList<Student>();
        try {
            //获取数据库链接
            conn=super.getConnection();
            //定义调用存储过程的语句
            String sql="{call proc_student_noparam()}";
            //创建调用存储过程的执行者并发送调用语句
            cs=conn.prepareCall(sql);
            //执行者执行查询操作,返回n条用
            rs=cs.executeQuery();
            while(rs.next()){
                Student stu=new Student(rs.getInt("cid"), rs.getInt("sid"), rs.getString("sname"), rs.getString("password"), rs.getInt("age"), rs.getString("subject"), rs.getDouble("score"), rs.getString("examtime"));
               list.add(stu);
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            this.closeAll(rs, cs, conn);
        }
        return list;
    }
    /**
     * 2.查询单条:调用输入参数存储过程
     */
    @Override
    public Student findById(int sid) {
        //定义对象
        Student stu=null;
        //获取数据库连接
        conn=super.getConnection();
        //定义调用存储过程的语句
        String sql="{call proc_student_hasparam(?)}";
        try {
            //创建调用存储过程的执行者并发送调用语句
            cs=conn.prepareCall(sql);
            //执行者给调用存储过程领命中的占位符赋值    
            cs.setInt(1, sid);
            //执行者执行查询操作:返回一条
            rs=cs.executeQuery();
            if(rs.next()){
                 stu=new Student(rs.getInt("cid"), rs.getInt("sid"), rs.getString("sname"), rs.getString("password"), rs.getInt("age"), rs.getString("subject"), rs.getDouble("score"), rs.getString("examtime"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
         //返回对象
        return stu;
    }
   /**
    * 3.统计总条数:调用带有输出参数存储过程
    */
    @Override
    public int totalCount() {
        //定义
        int count=0;
        //获取数据库连接
        conn=super.getConnection();
        //定义调用存储过程命令
        String sql="{ call proc_student_outparam(?)}";
        try {
            //创建调用存储过程的执行者并发送调用命令
            cs=conn.prepareCall(sql);
            //执行者注册输出参数,并指定参数数据类型
            cs.registerOutParameter(1, Types.INTEGER);
            //执行者执行存储过程操作
            cs.execute();
            //执行者获取执行后得到的输出参数结果
            count=cs.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //释放资源
            super.closeAll(rs, cs, conn);
        }
        //返回结果
        return count;
    }
    /**
     * 4.统计大于某个年龄段的学生人数:
     * 调用带有输入和输出参数的存储过程
     * 输入和输出参数是两个或同一个的变量
     */
    @Override
    public int totalCountAge(int age) {
        //定义接受输出参数值变量
        int count=0;
        //获取数据库链接
        conn=super.getConnection();
        try {
            //方法1:输出输入是两个参数
            /*
             //定义调用存储过程语句
             String sql="{call proc_student_inoutparam(?,?)}";
            //创建调用存储过程的执行者并发送调用命令
            cs=conn.prepareCall(sql);
            //为调用命令的占位符赋值
            cs.setInt(1, age);
            //注册输出参数
            cs.registerOutParameter(2, Types.INTEGER);*/
            
            //方法2:输入输出是同一个参数
            //定义调用存储过程语句
            String sql="{call proc_student_inoutOneParam(?)}";
            //创建调用存储过程的执行者并发送调用命令
            cs=conn.prepareCall(sql);
            //为调用命令的占位符赋值
            cs.setInt(1, age);
            //注册输出参数
            cs.registerOutParameter(1, Types.INTEGER);
            
            //执行调用存储过程操作
            cs.execute();
            //获取存储过程输出参数结果
            count=cs.getInt(1);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            super.closeAll(rs, cs, conn);
        }
        return count;
    }

}
StudentDaoImpl 技术分享
package com.part2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * 2.链接数据库的工具类
 * @author Administrator
 *
 */
public class BaseDao {
    // 1.定义驱动
    public static final String DRIVER = "com.mysql.jdbc.Driver";
    // 2.定义url
    public static final String URL = "jdbc:mysql://127.0.0.1:3306/tb50";
    // 3.定义user、
    public static final String USER = "root";
    // 4.定义password
    public static final String PASSWORD = "ok";
    // 5.定义Connection通路
    public static Connection conn = null;
    // 6.定义执行者preparedStatement
    public static PreparedStatement pstm = null;
    // 7.定义结果集resultset
    public static ResultSet rs = null;
    // 8.static中加载驱动=建立mysql和java
    static {
        try {
            Class.forName(DRIVER);
        } catch (ClassNotFoundException e) {
            System.out.println("DRIVER 有问题");
            e.printStackTrace();
        }
    }
    /**
     * 9.获取数据库连接
     * @return
     */
    public Connection getConnection(){
        try {
            conn=DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("URL, USER, PASSWORD 由问题");
        }
        return conn;
    }
    /**
     * 10.增删改公共方法
     * @param sql
     * @param obj
     * @return
     */
    public int executeUpdate(String sql,Object[] param){
        int num=0;
        try {
            //10.1获取数据库链接
            this.conn=this.getConnection();
            //10.2.创建执行者并发送sql命令
            pstm=conn.prepareStatement(sql);
            //10.3 执行者循环给sql占位符赋值
            if(param!=null){
                for (int i = 0; i < param.length; i++) {
                    pstm.setObject(i+1, param[i]);
                }
            }
            //10.4 .执行操作
             num=pstm.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //10.5 释放资源
            this.closeAll(rs,pstm,conn);
            
        }
        
        return num;
    }
    /**
     * 12.查询的公共方法
     * @param sql
     * @param obj
     * @return
     */
    public ResultSet executeQuery(String sql,Object[] param){
        try {
            //10.1获取数据库链接
            this.conn=this.getConnection();
            //10.2.创建执行者并发送sql命令
            pstm=conn.prepareStatement(sql);
            //10.3 执行者循环给sql占位符赋值
            if(param!=null){
                for (int i = 0; i < param.length; i++) {
                    pstm.setObject(i+1, param[i]);
                }
            }
            //10.4 .执行操作
            rs=pstm.executeQuery();
            
        } catch (SQLException e) {
            
            e.printStackTrace();
        }
        return rs;
    }
    /**
     * 11.释放资源
     * @param rs2
     * @param pstm2
     * @param conn2
     */
    public void closeAll(ResultSet rs, PreparedStatement pstm,
            Connection conn) {
        try {
            if (rs!=null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (pstm!=null) {
                pstm.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (conn!=null) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        
        
    }

    
}
BaseDao 深度封裝 技术分享
package com.part2;

import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
 * 增删改查实现类
 * @author Administrator
 *
 */
public class StudentDaoImpl extends BaseDao implements IStudentDao {
    /**
     * 1.查询所有
     */
    @Override
    public List<Student> findAll() {
        //1.1定义list集合,用来存放rs中的内容
        List<Student> list=new ArrayList<Student>();
        //1.2定义sql
        String sql="select * from student";
        //1.3调用basedao的查的方法、
        super.rs=super.executeQuery(sql, null);
        try {
            //1.4 循环获取rs的内容并添加到list集合
            while(rs.next()){
                //1.4.1 循环拿到一条赋值给student对象一个
                /*Student stu=new Student();
                stu.setAge(rs.getInt("age"));
                stu.setCid(rs.getInt("cid"));
                stu.setExamtime(rs.getString("examtime"));
                stu.setPassword(rs.getString("password"));
                stu.setScore(rs.getDouble("score"));
                stu.setSid();
                stu.setSname(rs.getString("sname"));
                stu.setSubject(rs.getString("subject"));*/
                Student stu=new Student(rs.getInt("cid"), rs.getInt("sid"), rs.getString("sname"), rs.getString("password"), rs.getInt("age"), rs.getString("subject"), rs.getDouble("score"), rs.getString("examtime"));
                
                //1.4.2 向集合添加对象
                list.add(stu);
            }
        } catch (SQLException e) {
            
            e.printStackTrace();
        }finally{
            //1.5 释放资源
            super.closeAll(rs, pstm, conn);
        }
        //返回集合
        return list;
    }
    /**
     * 2.根据id查询对象
     */
    @Override
    public Student findById(int sid) {
        Student stu=null;
        String sql="select * from student where sid=?";
        Object[] param={sid};
        rs=super.executeQuery(sql, param);
        try {
            if(rs.next()){
                stu=new Student(rs.getInt("cid"), rs.getInt("sid"), rs.getString("sname"), rs.getString("password"), rs.getInt("age"), rs.getString("subject"), rs.getDouble("score"), rs.getString("examtime"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            super.closeAll(rs, pstm, conn);
        }
        return stu;
    }
    /**
     * 添加
     */
    @Override
    public int saveStu(Student stu) {
        String sql="insert into student(sname,password," +
                "age,subject,score,examtime,cid) " +
                "values(?,?,?,?,?,?,?)";
        Object[] param={stu.getSname(),stu.getPassword(),
                stu.getAge(),stu.getSubject(),stu.getScore(),
                stu.getExamtime(),stu.getCid()};
        return super.executeUpdate(sql, param);
    }
    /**
     * 4.修改
     */
    @Override
    public int updateStu(Student stu) {
        String sql="update student set sname=?,password=?,age=?," +
                "subject=?,score=?,examtime=?,cid=? where sid=?";
        Object[] param={stu.getSname(),stu.getPassword(),
                stu.getAge(),stu.getSubject(),stu.getScore(),
                stu.getExamtime(),stu.getCid(),stu.getSid()};
        return super.executeUpdate(sql, param);
    }
    
    /**
     * 5.删除
     */
    @Override
    public int deleteStuById(int sid) {
        String sql="delete from student where sid=?";
        Object[] param={sid};
        return super.executeUpdate(sql, param);
    }

   
    

}
StudentDaoImpl 和上面一起 技术分享
package com.part2;

import java.sql.Date;

/**
 * 1.实体类==封装的是数据库的字段
 * 实体类的属性名一般情况和数据库的字段保持一一对应
 * @author Administrator
 *
 */
public class Student {
    private int cid;//47
    private int sid;
    private String sname;
    private String password;
    private int age;
    private String subject;
    private double score;
    private String examtime;
    
    public Student() {
    }
    
    public Student(int cid, String sname, String password, int age,
             String subject, double score, String examtime) {
        this.cid = cid;
        this.sname = sname;
        this.password = password;
        this.age = age;
        this.subject = subject;
        this.score = score;
        this.examtime = examtime;
    }

    public Student(int cid, int sid, String sname, String password,
            int age,  String subject, double score, String examtime) {
        this.cid = cid;
        this.sid = sid;
        this.sname = sname;
        this.password = password;
        this.age = age;
        this.subject = subject;
        this.score = score;
        this.examtime = examtime;
    }
    public int getCid() {
        return cid;
    }
    public void setCid(int cid) {
        this.cid = cid;
    }
    public int getSid() {
        return sid;
    }
    public void setSid(int sid) {
        this.sid = sid;
    }
    public String getSname() {
        return sname;
    }
    public void setSname(String sname) {
        this.sname = sname;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public int getAge() {
        return
                        
                    

人气教程排行