Java中JDBC怎么用
导读:本文共8375.5字符,通常情况下阅读需要28分钟。同时您也可以点击右侧朗读,来听本文内容。按键盘←(左) →(右) 方向键可以翻页。
摘要: JDBCJava DataBase Connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装。JDBC提供了很多接口,然后不同数据库厂商去实现这个接口,到底底层如何去实现,不同的数据库不一样,不同的数据库厂商需要提供接口实现类(驱动类、驱动程序 Driver、驱动)我们连接不同的数... ...
目录
(为您整理了一些要点),点击可以直达。JDBC
Java DataBase Connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装。
JDBC提供了很多接口,然后不同数据库厂商去实现这个接口,到底底层如何去实现,不同的数据库不一样,不同的数据库厂商需要提供接口实现类(驱动类、驱动程序 Driver、驱动)
我们连接不同的数据库,我们只需要使用不同的驱动即可。
J:Java:提供访问数据库的规范(接口),
DBC:接口的实现,厂商去实现这个接口。
JDBC是一种用于执行SQL语句的java api.
版本号
1.1.1 Major. Minor. Build
Major:项目由架构、大规模的变化
Minor:有新功能的时候
Build:编译版本
JDBC开发
Java程序使用第三方提供工具框架,都需要导入jar包
可以通过以下网址搜索找到mysql的相关jar包
https://mvnrepository.com/
下载好jar包后,在于src同级的目录下,建立一个lib文件夹,添加jar包,并添加依赖
代码实现
通过一个简单的案例来实现JDBC的使用
importjava.sql.*;publicclassDemo02{publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException{//1注册驱动Class.forName("com.mysql.jdbc.Driver");//2建立连接Stringurl="jdbc:mysql://localhost:3306/mydb01";StringusernName="xxx";//登录数据库的账号Stringpassword="xxxx";//登录数据库的密码Connectionconn=DriverManager.getConnection(url,usernName,password);//3获取执行sQL语句的对象Statementstatement=conn.createStatement();//4获取数据库返回的结果Stringsql="deletefromempwhereempno="+"7499";StringsqlUpdate="updateempsetsal="+10000+"whereempno="+"7369";StringsqlInsert="INSERTINTOempVALUES(2018,\"boss\",\"king\",NULL,\"2018-8-8\",15000,10000,10);";//5处理数据集inti=statement.executeUpdate(sql);ints=statement.executeUpdate(sqlUpdate);intins=statement.executeUpdate(sqlInsert);System.out.println(i+"行受到影响----删除");System.out.println(s+"行受到影响----更新");System.out.println(ins+"行受到影响----插入");//6关闭连接statement.close();conn.close();}}
使用JDBC的顺序
(1)注册数据库驱动
(2)和数据库建立连接
(3)获取执行SQL语句的对象
(4)获取数据库返回的结果
(5)处理数据集(逻辑代码)
(6)释放资源,关闭连接
常用类
Connection
通过配置文件可以创建一个connect对象
Statement
通过connect对象获取操作数据库的Statement对象,
通过它来实现对数据库增删改查操作。
executeQuery():查,返回数据集
executeUpdate():增删改,返回int的数据,影响的行数
ResultSet
数据集,可以理解就是一个集合。
取出数据:
通过下标:从1开始
通过字段名:SQL语句中select后面跟的字段,有可能和数据库一样,也可能不一样
JDBC的优化
平时开发和项目上线之后使用的数据库是不一样的,不是同一个
这也就是我们说的,开发环境不一样
开发环境不一样,使用的数据库也就不一样,那么上面的数据库中配置的三要素就要进行修改
而这种修改是人工操作的,人工操作就有存在了失误,而修改之后的.java文件,也要重新编译,这也可能出现错误
假设项目上线,需要以下四个步骤:
测试环境-->修改配置 -->重新编译-->生产环境
如果想要避免上述出现的失误的情况,就要绕开中间的两个步骤
解决的方法就是,配置文件,添加配置文件,将要修改的配置信息存放到配置文件中,每次读取信息从配置文件中读取
而配置文件的位置是固定的,也不会重新编译,这样就可以降低风险
java中用IO流也可以读取配置文件,通过一个专有的类Properties也可以读写配置文件
IO读取配置文件
importjava.io.BufferedReader;importjava.io.FileReader;importjava.io.IOException;importjava.sql.*;importjava.util.Properties;publicclassIoReadProp{publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException,IOException{//1注册驱动Class.forName("com.mysql.jdbc.Driver");String[]para=read();//2建立连接Stringurl=para[0];StringusernName=para[1];Stringpassword=para[2];Connectionconn=DriverManager.getConnection(url,usernName,password);//3获取执行sQL语句的对象Statementstatement=conn.createStatement();//4获取数据库返回的结果Stringsql="select*fromemp";ResultSetresultSet=statement.executeQuery(sql);//5处理数据集try{while(resultSet.next()){//.getXXX方法中的参数1,字段名2.字段的下标intempno=resultSet.getInt("empno");Stringename=resultSet.getString("ename");Stringjob=resultSet.getString(3);Datedate=resultSet.getDate(5);System.out.println("empno:"+empno+",ename:"+ename+",job:"+job+",date:"+date);}}catch(Exceptione){e.printStackTrace();}finally{//6关闭连接resultSet.close();statement.close();conn.close();}}publicstaticString[]read()throwsIOException{FileReaderfr=newFileReader("E:\\javalearning\\src\\jdbc\\jdbc.properties");//创建写入缓冲区BufferedReaderbufferedReader=newBufferedReader(fr);String[]str=newString[3];for(inti=0;i<3;i++){str[i]=bufferedReader.readLine().split("=")[1].replace(";","").trim();}bufferedReader.close();fr.close();returnstr;}}
Properties读取配置文件
importjava.io.*;importjava.sql.*;importjava.util.Iterator;importjava.util.Properties;publicclassPropReadProp{publicstaticvoidmain(String[]args)throwsClassNotFoundException,SQLException,IOException{//1注册驱动Class.forName("com.mysql.jdbc.Driver");//用户数组存放数据库信息String[]para=newString[3];//读取配置文件inti=0;Propertiesprop=newProperties();FileInputStreamfileInputStream=newFileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");InputStreamin=newBufferedInputStream(fileInputStream);prop.load(in);Iterator<String>it=prop.stringPropertyNames().iterator();while(it.hasNext()){para[i]=prop.getProperty(it.next());i++;}in.close();//2建立连接Stringurl=para[0];StringusernName=para[1];Stringpassword=para[2];Connectionconn=DriverManager.getConnection(url,usernName,password);//3获取执行sQL语句的对象Statementstatement=conn.createStatement();//4获取数据库返回的结果Stringsql="select*fromemp";ResultSetresultSet=statement.executeQuery(sql);//5处理数据集try{while(resultSet.next()){//.getXXX方法中的参数1,字段名2.字段的下标intempno=resultSet.getInt("empno");Stringename=resultSet.getString("ename");Stringjob=resultSet.getString(3);Datedate=resultSet.getDate(5);System.out.println("empno:"+empno+",ename:"+ename+",job:"+job+",date:"+date);}}catch(Exceptione){e.printStackTrace();}finally{//6关闭连接resultSet.close();statement.close();conn.close();}}}
分层DAO
Data Access Object数据访问对象是一个面向对象的数据库接口
会建立一个包:dao,里面的类都是用来操作数据库的。
通常情况下,有几张表,就有几个DAO
分层Entity、bean、pojo
实体,也就是一个一个类,该类里面只有属性,和对应set.get方法
往往一个表一个实体,实体的属性和表的字段有没有关系,名字一般一样,类型相对应
使用逆向工程,通过表导出实体。
Utils 工具类
代替我们去操作一系列的连接关闭等操作
案例:
目录结构如下,
EmpDAO代码如下:
packagejdbc.dao;importjdbc.entity.Emp;importjdbc.utils.JDBCUtils;importjava.sql.Connection;importjava.sql.ResultSet;importjava.sql.SQLException;importjava.sql.Statement;publicclassEmpDAO{/***根据员工id获取员工信息*/publicEmpgetEmpById(Integerid){Connectionconnection=null;Statementstatement=null;ResultSetrs=null;Empemp=null;try{connection=JDBCUtils.getConnection();statement=connection.createStatement();rs=statement.executeQuery("select*fromempwhereempno='"+id+"'");while(rs.next()){emp=newEmp();intempno=rs.getInt("empno");emp.setEmpno(empno);Stringename=rs.getString("ename");emp.setEname(ename);Stringjob=rs.getString(3);emp.setJob(job);Stringhiredate=rs.getString(5);emp.setHiredate(hiredate);}}catch(SQLExceptione){e.printStackTrace();}finally{JDBCUtils.close(connection,statement,rs);}returnemp;}publicEmpgetEmpById(Stringid){Connectionconnection=null;Statementstatement=null;ResultSetrs=null;Empemp=null;try{connection=JDBCUtils.getConnection();statement=connection.createStatement();rs=statement.executeQuery("select*fromempwhereempno="+id);while(rs.next()){emp=newEmp();intempno=rs.getInt("empno");emp.setEmpno(empno);Stringename=rs.getString("ename");emp.setEname(ename);Stringjob=rs.getString(3);emp.setJob(job);Stringhiredate=rs.getString(5);emp.setHiredate(hiredate);}}catch(SQLExceptione){e.printStackTrace();}finally{JDBCUtils.close(connection,statement,rs);}returnemp;}}
entity中的Emp代码如下
packagejdbc.entity;publicclassEmp{//emp表中的相关属性privateIntegerempno;privateStringename;privateStringjob;privateStringmgr;privateStringhiredate;privatedoublesal;privatedoublecomm;privateIntegerdeptno;publicIntegergetEmpno(){returnempno;}publicvoidsetEmpno(Integerempno){this.empno=empno;}publicStringgetEname(){returnename;}publicvoidsetEname(Stringename){this.ename=ename;}publicStringgetJob(){returnjob;}publicvoidsetJob(Stringjob){this.job=job;}publicStringgetMgr(){returnmgr;}publicvoidsetMgr(Stringmgr){this.mgr=mgr;}publicStringgetHiredate(){returnhiredate;}publicvoidsetHiredate(Stringhiredate){this.hiredate=hiredate;}publicdoublegetSal(){returnsal;}publicvoidsetSal(doublesal){this.sal=sal;}publicdoublegetComm(){returncomm;}publicvoidsetComm(doublecomm){this.comm=comm;}publicIntegergetDeptno(){returndeptno;}publicvoidsetDeptno(Integerdeptno){this.deptno=deptno;}//默认输出方法@OverridepublicStringtoString(){return"Emp{"+"empno="+empno+",ename='"+ename+'\''+",job='"+job+'\''+",mgr='"+mgr+'\''+",hiredate='"+hiredate+'\''+",sal="+sal+",comm="+comm+",deptno="+deptno+'}';}}
utils中的JDBCUtils代码如下
packagejdbc.utils;importjava.io.BufferedInputStream;importjava.io.FileInputStream;importjava.io.IOException;importjava.io.InputStream;importjava.sql.*;importjava.util.Iterator;importjava.util.Properties;publicclassJDBCUtils{privatestaticfinalStringURL;privatestaticfinalStringUSERNAME;privatestaticfinalStringPASSWORD;static{String[]parp=null;try{parp=PropRead();}catch(IOExceptione){e.printStackTrace();}URL=parp[0];USERNAME=parp[1];PASSWORD=parp[2];try{Class.forName("com.mysql.jdbc.Driver");}catch(ClassNotFoundExceptione){e.printStackTrace();}}/***创建连接*/publicstaticConnectiongetConnection()throwsSQLException{Connectionconn=DriverManager.getConnection(URL,USERNAME,PASSWORD);returnconn;}publicstaticvoidclose(Connectionco,Statementstate,ResultSetrs){if(rs!=null){try{rs.close();}catch(SQLExceptione){e.printStackTrace();}}if(state!=null){try{state.close();}catch(SQLExceptione){e.printStackTrace();}}if(co!=null){try{co.close();}catch(SQLExceptione){e.printStackTrace();}}}publicstaticvoidclose(Connectionco,Statementstate){if(state!=null){try{state.close();}catch(SQLExceptione){e.printStackTrace();}}if(co!=null){try{co.close();}catch(SQLExceptione){e.printStackTrace();}}}/***读取配置文件*@return*@throwsIOException*/publicstaticString[]PropRead()throwsIOException{String[]para=newString[3];inti=0;Propertiesprop=newProperties();FileInputStreamfileInputStream=newFileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");InputStreamin=newBufferedInputStream(fileInputStream);prop.load(in);Iterator<String>it=prop.stringPropertyNames().iterator();while(it.hasNext()){para[i]=prop.getProperty(it.next());i++;}in.close();returnpara;}}
测试代码如下:
packagejdbc;importjdbc.dao.EmpDAO;importjdbc.entity.Emp;importjava.util.Scanner;publicclassMain{publicstaticvoidmain(String[]args){EmpDAOempDAO=newEmpDAO();System.out.println("请输入ID");Scannerscanner=newScanner(System.in);Stringvalue=scanner.nextLine();Empemp=empDAO.getEmpById(value);Empemp1=empDAO.getEmpById(7900);System.out.println(emp);System.out.println(emp1);}}
这样就简单实现了一个分层的使用JDBC的案例
SQL注入攻击
根据上述案例,我们可以输入一个员工的id来查找该员工
但是有一个问题,你如何去规定用户的输入,下面给大家看一个现象
我的数据库在中并没有123456789这个id的人,那么为什么还会有结果呢?
就是因为我们的sql语句是根据字符串拼接生成的,当你输入的数据中包含sql关键字时,会被当成sql语句去执行
注意:这是很危险的!
不友好的用户可以根据这个漏洞对你的数据库进行修改,甚至删除你的数据库!
解决方法:PreparedStatement类
PreparedStatement是statement的子类
解决原理:
SQL语句不在拼接,而是通过预处理,也就是说,用户输入的任何内容,都只能作为值,不解析特殊字符。
修改之后打代码如下:
publicEmpgetEmpById2(Stringid){Connectionconnection=null;PreparedStatementstatement=null;ResultSetrs=null;Empemp=null;try{connection=JDBCUtils.getConnection();Stringsql="select*fromempwhereempno=?";statement=connection.prepareStatement(sql);statement.setString(1,id);rs=statement.executeQuery();while(rs.next()){emp=newEmp();intempno=rs.getInt("empno");emp.setEmpno(empno);Stringename=rs.getString("ename");emp.setEname(ename);Stringjob=rs.getString(3);emp.setJob(job);Stringhiredate=rs.getString(5);emp.setHiredate(hiredate);}}catch(SQLExceptione){e.printStackTrace();}finally{JDBCUtils.close(connection,statement,rs);}returnemp;}
再次测试:结果如图
</div> <div class="zixun-tj-product adv-bottom"></div> </div> </div> <div class="prve-next-news">
Java中JDBC怎么用的详细内容,希望对您有所帮助,信息来源于网络。