MySQL数据库JDBC编程详解流程

目录
  • 一、数据库编程的必备条件
  • 二、java的数据库编程:jdbc
  • 三、jdbc工作原理
  • 四、jdbc开发步骤
  • 五、jdbc操作步骤
  • 六、优化jdbc的部分代码
    • 1.获取数据库连接对象
    • 2.操作命令对象statement
    • 3.resultset对象
    • 4.总结

一、数据库编程的必备条件

编程语言: 如java、c++、c、python等

数据库: 如oracle、mysql、sql server等

数据库驱动包: 不同的数据库,要使用编程语言来操作时,就需要使用该数据库厂商提供的数据库驱动包。

如:mysql提供了java的驱动包mysql-connector-java,需要基于java操作mysql即需要该驱动包。同样的,要基于java操作oracle数据库则需要oracle的数据库驱动包ojdbc。

二、java的数据库编程:jdbc

jdbc,即java database connectivity,java数据库连接,是一种用于执行sql语句的java api,它是java中的数据库连接规范。 这个api由java.sql. *, javax.sql. * 包中的一些类和接口组成,它为java开发人员操作数据库提供了一个标准的api,可以为多种关系数据库提供统一访问。

三、jdbc工作原理

jdbc为多种关系数据库提供了统一访问方式。作为特定厂商数据库访问api的一种高级抽象,它主要包含一些通用的接口类。

jdbc访问数据库层次结构:

我们使用一套jdbc编码,在切换数据库之后,java操作数据库的代码可以不动(几乎),数据库驱动包要调整,sql因为有标准sql的部分,还有数据库相关的关键字,如mysql中的limit等,这些也需要调整。

jdbc优势:

java语言访问数据库操作完全面向抽象接口编程

开发数据库应用不用限定在特定的数据库厂商的api

为java操作不同的数据库提供一种统一的规范,程序在不同数据库的可移植性大大增强

四、jdbc开发步骤

1.创建一个普通的java项目

2.下载mysql的驱动包

下载驱动包网址

我用的是5.1.xx版本的,说明:不同版本的数据库驱动包,里边的类/接口可能不同

3.项目中添加数据库驱动包(依赖)

验证:写java代码,可以使用mysql驱动包中的类/接口,才表示引入的依赖没有问题。

4.测试:连接数据库

注意:

1.一开始我们写入forname时会飘红,这里先不用管,直接抛出异常。 alt+enter出现以下的界面,点击第一个:

2.获取数据库连接:connection接口,需要使用jdbc中的,不要使用mysql中的

3.mysql数据连接的url参数格式如下:

jdbc:mysql://服务器地址:端口/数据库名?参数名=参数值

//加载jdbc驱动程序:反射的方式,这样调用初始化com.mysql.jdbc.driver类,//即将该类加载到jvm方法区,并执行该类的静态方法块,静态属性//数据库驱动包就可以在这种操作下,执行对应的初始化工作(驱动)class.forname("com.mysql.jdbc.driver");//获取数据库连接:connection接口,需要使用jdbc中的,不要使用mysql中的connection conn = drivermanager.getconnection("jdbc:mysql://localhost:3306/kang?" +                "user=root&password=010124&useunicode=true&characterencoding=utf-8&usessl=false");

五、jdbc操作步骤

1.获取数据库连接对象

connection(jdbc中的接口)

2.使用数据库连接对象来创建一个操作命令对象statement,该对象是进行sql操作的抽象出来的对象

//通过连接对象创建操作命令对象statement(使用jdbc中的),该对象是用于操作sql的一个抽象的对象
statement s=conn.createstatement();

3.调用操作命令对象的方法来执行sql 查询:executequery 更新操作(插入、修改、删除):executeupdate,返回值int,表示执行成功了几条

//更新操作:调用executeupdate方法,插入,修改,删除都是
int n=s.executeupdate("update exam_result set math=60 where id=1");
system.out.println("修改成功的数量:"+n);

