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包

下载好jar包后,在于src同级的目录下,建立一个lib文件夹,添加jar包,并添加依赖

代码实现

通过一个简单的案例来实现JDBC的使用

import java.sql.*;

public class Demo02 {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

//1注册驱动

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

//2建立连接

String url = "jdbc:mysql://localhost:3306/mydb01";

String usernName = "xxx"; //登录数据库的账号

String password = "xxxx"; //登录数据库的密码

Connection conn = DriverManager.getConnection(url, usernName, password);

//3获取执行sQL语句的对象

Statement statement = conn.createStatement();

//4获取数据库返回的结果

String sql = "delete from emp where empno = " +"7499";

String sqlUpdate = "update emp set sal = "+10000+" where empno = " +"7369";

String sqlInsert = "INSERT INTO emp VALUES(2018,\"boss\",\"king\",NULL,\"2018-8-

8\",15000,10000,10);";

//5处理数据集

int i = statement.executeUpdate(sql);

int s = statement.executeUpdate(sqlUpdate);

int ins = 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读取配置文件

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

import java.sql.*;

import java.util.Properties;

public class IoReadProp {

public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {

//1注册驱动

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

String[] para = read();

//2建立连接

String url = para[0];

String usernName = para[1];

String password = para[2];

Connection conn = DriverManager.getConnection(url,usernName,password);

//3获取执行sQL语句的对象

Statement statement = conn.createStatement();

//4获取数据库返回的结果

String sql = "select * from emp";

ResultSet resultSet = statement.executeQuery(sql);

//5处理数据集

try {

while (resultSet.next()){

//.getXXX方法中的参数 1,字段名 2.字段的下标

int empno = resultSet.getInt("empno");

String ename = resultSet.getString("ename");

String job = resultSet.getString(3);

Date date = resultSet.getDate(5);

System.out.println("empno:"+empno+", ename:"+ename+", job:"+job+", date:"+date);

}

}

catch (Exception e){

e.printStackTrace();

}

finally {

//6关闭连接

resultSet.close();

statement.close();

conn.close();

}

}

public static String [] read()throws IOException {

FileReader fr = new FileReader( "E:\\javalearning\\src\\jdbc\\jdbc.properties" );

//创建 写入 缓冲区

BufferedReader bufferedReader = new BufferedReader( fr );

String [] str = new String[3];

for(int i =0 ;i < 3;i++){

str[i] = bufferedReader.readLine().split("=")[1].replace(";","").trim();

}

bufferedReader.close();

fr.close();

return str;

}

}

Properties读取配置文件

import java.io.*;

import java.sql.*;

import java.util.Iterator;

import java.util.Properties;

public class PropReadProp {

public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {

//1注册驱动

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

//用户数组存放数据库信息

String[] para = new String[3];

//读取配置文件

int i = 0;

Properties prop = new Properties();

FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");

InputStream in = new BufferedInputStream(fileInputStream);

prop.load(in);

Iterator it = prop.stringPropertyNames().iterator();

while (it.hasNext()) {

para[i] = prop.getProperty(it.next());

i++;

}

in.close();

//2建立连接

String url = para[0];

String usernName = para[1];

String password = para[2];

Connection conn = DriverManager.getConnection(url, usernName, password);

//3获取执行sQL语句的对象

Statement statement = conn.createStatement();

//4获取数据库返回的结果

String sql = "select * from emp";

ResultSet resultSet = statement.executeQuery(sql);

//5处理数据集

try {

while (resultSet.next()) {

//.getXXX方法中的参数 1,字段名 2.字段的下标

int empno = resultSet.getInt("empno");

String ename = resultSet.getString("ename");

String job = resultSet.getString(3);

Date date = resultSet.getDate(5);

System.out.println("empno:" + empno + ", ename:" + ename + ", job:" + job + ", date:" + date);

}

} catch (Exception e) {

e.printStackTrace();

} finally {

//6关闭连接

resultSet.close();

statement.close();

conn.close();

}

}

}

分层DAO

Data Access Object数据访问对象是一个面向对象的数据库接口

会建立一个包:dao,里面的类都是用来操作数据库的。

通常情况下,有几张表,就有几个DAO

分层Entity、bean、pojo

实体,也就是一个一个类,该类里面只有属性,和对应set.get方法

往往一个表一个实体,实体的属性和表的字段有没有关系,名字一般一样,类型相对应

使用逆向工程,通过表导出实体。

Utils 工具类

代替我们去操作一系列的连接关闭等操作

案例:

目录结构如下,

EmpDAO代码如下:

package jdbc.dao;

import jdbc.entity.Emp;

import jdbc.utils.JDBCUtils;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class EmpDAO {

/**

* 根据员工id获取员工信息

*/

public Emp getEmpById(Integer id){

Connection connection =null;

Statement statement = null;

ResultSet rs = null;

Emp emp = null;

try {

connection = JDBCUtils.getConnection();

statement = connection.createStatement();

rs = statement.executeQuery("select * from emp where empno='"+id+"'");

while (rs.next()){

emp = new Emp();

int empno = rs.getInt("empno");

emp.setEmpno(empno);

String ename = rs.getString("ename");

emp.setEname(ename);

String job = rs.getString(3);

emp.setJob(job);

String hiredate = rs.getString(5);

emp.setHiredate(hiredate);

}

} catch (SQLException e) {

e.printStackTrace();

}

finally {

JDBCUtils.close(connection,statement,rs);

}

return emp;

}

public Emp getEmpById(String id){

Connection connection =null;

Statement statement = null;

ResultSet rs = null;

Emp emp = null;

try {

connection = JDBCUtils.getConnection();

statement = connection.createStatement();

rs = statement.executeQuery("select * from emp where empno="+id);

while (rs.next()){

emp = new Emp();

int empno = rs.getInt("empno");

emp.setEmpno(empno);

String ename = rs.getString("ename");

emp.setEname(ename);

String job = rs.getString(3);

emp.setJob(job);

String hiredate = rs.getString(5);

emp.setHiredate(hiredate);

}

} catch (SQLException e) {

e.printStackTrace();

}

finally {

JDBCUtils.close(connection,statement,rs);

}

return emp;

}

}

entity中的Emp代码如下

package jdbc.entity;

public class Emp {

//emp表中的相关属性

private Integer empno;

private String ename;

private String job;

private String mgr;

private String hiredate ;

private double sal;

private double comm;

private Integer deptno;

public Integer getEmpno() {

return empno;

}

public void setEmpno(Integer empno) {

this.empno = empno;

}

public String getEname() {

return ename;

}

public void setEname(String ename) {

this.ename = ename;

}

public String getJob() {

return job;

}

public void setJob(String job) {

this.job = job;

}

public String getMgr() {

return mgr;

}

public void setMgr(String mgr) {

this.mgr = mgr;

}

public String getHiredate() {

return hiredate;

}

public void setHiredate(String hiredate) {

this.hiredate = hiredate;

}

public double getSal() {

return sal;

}

public void setSal(double sal) {

this.sal = sal;

}

public double getComm() {

return comm;

}

public void setComm(double comm) {

this.comm = comm;

}

public Integer getDeptno() {

return deptno;

}

public void setDeptno(Integer deptno) {

this.deptno = deptno;

}

//默认输出方法

@Override

public String toString() {

return "Emp{" +

"empno=" + empno +

", ename='" + ename + '\'' +

", job='" + job + '\'' +

", mgr='" + mgr + '\'' +

", hiredate='" + hiredate + '\'' +

", sal=" + sal +

", comm=" + comm +

", deptno=" + deptno +

'}';

}

}

utils中的JDBCUtils代码如下

package jdbc.utils;

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.IOException;

import java.io.InputStream;

import java.sql.*;

import java.util.Iterator;

import java.util.Properties;

public class JDBCUtils {

private static final String URL ;

private static final String USERNAME ;

private static final String PASSWORD ;

static{

String [] parp = null;

try {

parp = PropRead();

} catch (IOException e) {

e.printStackTrace();

}

URL = parp[0];

USERNAME = parp[1];

PASSWORD=parp[2];

try {

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

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

/**

* 创建连接

*/

public static Connection getConnection() throws SQLException {

Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);

return conn;

}

public static void close(Connection co , Statement state, ResultSet rs){

if(rs != null){

try {

rs.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(state !=null){

try {

state.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(co !=null){

try {

co.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

public static void close(Connection co , Statement state){

if(state !=null){

try {

state.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

if(co !=null){

try {

co.close();

} catch (SQLException e) {

e.printStackTrace();

}

}

}

/**

* 读取配置文件

* @return

* @throws IOException

*/

public static String [] PropRead()throws IOException {

String[] para = new String[3];

int i = 0;

Properties prop = new Properties();

FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");

InputStream in = new BufferedInputStream(fileInputStream);

prop.load(in);

Iterator it = prop.stringPropertyNames().iterator();

while (it.hasNext()) {

para[i] = prop.getProperty(it.next());

i++;

}

in.close();

return para;

}

}

测试代码如下:

package jdbc;

import jdbc.dao.EmpDAO;

import jdbc.entity.Emp;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

EmpDAO empDAO = new EmpDAO();

System.out.println("请输入ID");

Scanner scanner = new Scanner( System.in );

String value = scanner.nextLine();

Emp emp = empDAO.getEmpById (value);

Emp emp1 = empDAO.getEmpById (7900);

System.out.println(emp);

System.out.println(emp1);

}

}

这样就简单实现了一个分层的使用JDBC的案例

SQL注入攻击

根据上述案例,我们可以输入一个员工的id来查找该员工

但是有一个问题,你如何去规定用户的输入,下面给大家看一个现象

我的数据库在中并没有123456789这个id的人,那么为什么还会有结果呢?

就是因为我们的sql语句是根据字符串拼接生成的,当你输入的数据中包含sql关键字时,会被当成sql语句去执行

注意:这是很危险的!

不友好的用户可以根据这个漏洞对你的数据库进行修改,甚至删除你的数据库!

解决方法:PreparedStatement类

PreparedStatement是statement的子类

解决原理:

SQL语句不在拼接,而是通过预处理,也就是说,用户输入的任何内容,都只能作为值,不解析特殊字符。

修改之后打代码如下:

public Emp getEmpById2(String id){

Connection connection =null;

PreparedStatement statement = null;

ResultSet rs = null;

Emp emp = null;

try {

connection = JDBCUtils.getConnection();

String sql = "select * from emp where empno=?";

statement = connection.prepareStatement(sql);

statement.setString(1,id);

rs = statement.executeQuery();

while (rs.next()){

emp = new Emp();

int empno = rs.getInt("empno");

emp.setEmpno(empno);

String ename = rs.getString("ename");

emp.setEname(ename);

String job = rs.getString(3);

emp.setJob(job);

String hiredate = rs.getString(5);

emp.setHiredate(hiredate);

}

} catch (SQLException e) {

e.printStackTrace();

}

finally {

JDBCUtils.close(connection,statement,rs);

}

return emp;

}

再次测试:结果如图

总结:并不是意味着Statement不能用,或者不能SQL拼接

但是如果是前端穿过的来的值需要直接放到SQL语句中,就需要注意。

以上所述是小编给大家介绍的Java基础知识——JDBC详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!

java jdbc_详解Java基础知识——JDBC相关推荐

  1. Java方法详解(基础)

    Java方法详解(基础) 什么是方法? System.out.println():调用系统类标准输出对象方法out. 方法是语句的集合,他们在一起执行一个功能. 方法是解决一类问题的步骤的有序组合. ...

  2. java deepcopy_详解JAVA 深层拷贝 DeepCopy的使用方式

    说到复制方法,在开发程序中要怎么复制呢?其实复制Java数组的方法很多,但大多数都是浅层复制,今天爱站技术频道小编带你寻找详解JAVA 深层拷贝 DeepCopy的使用方式. 方法实现很简单,提供两种 ...

  3. 【java】详解Java的类文件(class文件)结构

    1.概述 转载:详解Java的类文件(class文件)结构 大家好,我是二哥呀,今天我拿了一把小刀,准备解剖一下 Java 的 class 文件. CS 的世界里流行着这么一句话,"计算机科 ...

  4. java中文乱码解决之道(二)—–字符编码详解:基础知识 + ASCII + GB**

    原文出处:http://cmsblogs.com/?p=1412 在上篇博文(java中文乱码解决之道(一)-–认识字符集)中,LZ简单介绍了主流的字符编码,对各种编码都是点到为止,以下LZ将详细阐述 ...

  5. Java网络编程详解——网络基础知识介绍、IP和端口介绍、URL和URLConnection介绍

    网络基础知识--计算机网络介绍.通信协议与网络结构模型 一. 计算机网络就是把分布在不同地理区域的计算机与专门的外部设备,用通信线路互连成一个网络系统,从而使众多的计算机可以互相传递信息,共享资源. ...

  6. java object 详解_Java基础之Object类详解

    类Object是类层次结构的根类.每个类都直接或者间接地继承Object类.所有对象(包括数组)都实现这个类的方法.Object类中的构造方法只有一个,并且是无参构造方法,这说明每个类中默认的无参构造 ...

  7. php读音量大小,Android_Android中实时获取音量分贝值详解,基础知识 度量声音强度,大 - phpStudy...

    Android中实时获取音量分贝值详解 基础知识 度量声音强度,大家最熟悉的单位就是分贝(decibel,缩写为dB).这是一个无纲量的相对单位,计算公式如下: 分子是测量值的声压,分母是参考值的声压 ...

  8. java命令详解 java -D

    2019独角兽企业重金招聘Python工程师标准>>> JAVA 命令参数详解: 1.-D<name>=<value> set a system proper ...

  9. java nio详解,Java NIO API详解

    Java NIO API详解 在JDK 1.4以前,Java的IO操作集中在java.io这个包中,是基于流的阻塞(blocking)API.对于大多数应用来说,这样的API使用很方 便,然而,一些对 ...

最新文章

  1. matplotlib画图中文显示问题
  2. c++ -DNDEBUG openMP优化
  3. How to make Windows Form app truly Full Screen (and to hide Taskbar) in C#? 转
  4. @EnableGlobalMethodSecurity(prePostEnabled = true)
  5. 转:Socket在阻塞模式下的信息收发和文件接收
  6. 2017.9.24 虔诚的墓主人 思考记录
  7. 锤子新机或10月31日发布,罗永浩:与我无关
  8. digital ocean 内存不足时增加swap文件的方法
  9. sms 2003 Service Pack 3 Open Beta
  10. 如何实现Windows Network所有会话的限制登录和访问控制
  11. ubuntu16中,google浏览器安装OneNote Web Clipper插件
  12. 计算机搜不到连接打印机主机,电脑搜索不到局域网打印机怎么办
  13. Spring boot 集成 Redis Scarch
  14. 无人机编队飞行技术 pdf_无人机教师李刚:无人机飞行中最重要的六个要点
  15. 什么是Java的灵魂?了解JVM的结构模型,生命周期,Java王朝虚拟机的更替,各家大厂虚拟机百花齐放
  16. 各代iPhone iPad 内部代号 Hardware Model
  17. 优选法中的黄金分割法
  18. SQL SERVER 语句的谓词ANY、ALL的意思
  19. vol.173 乱炖 · 公司基因论靠不靠谱?
  20. 查询mysql 的内存使用_mysql查看内存使用情况

热门文章

  1. php登入模块代码,thinkphp LoginAction.class.php 登录模块
  2. mongo按季度统计_2020年第一季度电网工程设备材料信息价(完整版)
  3. python 干什么工作具有明显优势-为什么这么多人学Python?Python在就业上有什么优势?...
  4. python基础编程语法-Python基础语法学习笔记
  5. python3哪个版本稳定-Python 3.9 发布稳定版本,八大特性学起来!
  6. python零基础学习书-零基础如何学好python?推荐6本入门书籍,帮你打基础
  7. python学来干什么-学python出来到底能干嘛
  8. python3.6安装步骤-Ubuntu16.04安装python3.6详细教程
  9. python能干什么-Python这么火,学完到底能干什么
  10. python读法-python怎么读sql数据?