编程语言:C 、C++、JAVA、Python等
数据库:MySQL、Oracle、SQL Server等
各种编程语言都能操作数据库
不同的数据库,对应不同的编程语言提供的不同的数据库驱动包(API(一组类或方法)),调用这些API就能操作数据库
JDBC是Java标准库提供的API,把各种不同的数据库的接口统一起来,这组API可操作任意的数据库
看JBDC如何访问数据库
创建数据库源,把数据库的位置信息写入
IP地址、端口号(可通过workbench查找)、数据库名通过一个URL语句写入
URL语句的格式是固定的 "jdbc:mysql://IP地址:端口号/数据库名"
还要写入用户名、密码等
characterEncoding说明字符编码,useSSL说明是否加密
//1.创建一个 数据源
DataSource dataSource = new MysqlDataSource();
// 1)数据库的ip,端口,数据库名通过一个URL来表示,需要调用setUrl()实现,setUrl()是MysqlDataSource的方法
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
// 2)设置登录数据库的用户名
((MysqlDataSource) dataSource).setUser("root");
//MySQL支持自己创建用户,安装好MySQL数据库,就有一个用户,“root”,即管理员,拥有最高的权限
// 3)设置登录数据库的密码
((MysqlDataSource) dataSource).setPassword("cuige2001");
不使用转型的写法
MysqlDataSource dataSource = new MysqlDataSource();
使用转型写法的好处:
DataSource 是Java标准库提供的API,是通用的,支持各种数据库;MysqlDataSource是数据库JDBC驱动程序提供的API,专门针对MySQL数据库;
转型写法中,数据源dataSource都是DataSource类型,和具体的数据库无关,如果以后切换数据库,只要改动MysqlDataSource,其他代码无需改动!!
Connection connection = dataSource.getConnection();
//连接失败时会抛出异常(受查异常),导致连接失败的原因很多 ip地址、端口号、用户名、密码错误、数据库权限受阻等等
容易抛出异常SQLException,要么用try catch()包裹,要么抛给上层调用者
Connection在标准库中有,在MySQL驱动中也有,此处使用的是标准库中的Connection(java.sql.Connection)
Scanner scanner = new Scanner(System.in);
System.out.println("请输入id:");
int id = scanner.nextInt();
System.out.println("请输入城市:");
String name = scanner.next();
//静态拼接
String sql = "insert into shandong values(1,'济南')";
//动态拼接
String sql = "insert into shandong values("+ id + ",'"+ name + "')";
String sql = "insert into shandong values(?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);
statement.setString(2, name);
动态拼接应该用第三种方法,?表示占位符,如果sql语句中有?,一定要记得后面用setXXX()方法填充
PreparedStatement使用的是标准库中的API
setInt() 或 setString() 对输入的内容有严格的校验,有疑似SQL语句的内容就能识别出来;使用前两种,如果是 sql 中有类似于drop database XXX的信息,数据库执行就完犊子了
Statement和PreparedStatement的区别:
int ret = statement.executeUpdate();
ResultSet resultset = statement.executeQuery();
executeUpdate()表示数据发生变更,包括insert,update,delete等,返回的值是影响的行数
executeQuery()表示查询,返回的是一个结果集(相当于一个临时表)
while(resultset.next()){
int id = resultset.getInt("id");
String name = resultset.getString("name");
System.out.println("id: " + id + ", name: " + name);
}
关闭结果集,命令,连接
先开后闭,关闭的顺序与申请的顺序相反
客户端和服务器之间都会分配一部分资源来维系这个连接(记录对端的ip,port),每维持一个连接,都会消耗一部分硬件资源
resultSet.close();
statement.close();
connection.close();
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public static void testSelect() throws SQLException {
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("cuige2001");
Connection connection = dataSource.getConnection();
String sql = "select * from shandong";
PreparedStatement statement = connection.prepareStatement(sql);
//resultset就相当于一张临时表,在有些语言/库中ResultSet也叫光标(cursor) 如Python中
ResultSet resultset = statement.executeQuery();
while(resultset.next()){
int id = resultset.getInt("id");
String name = resultset.getString("name");
System.out.println("id: " + id + ", name: " + name);
}
resultset.close();
statement.close();
connection.close();
}
public static void testUpdate() throws SQLException {
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("cuige2001");
Connection connection = dataSource.getConnection();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入修改的名称");
String name = scanner.next();
System.out.println("请输入id");
int id = scanner.nextInt();
String sql = "Update shandong set name = ? where id = ?";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(2,id);
statement.setString(1,name);
int ret = statement.executeUpdate();
System.out.println(ret);
statement.close();
connection.close();
}
public static void testDelete() throws SQLException {
//1.创建数据源,把数据库的位置信息设置进去
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("cuige2001");
//2.与数据库建立连接
Connection connection = dataSource.getConnection();
//3.构造SQL语句
Scanner scanner = new Scanner(System.in);
System.out.println("请输入需要删除城市的id");
int id = scanner.nextInt();
String sql = "delete from shandong where id = ?";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1,id);
//4.执行SQL语句
int ret = statement.executeUpdate();
System.out.println(ret);
//5.回收资源
statement.close();
connection.close();
}
public static void testInsert() throws SQLException {
//1.创建一个 数据源
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
((MysqlDataSource) dataSource).setUser("root");
((MysqlDataSource) dataSource).setPassword("cuige2001");
//2.连接数据库,进行网络通信
Connection connection = dataSource.getConnection();
Scanner scanner = new Scanner(System.in);
System.out.println("请输入id:");
int id = scanner.nextInt();
System.out.println("请输入城市:");
String name = scanner.next();
//3.创建SQL语句,插入数据
String sql = "insert into shandong values(?,?)";
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);
statement.setString(2, name);
//4.执行SQL语句,进行网络通信
int ret = statement.executeUpdate();
System.out.println(ret);
//5.关闭连接,回收一部分资源
statement.close();
connection.close();
}
实际操作中可以通过封装实现与数据库的网络通信
import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
private static String url = "jdbc:mysql://127.0.0.1:3306/bookmanage?characterEncoding=utf8&useSSL=false";
private static String user = "root";
private static String password = "cuige2001";
//一个程序中只要有一个连接即可,有一个DataSource实例即可!
//保证 某个类在程序中只有 “唯一的实例”(可以有多种不同的实例,每种实例只有一个啊),叫做"单例模式",也是一种设计模式
private static DataSource dataSource = new MysqlDataSource();
//静态代码块,"类加载"的时候执行
static{
((MysqlDataSource)dataSource).setUrl(url);
((MysqlDataSource)dataSource).setUser(user);
((MysqlDataSource)dataSource).setPassword(password);
}
//建立连接
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
public static void close(Connection connection, Statement statement, ResultSet resultSet) {
// TODO 用一层 try catch() 包裹是不行的 !!! 如果 resultSet发生异常的话,statement和connection的资源不会回收哦
// try{
// if(resultSet != null){
// resultSet.close();
// }
// if(statement != null){
// statement.close();
// }
// if(connection != null){
// connection.close();
// }
// }catch(SQLException e){
// e.printStackTrace();
// }
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}