4.如果是查询操作,需要处理结果集对象 查询,返回resultset结果集对象,这个结果集对象类似于数据结构中list<map<string,object>>

//查询:
//(1)调用statement操作命令对象的executequery(sql)
//(2)返回一个resultset结果集对象(查询sql执行的结果集)
resultset r=s.executequery("select id,name,chinese,math,english from exam_result where id>3");
//处理结果:结果集可能是多行数据,需要遍历来获取
//调用next就移动到下一行,返回true代表改行有数据,返回false代表该行没有数据
while(r.next()){//一直遍历到最后
    //进入循环,代表操作遍历的一行数据
    int id=r.getint("id");
    string name=r.getstring("name");
    int chinese=r.getint("chinese");
    int math=r.getint("math");
    int english=r.getint("english");
    system.out.printf("id=%s,name=%s,chinese=%s,math=%s,english=%s\n"
    ,id,name,chinese,math,english);
        }

运行结果:

注解:

5.释放资源 无论jdbc操作成功,还是出现异常,都需要释放资源,要考虑出现异常对象还没有完成初始化,还是null的情况,需要反向释放资源。

public class jdbc {
    public static void main(string[] args) throws classnotfoundexception, sqlexception {
        connection conn =null;
        statement s=null;
        resultset r=null;
        try{
            //之前写过的所有程序放到try里边
        }finally{//无论如何,都要释放资源
            //释放资源:
            //(1)无论什么情况(异常)
            //(2)释放的顺序,和创建的顺序要相反
            //(结果集对象,操作命令对象,数据库连接对象)
            if(r!=null){
                r.close();
            }
            if(s!=null){
                s.close();
            }
            if(conn!=null){
                conn.close();
            }
        }
    }
}

六、优化jdbc的部分代码

1.获取数据库连接对象

connection接口实现类由数据库提供,获取connection对象通常有两种方式:

1.一种是通过drivermanager(驱动管理类)的静态方法获取 也就是上面我们提到的方法。

2.一种是通过datasourse(数据源/数据库连接池)对象获取。实际应用中会使用datasourse对象。

//先创建数据库连接池,再通过连接池获取数据库连接对象
datasource ds=new mysqldatasource();
//创建数据库连接池:初始化时,就会创建一定数量的数据库连接,这些连接对象可以重复使用,效率更高
//整个url带参数可以只使用seturl方法,也可以用参数调用方法的方式来设置
((mysqldatasource)ds).seturl("jdbc:mysql://localhost:3306/kang");
((mysqldatasource)ds).setuser("root");
((mysqldatasource)ds).setpassword("010124");
((mysqldatasource)ds).setuseunicode(true);
((mysqldatasource)ds).setcharacterencoding("utf-8");
((mysqldatasource)ds).setusessl(false);
conn = ds.getconnection();
system.out.println(conn);

两者区别:

1.drivermanager类来获取的connection连接,是无法重复利用的,每次使用完以后释放资源时,通过connection.close()都是关闭物理连接

2.datasourse提供连接池的支持。连接池在初始化时将创建一定数量的数据库连接,这些链接是可以复用的,每次使用完数据库连接,释放资源调用connection.close()都是将connection连接对象回收。效率更高。

2.操作命令对象statement

statement对象主要是将sql语句发送到数据库中,jdbc api中主要提供了三种statement对象。

statement: 用于执行不带参数的简单sql语句(简单的操作命令对象)

preparedstatement:(预编译的操作命令对象)

用于执行带或者不带参数的sql语句

sql语句会预编译在数据库系统

执行速度快于statement对象

callablestatement: 用于执行数据库存储过程的调用(存储过程的操作命令对象) 存储过程:就是写一段sql代码,里边可以写变量,循环,条件判断等等。

查询操作:

