JDBC(Java DataBase Connectivity)

JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。

JDBC为开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够使用java API编写数据库应用程序,并且可跨平台运行,并且不受数据库供应商的限制。

JDBC为我们提供了java连接数据库的驱动。而这个驱动也是由Java开发出来的,我们只需要将这个驱动放进项目中,通过这个驱动,我们就可以用Java连接数据库,进行数据库的管理操作。

了解:JDBC与ODBC的区别

二者皆可以实现对数据库的操作(连接、增删改查、建库建表)。

JDBC是SUN开发的java连接数据库的标准

ODBC是微软开发的,C语言的

JDBC规范(掌握四个核心对象):

DriverManager: 用于注册驱动
Connection: 表示与数据库创建的连接
Statement: 操作数据库sql语句的对象
ResultSet: 结果集或一张虚拟表

数据操作步骤

注册驱动(只做一次)

建立数据库连接

创建执行SQL的语句(Statement)

执行SQL语句

注:如果是查询,需要处理执行的结果(如:接收查询数据)

释放资源(千万不要漏了)

JDBC常用的类和接口详解

1、java.sql.DriverManager类:创建连接

a、注册驱动

DriverManager.registerDriver(new com.mysql.jdbc.Driver());  //不建议使用

原因有2个:

导致驱动被注册2次
强烈依赖数据库的驱动jar

解决办法:

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

b、与数据库建立连接

static Connection getConnection(String url, String user, String password) 
//试图建立到给定数据库 URL 的连接。

getConnection("jdbc:mysql://localhost:3306/jdbc01", "root", "root");

URL:SUN公司与数据库厂商之间的一种协议。

jdbc:mysql://localhost:3306/db01
协议 子协议       IP : 端口号 数据库

mysql: jdbc:mysql://localhost:3306/db01 或者 jdbc:mysql:///db01(默认本机连接)
oracle: jdbc:oracle:thin:@localhost:1521:sid
getConnection(String url, Properties info) 
getConnection(String url) 

DriverManager.getConnection("jdbc:mysql://localhost:3306/db01?user=root&password=root");

2、java.sql.Connection接口:一个连接(桥)

接口的实现在数据库驱动中。所有与数据库交互都是基于连接对象的。

Statement  createStatement(); //创建操作sql语句的对象

3、java.sql.Statement接口:操作sql语句,并返回相应结果的对象(小货车)

接口的实现在数据库驱动中。用于执行静态 SQL 语句并返回它所生成结果的对象。

ResultSet executeQuery(String sql) //根据查询语句返回结果集。只能执行select语句。

int executeUpdate(String sql) //根据执行的DML(insert update delete)语句,返回受影响的行数。

boolean execute(String sql)  //此方法可以执行任意sql语句。返回boolean值,表示是否返回ResultSet结果集。
                             //仅当执行select语句,且有返回结果时返回true, 其它语句都返回false;

4、java.sql.ResultSet接口:结果集(客户端用来存表数据的对象)

a、封装结果集的。
提供一个游标,默认游标指向结果集第一行之前。
调用一次next(),游标向下移动一行。
提供一些get方法。

封装数据的方法

Object getObject(int columnIndex); 根据序号取值,索引从1开始
Object getObject(String ColomnName); 根据列名取值。

将结果集中的数据封装到JavaBean中

Java的数据类型与数据库中的类型的关系

Java数据类型数据库数据类型
bytetityint
shortsmallint
intint
longbigint
floatfloat
doubledouble
Stringchar/varchar
Datedate
boolean next()  //将光标从当前位置向下移动一行

// 有两种方式获取字段值,1.通过下标;2.通过字段名
int getInt(int colIndex)    //以 int 形式获取ResultSet结果集当前行指定列号值
int getInt(String colLabel) 
float getFloat(int colIndex)    //以 float 形式获取ResultSet结果集当前行指定列号值
float getFloat(String colLabel) 
String getString(int colIndex)  //以 String 形式获取ResultSet结果集当前行指定列号值
String getString(String colLabel)
Date getDate(int columnIndex)
Date getDate(String columnName)
void close()    //关闭 ResultSet 对象

