前面我们学习了MySQL的相关知识,事实上MySQL数据库管理系统就是一个服务器,例如命令行、可视化工具等都是客户端,通过提供的服务器的IP、端口号以及用户名密码等可以与服务器进行交互。
在JAVA中,数据库存取技术可以分为以下几类:
JDBC是Java访问数据库的基石,Mybatis等只是更好的封装了JDBC.。
JDBC(Java Database Connectivity):Java连接数据库的技术。
JDBC通常指的是SUN公司为各大数据库厂商Java程序如何连接和操作DBMS软件制定的统一的标准,即公共接口。这个公共接口由各大数据库厂商提供实现类,这些实现类就构成了数据库驱动。
Java程序员编写Java代码时,只要面向接口编程就可以了,运行时将驱动实现类加到项目中即可。Java程序员只要学习SUN公司提供的JDBC的公共接口就可以了。
JDBC的作用可以下面的图进行深层次的解释。
总结:JDBC是SUN公司提供一套用于数据库操作的接口API,Java程序员只需要面向这套接口编程就行。不同的数据库厂商,需要针对这套接口,提供不同实现类。不同的实现类,就是不同数据库的驱动类。
JDBC API是一系列的接口,它规定和规范了应用程序与数据库的连接、执行SQL语句,并等到返回结果等。声明在java.sql和javax.sql包中。
获取数据库连接的步骤可用下面这些步骤进行实现。
驱动程序由数据库提供商进行提供下载。 MySQL的驱动下载地址:http://dev.mysql.com/downloads/。
如何将Java Project项目应用中添加数据库驱动jar:
(2)将jar包添加到项目的类路径下。
加载并注册驱动:
加载驱动,把驱动类加载到内存中。
注册驱动,把驱动类的对象交给DriverManager管理,用于后面创建连接等使用。
1.Class.forName()
调用Class类的静态方法forName(),向其传递要加载的JDBC驱动的类名。
可以通过DriverManager类建立到数据库的连接Connection:
DriverManager试图从已经注册的JDBC驱动程序集中选择一个适当的驱动程序。
通过DriverManager类建立到数据库的连接Connection的方法 |
---|
public static Connection getConnection(String url) |
public static Connection getConnection(String url,String user, String password),此方法最为常用 |
public static Connection getConnection(String url,Properties info)其中Properties info通常至少应该包括 “user” 和 “password” 属性 |
JDBC URL用来标识一个被注册的驱动程序,驱动程序管理器通过这个URL选择正确的驱动程序,从而建立到数据的连接。
jdbc:<子协议>:<子名称>
协议:JDBC URL 中的协议总是jdbc
子协议:子协议用来标识一个数据库驱动程序
子名称:一个标识数据库的方法。用子名称的目的是为了定位数据库提供足够的信息
例如:
MySQL的连接URL编写方式:
jdbc:mysql://主机名称:mysql服务端口号/数据库名称?参数=值&参数=值
例如:jdbc:mysql://localhost:3306/testdb
数据库连接被用于向数据库服务器发送命令和SQL语句,并接受数据库返回的结果。其实一个数据库的连接就是一个Socket连接。
在java.sql包中3个接口分别定义了对数据库的调用的不同方式:
Statement
通过调用Connection对象的createStatement()方法创建该对象。
该对象用于执行静态的SQL语句,并且返回执行结果。
Statement接口中定义了下列方法用于执行SQL语句:
int excuteUpdate(String sql):执行更新操作insert、update、delete
ResultSet excuteQuery(String sql):执行查询操作select
ResultSet
通过调用Statement对象的excuteQuery()方法创建该对象。
ResultSet对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过ResultSet对象的next()方法移动到下一行。
ResultSet接口的常用方法 |
---|
boolean next():移动到下一行 |
get***(String columnLabel):columnLabel使用SQL AS子句指定的列表签。如果没有指定SQL AS子句,则标签是列名称 |
get***(int index):索引从1开始 |
Connection、Statement、ResultSet都是应用程序和数据库服务器的连接资源,使用后一定要关闭,可以在finally中关闭。
使用JDBC进行增加数据操作的实例代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
/**
* 1.使用JDBC向mysql数据库中添加记录
*
*/
//1.通过反射,加载与注册驱动类
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
String url="jdbc:mysql://localhost:3306/school";
Connection connection = DriverManager.getConnection(url, "root", "root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
String sql="insert books values(7,'SpringBoot学习',230)";
//5.执行sql语句
int len = statement.executeUpdate(sql);//insert,update以及delete都用这个方法
System.out.println(len>0?"添加成功":"添加失败");
//6.关闭资源
statement.close();
connection.close();
}
}
使用JDBC进行修改数据操作的实例代码:
/**
* 2.使用JDBC将mysql数据库中的数据进行修改
*
*
*/
//1.通过反射,加载与注册驱动类
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
String url="jdbc:mysql://localhost:3306/school";
Connection connection = DriverManager.getConnection(url, "root", "root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
String sql="update books set bname='详述SpringMVC' where bid=6 ";
//5.执行sql语句
int len = statement.executeUpdate(sql);//insert,update以及delete都用这个方法
System.out.println(len>0?"修改成功":"修改失败");
//6.关闭资源
statement.close();
connection.close();
使用JDBC进行删除数据操作的实例代码:
/***
* 3.使用JDBC将mysql数据库中的数据进行删除操作
*/
//1.通过反射,加载与注册驱动类
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
String url="jdbc:mysql://localhost:3306/school";
Connection connection = DriverManager.getConnection(url, "root", "root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
String sql="delete from books where bid=2 ";
//5.执行sql语句
int len = statement.executeUpdate(sql);//insert,update以及delete都用这个方法
System.out.println(len>0?"删除成功":"删除失败");
//6.关闭资源
statement.close();
connection.close();;
使用JDBC进行查询数据操作的实例代码:
/***
* 4.使用JDBC将mysql数据库中的数据进行查询操作
*/
//1.通过反射,加载与注册驱动类
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
String url="jdbc:mysql://localhost:3306/school";
Connection connection = DriverManager.getConnection(url, "root", "root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
String sql="select * from books ";
//5.执行sql语句
ResultSet resultSet = statement.executeQuery(sql);//执行sql查询语言,使用executeQuery()
//6.遍历resultSet
while(resultSet.next()){
int bid = resultSet.getInt("bid");
String bname = resultSet.getString("bname");
double price = resultSet.getDouble("price");
System.out.println(bid+"=="+bname+"=="+price);
}
//7.关闭资源
statement.close();
connection.close();
}
}
PreparedStatement接口是Statement的子接口,它表示一条预编译过的SQL语句。
(1)SQL拼接
/**
* 1.Statement:SQL拼接
*
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入书籍的名称:");
String bname = input.next();
System.out.println("请输入书籍的价格:");
double price = input.nextDouble();
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school","root","root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
String sql="insert into books values(2,'" + bname+"'," + price + ")";
//5.执行sql语句b
int len = statement.executeUpdate(sql);
System.out.println(len>0?"添加成功":"添加失败");
//6.关闭资源
statement.close();
connection.close();
(2)SQL注入
SQL注入是利用某些系统没有对用户输入的数据进行充分地检查,而在用户输入数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意行为的做法。对于Java而言,要防范SQL注入,只要用PreparedStatement来代替Statement即可。
/**
* 2.Statement:SQL注入
*/
Scanner input = new Scanner(System.in);
System.out.println("请输入书籍的名称:");
String bname = input.next();
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school","root","root");
//3.创建Statement对象
Statement statement = connection.createStatement();
//4.编写sql语句
//数据库原理 'or '1'='1
String sql="select bid,bname,price from books where bname='"+bname+"'";
//5.执行sql语句b
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
int id = resultSet.getInt(1);
String name = resultSet.getString(2);
double price = resultSet.getDouble(3);
System.out.println(id+"\t"+name+"\t"+price);
}
//6.关闭资源
statement.close();
connection.close();
(3)处理Blob类型数据
BLOB(binary large object),二进制大对象,BLOB是数据库用来存储二进制文件的字段类型。
插入BlOB类型数必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串进行拼接。
通过调用Connection对象的PreparedStatement(String sql)方法获取PreparedStatement对象。
PreparedStatement接口是Statement的子接口,它表示一条预编译过的SQL语句。
PreparedStatement对象所代表的SQL语句中的参数用问号(?)来表示,调用PreparedStatement对象的set()方法来设置这些参数。
ResultSet executeQuery()执行查询,并返回该查询生成的Result对象。
int executeUpdate():执行更新,包含增、删、改。
使用PreparedStatement可以解决SQL语句中的拼接
public static void add() throws ClassNotFoundException, SQLException {
Scanner input = new Scanner(System.in);
System.out.println("请输入书籍的编号:");
int bid = input.nextInt();
System.out.println("请输入书籍的名称:");
String bname = input.next();
System.out.println("请输入书籍的价格:");
double price = input.nextDouble();
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school","root","root");
//3.编写带?的sql语句
String sql="insert into books values(?,?,?)";
//4.准备一个PreparedStatement:预编译sql
PreparedStatement preparedStatement = connection.prepareStatement(sql);
//5.把?用具体的值进行代替
preparedStatement.setObject(1,bid);
preparedStatement.setObject(2,bname);
preparedStatement.setObject(3,price);
//6.执行sql语句
int len = preparedStatement.executeUpdate();
System.out.println(len>0?"添加成功":"添加成功");
//7.释放资源
preparedStatement.close();
connection.close();
}
使用PreparedStatement可以解决SQL注入现象
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//从键盘输入书籍的名称,来查询书籍的信息
Scanner input = new Scanner(System.in);
System.out.println("请输入书籍的名称:");
String bname = input.nextLine();//输入:计算机网络组成原理' or '1'='1
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
//3.编写sql语句
String sql = "select * from books where bname = ?";
//4.创建PreparedStatement
PreparedStatement pst = connection.prepareStatement(sql);
//插入一步,设置?号
pst.setString(1,bname);
//5.执行sql
ResultSet resultSet = pst.executeQuery();
//6.遍历resultSet
while (resultSet.next()) {
for (int i = 1; i <= 3; i++) {
System.out.print(resultSet.getObject(i) + "\t");
}
System.out.println();
}
//7.关闭资源
pst.close();
connection.close();
input.close();
}
使用PreparedStatement可以处理blob等二进制的数据类型
public static void main(String[] args) throws ClassNotFoundException, SQLException, FileNotFoundException {
//往school库的user表中添加一条记录
//1.注册驱动
Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/school", "root", "root");
//3.编写sql语句
String sql="insert into user values(3,?,?,?)";//避免拼接blob
//4.创建PreparedStatement对象
PreparedStatement pst = connection.prepareStatement(sql);
//5.设置?号
pst.setString(1,"chenliu");
pst.setString(2,"12345678");
pst.setBlob(3, new FileInputStream("E:\\xingye.jpg") );
//6.执行sql
int len = pst.executeUpdate();
System.out.println(len>0?"添加成功":"添加失败");
//7.关闭流
pst.close();
connection.close();
}
在本节中获取数据库连接、使用JDBC中Statement与PreparedStatement实现增删改查,这些基本操作需要重点掌握,其次需要注意的是PreparedStatement与Statement性能之间的对比。