愿君一阅
操作数据库
编程语言:C 、C++、JAVA、Python等
数据库:MySQL、Oracle、SQL Server等
各种编程语言都能操作数据库
不同的数据库,对应不同的编程语言提供的不同的数据库驱动包(API(一组类或方法)),调用这些API就能操作数据库
JDBC概述
JDBC是Java标准库提供的API,把各种不同的数据库的接口统一起来,这组API可操作任意的数据库
看JBDC如何访问数据库
JDBC使用
找到数据库驱动包,添加到项目中
可在官网、GitHub、中央仓库中寻找第三方库
中央仓库
- 找到驱动包,根据MySQL的版本下载相应的版本(子版本之间差别很小,如5.7版本的MySQL可以下载5.1或5.0任一版本驱动包)
- 下载mysql-connector-java-5.1.49.jar 。文件后缀名是.jar的是jar包,Java程序打包部署的一种常见格式,本质上是把.class文件以压缩包的形式打包在一起,绝大部分第三方库都是通过jar包的形式发布的
- 在项目中创建文件夹lib,将驱动包mysql-connector-java-5.1.49.jar复制到lib文件夹中
- 右击lib目录,点击Add as Library,点击ok
创建数据源
创建数据库源,把数据库的位置信息写入
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)
创建SQL语句
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的区别:
- Statement 用于执行不带参数(没有?占位符)的简单SQL语句(Statement的没有setXXX方法)
- PreparedStatement 用于执行带或不带参数的简单SQL语句,SQL语句会预编译在数据库系统,执行速度快于Statement对象
执行SQL语句(网络通信)
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 staticvoidtestSelect() 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 staticvoidtestUpdate() 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 staticvoidtestDelete() 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 staticvoidtestInsert() 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 staticvoidclose(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();}}}}
版权归原作者 威少总冠军 所有, 如有侵权,请联系我们删除。