b、可移动游标的方法

boolean next()  //将光标从当前位置向前移一行。 
boolean previous() 
                //将光标移动到此 ResultSet 对象的上一行。 
boolean absolute(int row)   //参数是当前行的索引,从1开始
                //根据行的索引定位移动的指定索引行。
void afterLast()    //将光标移动到末尾,正好位于最后一行之后。 
void beforeFirst() 
                //将光标移动到开头,正好位于第一行之前。 

5、释放资源
资源有限,要正确关闭。


开发一个JDBC程序的准备工作:

> JDBC规范在哪里:
    JDK中:
        java.sql.*;
        javax.sql.*;
> 数据库厂商提供的驱动:jar文件
        *.jar(例如mysql-connector-java-5.0.8.jar

1、创建java工程

项目名的命名规范:项目名全部小写。创建一个java工程。

2、导入jar包

使用JDBC操作数据库,需要导入JDBC的驱动包:mysql-connector-java-5.0.8.jar。

在项目下面创建一个文件夹:lib,将驱动包复制到lib下面,并将jar包加载到项目中,如下图所示:

l 新建lib文件夹:

l 将jar包复制到lib文件夹下面:

l 选中jar包,单击右键,在弹出的窗口中选择“Add to Build Path” ,将jar包加载到项目中

工程目录如下:
这里写图片描述


JDBC的增删查改示例

数据库:
这里写图片描述

代码:

//dbinfo.properties
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql:///db01
username=root
password=root
//User.java
public class User {
    private int id;
    private String name;
    private String password;
    private String email;
    private Date birthday;
    //此处省略一堆的各个属性的get方法和set方法
}
//这里自定义一个DBUtils工具类
public class DBUtils {
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;

    static{
        //此对象是用于加载properties文件数据的
        ResourceBundle rb = ResourceBundle.getBundle("dbinfo");
        driverClass = rb.getString("driverClass");
        url = rb.getString("url");
        username = rb.getString("username");
        password = rb.getString("password");
        try {
            Class.forName(driverClass);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //得到连接的方法
    public static Connection getConnection() throws Exception{
        return DriverManager.getConnection(url, username, password);
    }

    //关闭资源的方法
    public static void closeAll(ResultSet rs,Statement stmt,Connection conn){
        //关闭资源
        if(rs!=null){
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}
//TestCRUD.java
public class TestCRUD {
    @Test
    public void testSelect(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            conn = DBUtils.getConnection();
            stmt = conn.createStatement();
            rs = stmt.executeQuery("select * from users");
            List<User> list = new ArrayList<User>();
            while(rs.next()){
                User u = new User();
                u.setId(rs.getInt(1));//或 u.setId(rs.getInt("id"));
                u.setName(rs.getString(2));//或 u.setName(rs.getString("name"));
                u.setPassword(rs.getString(3));
                u.setEmail(rs.getString(4));
                u.setBirthday(rs.getDate(5));
                list.add(u);
            }
            for (User user : list) {
                System.out.println(user);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            DBUtils.closeAll(rs, stmt, conn);
        }
    }

    @Test
    public void testInsert(){
        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = DBUtils.getConnection();
            stmt = conn.prepareStatement("INSERT INTO users VALUES(?,?,?,?,?)");
            stmt.setInt(1, 5);
            stmt.setString(2, "tom");
            stmt.setString(3, "333");
            stmt.setString(4, "tom@163.com");
            //stmt.setDate(5, new java.sql.Date(System.currentTimeMillis()));
            stmt.setString(5, "2015-09-11");

            int i = stmt.executeUpdate();
            if(i>0){
                System.out.println("success");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            DBUtils.closeAll(null, stmt, conn);
        }
    }

    @Test
    public void testUpdate(){
        Connection conn = null;
        PreparedStatement stmt = null;

        try {
            conn = DBUtils.getConnection();
            stmt = conn.prepareStatement("UPDATE users SET NAME=?,PASSWORD=?,email=? WHERE id=?");
            stmt.setString(1, "jerry123");
            stmt.setString(2, "123");
            stmt.setString(3, "jerry@163.com");
            stmt.setInt(4, 5);

            int i = stmt.executeUpdate();
            if(i>0){
                System.out.println("success");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            DBUtils.closeAll(null, stmt, conn);
        }
    }

    @Test
    public void testDelete(){
        Connection conn = null;
        Statement stmt = null;

        try {
            conn = DBUtils.getConnection();
            stmt = conn.createStatement();
            int i = stmt.executeUpdate("DELETE FROM users WHERE id=4");
            if(i>0){
                System.out.println("success");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            DBUtils.closeAll(null, stmt, conn);
        }
    }
}

Statement与PreparedStatement

StatementPreparedStatement两者都可以把SQL语句从Java程序发送到指定数据库,并执行SQL语句,但是他们也具有如下区别:

Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出;

PreparedStatement会形成预编译的过程,对于多次重复执行的语句,PreparedStatement的效率要高一些,而且适合批处理数据(批量添加);

最重要的是,PreparedStatement能有效防止危险自负的注入,即SQL注入问题。

根据比较结果可知,我们需要选用PreparedStatement更好、更快速、更安全。因此,在以后的JDBC操作中,建议使用PreparedStatement。

Statement接口提供了两种常用的执行SQL语句的方法:executeQuery、executeUpdate。

  • executeUpdate:一般用于添加、删除、修改数据;
  • executeQuery:一般用于查询数据。

PreparedStatement接口继承自Statement。PreparedStatement在sql语句中通过使用占位符?来代替常量字段值,setXXX方法来填充字段值,取代掉占位符,形成完整的可执行的sql语句。

conn = DBUtils.getConnection();
stmt = conn.prepareStatement("INSERT INTO users VALUES(?,?)");
stmt.setInt(1, 5);
stmt.setString(2, "tom");
stmt.executeUpdate();

批量处理数据

一次性执行多条SQL语句(比如:一次下单购买多个商品)。

执行批量添加数据时,务必要将提交方式设置为手动提交。

con.setAutoCommit(false);//将提交方式设置为手动提交

在获取到连接后,获取PreparedStatement对象之前,需要将提交方式设置为手动提交。

在循环中,可以使用ps.addBatch()将给定的 SQL命令添加到此Statement对象的当前命令列表中。

循环结束后,使用ps.executeBatch(),可以将一批SQL命令提交给数据库,但是该方法之后必须要使用con.commit(),该命令是命令数据库新更改的数据成为持久化的数据。

@Test
    public void  testAddBatch(){
        Connection con = BaseDao.getConn();
        //批量添加数据
        PreparedStatement ps = null;
        try {
            con.setAutoCommit(false);//将提交方式设置为手动提交
            String sql = "insert into test(id,name,password) values(?,?,?)";
            ps = con.prepareStatement(sql);
            long start = System.currentTimeMillis();//获取当前系统时间的毫秒数
            for (inti = 0; i < 3000;i++) {
                ps.setInt(1, (i+1));
                ps.setString(2, "用户"+i);
                ps.setString(3, MD5Util.GetMD5Code("密码"+i));
                ps.addBatch();//将给定的SQL命令添加到此Statement对象的当前命令列表中。
            }
            System.out.println("数据循环耗时:"+(System.currentTimeMillis()-start)+"ms");
            start = System.currentTimeMillis();//获取当前系统时间的毫秒数
            //将一批命令提交给数据库来执行,如果全部命令执行成功,则返回更新计数组成的数组
            ps.executeBatch();
            con.commit();//提交
            System.out.println("数据执行SQL耗时:"+(System.currentTimeMillis()-start)+"ms");
        } catch (Exceptione) {
            e.printStackTrace();
        }finally {
            BaseDao.close(con, ps, null);
        }
    }
采用批量处理数据的优点:
    减少访问数据库的次数,大大提高了批量SQL执行的效率。

动态SQL中LIKE的使用

在使用动态SQL为like赋值的时候,like直接使用?即可。PreparedStatement对象为占位符赋值的时候,我们需要把百分号%拼接进去即可。

案例:

String sql = "select * from user where username like ?";

ps.setString(1,"%"+参数值+"%");

参考自《JDBC》

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值