s = conn.createstatement();
//查询:模拟在页面上,输入学生姓名来搜索学生
//(1)调用statement操作命令对象的executequery(sql)
//(2)返回一个resultset结果集对象(查询sql执行的结果集)
string queryname="孙权";//能正常查询的输入
//(1)调用statement操作命令对象的executequery(sql)
//(2)返回一个resultset结果集对象(查询sql执行的结果集)
string sql="select id,name,chinese,math,english from exam_result where name='"+queryname+"'";
system.out.println(sql);
r = s.executequery(sql);
while (r.next()) {//一直遍历到最后
    //进入循环,代表操作遍历的一行数据
    int id = r.getint("id");
    string name = r.getstring("name");
    int chinese = r.getint("chinese");
    int math = r.getint("math");
    int english = r.getint("english");
    system.out.printf("id=%s,name=%s,chinese=%s,math=%s,english=%s\n", id, name, chinese, math, english);
    }

输出结果:

但是这里有一个现象: 如果我们把这里的queryname改为“skdj’ or ‘1’=’1”,在拼接sql字符串时,就可能出现安全问题。 输出结果为:

后面的‘1’=‘1’是一个恒为真的条件,所以就会造成整个or条件结果为真,输出所有成员。 要解决以上安全问题,需要调整以上操作命令对象那个为preparedstatement,并且使用占位符。

//要解决以上安全问题,需要调整以上操作命令对象那个为preparedstatement
string queryname="skeij' or '1'='1";
int queryid=6;
//准备一个带?占位符的sql
string sql="select id,name,chinese,math,english from exam_result where name=? or id=?";
ps=conn.preparestatement(sql);//创建预编译的操作命令对象
//替换占位符:调用setxxx方法,第一个参数,表示第几个占位符(从1开始),第二个参数,表示要替换的值
ps.setstring(1,queryname);//替换的值是什么类型,就调用setxxx方法
ps.setint(2,queryid);

//执行sql,需要使用无参的方法
r=ps.executequery();

输出结果为:

插入操作:

int queryid=7;
string queryname="图图";
int chinese=60;
int math=98;
int english=79;
string sql="insert into exam_result values(?,?,?,?,?)";
ps=conn.preparestatement(sql);
ps.setint(1,queryid);
ps.setstring(2,queryname);
ps.setint(3,chinese);
ps.setint(4,math);
ps.setint(5,english);

//executeupdate()方法返回值是一个整数,指示受影响的行数,通常用于update,insert,delete语句。
int ret=ps.executeupdate();
system.out.println(ret);

其余的删除,更新操作都与上面类似,这里不再过多演示。

3.resultset对象

resultset对象它被成为结果集,他代表符合sql语句条件的所有行,并且它通过一套getxxx方法提供了对这些行中数据的访问。 resultset里的数据一行一行排列,每行有多个字段,并且有一个记录指针,指针所指的数据叫做当前数据行,我们只能来操作当前的数据行。如果想要取得某一条记录,就要使用resultset的next()方法,如果我们想要得到resultset里的所有记录,就应该使用while循环。

//处理结果:结果集可能是多行数据,需要遍历来获取
//调用next就移动到下一行,返回true代表改行有数据,返回false代表该行没有数据
while (r.next()) {//一直遍历到最后
    //进入循环,代表操作遍历的一行数据
    int id = r.getint("id");
    string name = r.getstring("name");
    int chinese = r.getint("chinese");
    int math = r.getint("math");
    int english = r.getint("english");
    system.out.printf("id=%s,name=%s,chinese=%s,math=%s,english=%s\n", id, name, chinese, math, english);
    }

4.总结

主要掌握两种执行sql的方法:

1.executequery()方法执行后返回单个结果集的,通常用于select语句。

2.executeupdate()方法返回值是一个整数,指示受影响的行数,通常用于update、insert、delete语句。

preparedstatement注意事项:

1.参数化sql查询

2.占位符不能使用多值

3.占位符:?下标从1开始

4.阻止常见sql注入攻击

5.sql预编译

6.性能比statement高

到此这篇关于mysql数据库jdbc编程详解流程的文章就介绍到这了,更多相关mysql jdbc内容请搜索www.887551.com以前的文章或继续浏览下面的相关文章希望大家以后多多支持www.887551.com!

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