ok,看了题目,就可以知道今天要分享的是JDBC
讲这个这之前,想讲讲之前的。
之前我们操作数据库基本都是通过MySQL客户端,进行编写sql语句来操作的。
但是我们在开发中一般都是通过代码来操控数据库的。
而且在我们日常开发中,还一般通过ORM框架来进行操作,比如像是MyBatis、Django ORM……
代码来操作数据库,有着很多优点
提高工作效率、增强数据安全性……
好了,那么接下来讲讲这个JDBC是什么吧
JDBC(Java Database Connectivity)
是Java用于关系型数据库交互的API。(API:Application Programming Interface 应用程序接口)
这个数据库和代码进行打交道,前提是,这个数据库告诉代码怎么打交道,那么就可以提高数据库提高的一套API来进行交互。
注意,这里是以MySQL这个数据库作为例子,所以说的API也是指的是MySQL这里的提供的,
而且不同的数据库,提供着不同API。
那么这样说的话,那么对于程序员来说也是个苦恼的事,毕竟不同的API也要一些学习成本。
那么可以不可以把这个API统一一下呢?
这时候java站出来了,由于它的生态和市场份额较大,所以自己本身写了一套java的API标准,
使得各种数据库自身的API要适应到了java那一套的。
所以这样来说,对于java的学习者来说,这是个好事,省去一定的时间成本了。
那么之前说了,各种数据库自身的API要适应的java那一套,那它不是平白无故就完成的。
所以必须有点东西使其转换过来。
那么MySQL官方这里提供了这个:
mysql-connector
这个东西就可以完成上诉的转换!
诶,问题来了,那么这个东西怎么来呢?
巧就巧在,这个既不是MySQL自带的,也不是java自带。
而是要通过第三方的途径,进行下载。
这里的第三方途径,一般有以下几种:
1.官方网站
2.GitHub
3.maven中央仓库
这里介绍的是在中央仓库去下载。
中央仓库的地址:https://mvnrepository.com/
当然这是外面的网站,访问起来,稍微慢些。
那么怎么下载呢?
进入官网:
点击搜索框,搜索MySQL
这时候出现这样的页面(红色是我标记的):
选哪个都可以,那么我这里选择经典版
点击后,出现这样的页面
这里往下找,找到自己电脑上对应的MySQL版本。
不知道在哪的话
点击win键,搜索服务,
然后进去,再然后,往下找可以找到了。
然后呢,现在选对版本,大版本要选对,小版本个人选择咯
比如我这里的是MySQL5.7,那么我就选5开头的版本去选择下载
这里呢,我选择5.1.49
点击5.1.49后
在页面点击标记的地方
下载完jar包后,还不能使用它
还要将其导入到java创建的项目中
mysql-connector导入java项目
那么怎么导入java项目呢?
比如现在我创建了这个项目
然后呢
接着
然后我这里已经创建好了
然后呢,如何把下载好的jar导入呢?
这里提供简单粗暴的办法,ctrl+c复制jar包
然后点击创建好的lib目录,ctrl+v
然后
点击ok就行。
这时候导入好了,那么这样就可以了吗?
当然不行,这是idea中这个项目还没把这个这个目录中的内容当作“自己人”。
所以还得下一步
点击这个add as library。
然后出现这个页面
其他不用管,一直点击ok就行。
ok,这样子,就算是导入成功了。
接下来是重头戏
编写JDBC代码
这里我在idea中创建了一个test类来进行编写。
创建数据源对象
为什么先要创建数据源对象呢?
那肯定是要有对象你才能够对相关的类进行操作呀。
public class Test2 {
public static void main(String[] args) {
//创建数据源对象
DataSource dataSource=new MysqlDataSource();
}
}
这里的DataSourse 是一个接口来的,需要new实现这个接口的子类
一个jar包里的 MysqlDataSourse就是这个。
设置对象的相关属性
数据库在哪?
数据库用户名
数据库密码
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("9974");
里面的内容,暂且先不说,说说看为什么这样的写,
这是因为先前这样创建数据源:
DataSource dataSource=new MysqlDataSource();
那么这里涉及到向上转型,
为了设置数据库属性,就搞个向下转型?
多此一举?
当然不是的,有这种写法的好处
就是可以使代码的耦合度降低
毕竟之后再次使用Datasourse,是“看不到”这个MysqlDataSourse这个信息了。
当然,还有另外一种写法
MysqlDataSource mysqlDataSource=new MysqlDataSource();
mysqlDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/learn?characterEncoding=utf8&useSSL=false");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("9974");
那么好现在来解释下这里的三个属性内容
url:
url是唯一资源定位符,用来描述资源在网络的位置。
而且这里的数据库也是可以看作一种网络资源。
那么来解释下里面的内容是什么吧
jdbc:mysql:
描述url的用途,是给jdbc的MySQL使用的
127.0.0.1:3306
这里指的是访问数据的ip地址和数据库服务器的端口。
那为什么使用这个ip呢?
因为我们连接的这个数据库在我们的本机上的,所以我们访问的是本机的服务器地址
而且这个IP地址还是个特殊的地址,叫做:回环地址
还也叫做本机地址,
所以我就要使用这个ip,如果数据库是其他IP地址,那么替换上去就行
/learn
这个指定是这个连接数据库的名字
?characterEncoding=utf8&useSSL=false
这个?是分隔开路径和查询参数的,&是分割查询参数之间的
characterEncoding=utf8是说查询指定字符串为utf8
useSSL=false是说禁止SSL加密。因为本来不是什么重要的数据,所以就不用SSL来加密传输了。
SSL是一种在网络通信中提供安全的协议。
连接服务器
刚刚上面内容只是设置属性,还没有连接上数据库来
现在进行连接操作
//连接服务器
Connection connection=dataSource.getConnection();
这里值得注意的是,
Connection要选择包名是java.sql的
以及getConnection()会抛出异常,所以要处理这个异常
构建sql语句以及预编译操作
//构建sql语句
String sql="insert into stu2 values(1,'张三')";
PreparedStatement sqlStatement=connection.prepareStatement(sql);
这里的预编译操作是指的是对构造的sql语句进行语法检查。
为什么呢?
因为数据库服务器是连接着非常多的客户端的,每个客户端发来的sql语句都要进行在数据库服务器中进行语法检查,这对数据库的开销是个挑战,所以干脆放在代码层进行检测,使得数据库服务器压力少一些。
这里值得注意的是,这个prepareStatement()是Connection里的方法。
而且sql语句不需要分号了,但是在MySQL客户端是需要的 。
发送sql语句
//发送sql语句
int n=sqlStatement.executeUpdate();
System.out.println("受影响行数"+n);
这里的发送操作变成PreparedStatement提供的方法了。
提供的方法里我们目前常用的
这个是对更新操作
其更新操作包括:update、insert、delete、create table、drop table……
返回值是代表影响几行!
这个是查询操作的
返回值是一个结果值!
这个只是简单返回是否成功的。
那么写这个操作是更新操作,且我们想要打印出受几行影响。所以使用这个executeUpdate()方法。
public class Test2 {
public static void main(String[] args) throws SQLException {
// 创建数据源对象
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("9974");
//连接服务器
Connection connection=dataSource.getConnection();
//构建sql语句
String sql="insert into stu2 values(1,'张三')";
PreparedStatement sqlStatement=connection.prepareStatement(sql);
//发送sql语句
int n=sqlStatement.executeUpdate();
System.out.println("受影响行数 "+n);
}
}
执行效果
MySQL:
同样的,其他也写操作比如删除、更新、创建……也是跟上面差不多
那么还有个查询
查询如何写呢?
查询的话,就要有点点麻烦
//发送sql语句
ResultSet resultSet=sqlStatement.executeQuery();
while (resultSet.next()){
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
System.out.println(id+" "+name);
}
首先我们查询出来的是一堆数据来的,所以要拿个结果集合整体接收它。
接着要把集合里的东西遍历,打印出来
那么就像是上诉这样,因为有着两列,id和name
那么可以分别接收打印,也可以放到打印语句里直接打印。
结果:
和刚刚给的数据那边查询出来的是一致的。
最后不要忘了要关闭资源,我们的
PreparedStatement、ResultSet、Connection,这几个跟MySQL服务器打交道的,
所以要释放掉资源
那么整段代码如下:
public static void main(String[] args)throws SQLException {
Scanner scanner=new Scanner(System.in);
//创建数据源对象
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("9974");
//连接服务器
Connection connection=dataSource.getConnection();
//构建sql语句
String sql="select * from stu2";
PreparedStatement sqlStatement=connection.prepareStatement(sql);
//发送sql语句
ResultSet resultSet=sqlStatement.executeQuery();
while (resultSet.next()){
int id=resultSet.getInt("id");
String name=resultSet.getString("name");
System.out.println(id+" "+name);
}
resultSet.close();
sqlStatement.close();
connection.close();
}
那么,回到更新那边。
有个小小问题
发现插入操作给写死了,可以不可以让用户输入呢?
当然可以
这是代码
public static void main(String[] args) throws SQLException {
Scanner scanner=new Scanner(System.in);
//创建数据源对象
DataSource dataSource=new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/learn?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("9974");
//连接服务器
Connection connection=dataSource.getConnection();
//构建sql语句
System.out.println("请输入要插入的数据(id,name):");
int id=scanner.nextInt();
String name=scanner.next();
String sql="insert into stu2 values(?,?)";
PreparedStatement sqlStatement=connection.prepareStatement(sql);
sqlStatement.setInt(1,id);
sqlStatement.setString(2,name);
//发送sql语句
int n=sqlStatement.executeUpdate();
System.out.println("受影响行数 "+n);
sqlStatement.close();
connection.close();
scanner.close();
}
我们首先让用户输入插入id 和name
然后重要的来了,我们把之前
String sql="insert into stu2 values(1,'张三')";
里面替换为?
这是占位符的意思,然后呢,替换后,就要把输入id和name,放回到两个?里
sqlStatement.setInt(1,id); sqlStatement.setString(2,name);
就是这样两句的功劳了
1是值第一个?,替换为哪个变量值,注意了int类型就替换为int类型的
同理,2是第二个?同样是什么类型,就要用什么类型来进行替换
就是做出这样的修改就行了,其他的没什么了
运行结果
MySQL
所以这是成功了的意思。
到这里,我的JDBC分享完,即使以后开发不使用这个,但是一些框架也是对其进行封装的,
学习使用JDBC,倒也不是个坏处。
完!