linux怎么查看本机内存大小
220
2023-07-03
详解Java基础知识——JDBC
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的使用
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
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 ;
privatTNZrFFtgke 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
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详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,会及时回复大家的。在此也非常感谢大家对我们网站的支持!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~