数据库及MYSQL基础(3)-JDBC
教学视频链接:https://edu.aliyun.com/course/1694?spm=5176.11400004.0.0.29254768sg2H5P
程序文件链接:https://pan.baidu.com/s/1PyJEgHl8y8BaP-VPcJpb8g 提取码:oe97
JDBC入门
1,什么是JDBC
Java DataBase Connectivity就是Java数据库连接,使用Java语言来操作数据库。原来我们操作数据库是控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。
①导jar包:驱动;
②加载驱动类:class.forName("类名");
③给出url,username,password,其中url背下来;
④使用DriverManager类来得到Connection对象。
import java.sql.Connection; |
2,JDBC原理
早期SUN公司想编写一套可以连接所有数据库的API,但是当他们刚刚开始的时候就发现这是个不可能完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并且提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的-遵循JDBC规范的-可以访问自己数据库的API被称之为驱动。
Class.forName("com.mysql.jdbc.Driver");//驱动类加载【注册驱动】 |
com.mysql.jdbc.Driver driver=new com.mysql.jdbc.Driver(); |
加载类的时候会执行静态代码块,所有的java.sql.Driver实现类,都提供了static块,块内的代码就是把自己注册到DriverManager中。
在jdbc4.0之后,每个驱动jar包中,在META-INF/services目录下提供有名为java.sql.Driver的文件,文件内容就是该接口的实现类名称!
static { |
3,JDBC完成增删改查
①数据库连接准备
package cn.itcast.demo1; |
②数据库DML操作
String sql="INSERT INTO emp VALUES(NULL,'王武',23,'男')"; |
String sql="UPDATE emp"; |
String sql="UPDATE emp SET ename='红红的夏天',age=18,gender='女' WHERE eid=4";//修改 |
String sql="DELETE FROM emp";//删除 int r=stmt.executeUpdate(sql); |
③数据库DDL查询操作
public ResultSet executeQuery(String sql) throws SQLException { |
4,JDBC代码规范化
package cn.itcast.demo1; //实例化Connection |
Connection->Statement->ResultSet->
DriverManager
其实今后我们只需要会用DriverManager的getConnection()方法即可:
①Class.forName(driverClassName);//注册驱动
②String url="jdbc:mysql://localhost:3306/mydb1?serverTimezone=GMT%2B8&useSSL=false";
③String username="root";
④String password="";
⑤Connection conn=DriverManager.getConnection(url,username,password);
上面的代码可能出现的两种异常:
①ClassNotFoundException——这个异常在第一句出现,可能为
·没有导入mysql的jar包;
·把类名称打错,查看的类名不是com.mysql.jdbc.Driver
②SQLException——异常出现在第五句,出现这个异常的就是三个参数的问题
对于DriverManager.registerDriver()方法了解即可,因为今后注册驱动只会使用Class.forName()而不是用前一个方法。
Connection
Connection最为重要的方法就是获取Statement:
·Statement stmt=conn.createStatement();
后面在学习ResultSet()方法时,还需要学习一下下面的方法【方法重载】:
·Statement stmt=conn.createStatement(int,int);//两个参数决定能够生成什么样的结果集
Statement
·int executeUpdate(String sql)执行更新操作,即执行INSERT、UPDATE、DELETE语句,其实这个方法也可以执行CREATE TABLE、ALTER TABLE,以及DROP TABLE等语句,但我们很少会使用JDBC来执行这些语句。
·ResulSet executeQuery(String sql)执行查询操作,返回ResultSet结果集数据。
·boolean execute()执行增、删、改、查所有SQL语句,返回一个布尔类型,表示SQL语句是否有结果。如果execute()执行的是更新语句,那么还要强调用int getUpdateCount()来获取增删改影响的行数;如果执行的是查询语句,需要调用ResultSet getResultSet()来获取查询结果。
5,结果集光标与元数据
executeQuery()光标的位置:
①相对位移,下一行,不可滚动forward_only(只能rs.next());②绝对位移,第几行。
void beforeFirst():把光标放在第一行的前面 void afterLast():把光标放在最后一行的后面 boolean first():把光标放在第一行,返回值表示光标调控是否成功 boolean last() boolean isBeforeFirst():当前光标是否在第一行的前面 boolean isAfterLast() boolean isFirst() boolean isLast() boolean previous():把光标往前挪动一行 boolean next() boolean relative(int row):相对位移,当row为正数的时候,表示向下移动row行,为负数时表示向上移动row行 boolean absolute(int row):绝对位移,把光标移动到指定的行上 int getRow():返回当前光标所在行 |
获取结果集元数
rs.getMetaData()获取元数据,返回值为ResultSetMetaData; int getColumnCount()获取结果数据集 String getColumnName(String colIndex)获取指定列的列名 |
6,结果集的三大特性【滚动、敏感、可更新】
当使用Connection的createStatement时,已经确定了Statement生成的结果集是什么类型。
conn.createStatement();返回值->【不滚动-只有next()相对方法、不敏感、不可更新】
conn.createStatement(int,int);//方法重载 第一个参数: ResultSet.TYPE_FORWARD_ONLY:不滚动 ResultSet.TYPE_SCROLL_INSENSITIVE:滚动结果集,但结果集数据不会跟随数据库变化而变化 ResultSet.TYPE_SCROLL_SENSITIVE:滚动结果集,结果随着数据库变化而变化【实时性!理想!】 第二个参数: CONCUR_READ_ONLY:结果集是只读的,不能通过修改结果集而反向影响数据库 CONCUR_UPDATE:结果集是读写的,可以通过修改结果集而反向影响数据库 |
注意:mysql数据库默认全是可滚动的,没有FORWARD_ONLY的
ResultSet方法:
getInt()、getString()、getDouble()、getBoolean()、getObject()
7,PreparedStatement的用法
PreparedStatement是Statement的子接口,优点:①防SQL攻击;②提高代码的可读性与可维护性;③提高效率。
·范例:一个简单的SQL攻击程序
package cn.itcast.demo4; * 查询出结果返回true否则返回false |
import cn.itcast.demo4.Demo4; |
SELECT * FROM emp WHERE ename='红红的夏天'and age=18//→正常SQL SELECT * FROM emp WHERE ename='a' or 'a'='a'and age=18 or 'a'='a' |
学习使用PreparedStatement的用法:
①给出SQL模板;
②调用Connection中的preparedStatement(String sql模板);
③调用pstmt的setXxx()系列方法为sql模板中的?赋值;
④调用pstmt的executeUpdate()或executeQury()但是它的方法都没有参数。
public static boolean login2(String username,String age) throws ClassNotFoundException, SQLException { //①给出SQL模板 //②调用prepareStatement //调用查询方法向数据库发送SQL语句,返回ResultSet数据 |
8,预处理的原理
服务器的工作:
①校验sql语句的语法【耗时】;
②编译,与函数类似的东西;
③执行,调用函数;
PreparedStatement:
①前提,数据库必须支持预处理【现在几乎没有不支持的】;
②每个pstmt都与一个sql语句绑定在一起,先把sql模板给数据库,数据库先进行校验、再进行编译、执行时只是把参数传递过去;
③二次执行时,无需再次校验语法,直接执行。【类似懒汉-单例-模式】
9,mysql的预编译功能
MySQL执行预编译分为三步【预处理MySQL4.0之后默认关闭】:
①执行预编译语句,例如:prepare myfun from'SELECT * FROM emp WHERE eid=?'
②设置变量,例如:set @str='b1'
③执行语句,例如:execute myfun using @str
如果二次执行myfun,那么就不再需要第一步【预编译语句】
使用Statement执行预编译就是把上面的SQL语句执行一次。
Connection conn=JdbcUtils.getConnection(); Statement stmt=conn.createStatement(); stmt.executeUpdate("prepare myfun from'SELECT * FROM emp WHERE eid=?'"); stmt.executeUpdate("set @str='b1'"); ResulSet rs=stmt.executeQuery("execute myfun using @str"); while(rs.next()){ System.out.println(rs.getString(1)); } stmt.executeUpdate("set @str='b2'");//二次运行 ResulSet rs=stmt.executeQuery("execute myfun using @str"); while(rs.next()){ System.out.println(rs.getString(1)); } rs.close(); stmt.close(0; conn.close(); |
MySQL默认使用PreparedStatement是不能执行预处理编译的,这需要在url中给出useServerPrepStmts=true参数;当使用不同的PreparedStatement对象来执行相同的SQL语句时,还是会出现编译两次的现象,这是因为驱动没有缓存编译后的函数key,导致二次编译,如果希望缓存编译后函数的key,那么就要设置cachePrepStmts参数为true;打开批处理功能,rewriteBatchedStatements=true
例如:
①jdbc:mysql://localhost:3306/mydb1?useServerPrepStmts=true
②jdbc:mysql://localhost:3306/mydb1?useServerPrepStmts=true&cachePrepStmts=true
③jdbc:mysql://localhost:3306/mydb1?useServerPrepStmts=true&cachePrepStmts=true&rewriteBatchedStatements=true
url中的关键字及其值的作用
10,JdbcUtils1.0小工具
JdbcUtils-V1.0【单次初始化配置文件、数据库】
package cn.itcast.demo1; |
11,面向接口编程
修改项目:
①把UserDao修改为接口,然后把原来的UserDao修改类名为UserDaoImpl
②修改UserService中对UserDao的实例化:private UserDao userDao=DaoFactory.getUserDao()
③创建DaoFactory,提供getUserDao()方法
④使用配置文件来获取实体类的名称
DAO【Data Access Object】模式
DAO模式就是写一个类,把访问数据库的代码封装起来。DAO在数据库与业务【Service】逻辑之间。
·实体域,即操作的对象,例如我们操作的表示user表,那么就需要先写一个User类;
·DAO模式需要先提供一个DAO接口;
·然后提供一个DAO接口的实现类;
·再编写一个DAO工厂,Service通过工厂来获取DAO实现。
12,修改day14的登录案例
开闭原则:允许加,不允许改->需要重新测试
package cn.itcast.demo1; |
13,Util包下的Date与sql包下的时间类型转换
java.sql的东西不能出现在Dao以外的地方,否则就干扰了Service或者Server类
数据库类型与java中类型的对应关系:
DATE->java.sql.Date
TIME->java.sql.Time
TIMESTAMP->java.sql.Timestamp
领域对象【domain】中的所有属性不能出现java.sql包下的东西!即不能使用java.sql.Date
·ResultSet#getDate()返回的是java.sql.Date()
·PreparedStatement#setDate(int,Date),其中第二个参数也是java.sql.Date类型
时间类似的转换:【sql是util的子类】
·java.util.Date->java.sql.Date、Time、Timestamp
①先把util的Date转换成毫秒值;
②使用毫秒值创建sql的Date、Time、Timestamp
java.util.Date date=new java.util.Date(); long l=date.getTime(); java.sql.Date sqlDate=new java.sql.Date(l); |
·java.sql.Date、Time、Timestamp->java.util.Date
java.util.Date date=java.sql.Date() |
14,大数据
目标:把MP3保存到数据库之中!
USE mydb1; CREATE TABLE tab_bin( id INT PRIMARY KEY AUTO_INCREMENT, filename VARCHAR(100), DATA MEDIUMBLOB ); |
import java.io.IOException; |
import org.apache.commons.io.IOUtils; |
import java.io.IOException; |
15,批处理
批处理就是一批一批的处理,而不是一个一个的处理。
import java.sql.Connection; |
driverClassName=com.mysql.jdbc.Driver |
数据库及MYSQL基础(3)-JDBC的更多相关文章
- 数据库及MYSQL基础(2)
数据库及MySQL基础(1) SQL进阶及查询练习 1,单表的查询练习 SELECT * FROM emp WHERE deptno=30; SELECT ename,empno,deptno FRO ...
- 数据库02 /MySQL基础数据类型、完整性约束、sql_mode模式
2.MySQL基础数据类型.完整性约束.sql_mode模式 目录 2.MySQL基础数据类型.完整性约束.sql_mode模式 1. MySQL常用数据类型 MySQL常用数据类型预览 1. 1 数 ...
- MySQL基础和JDBC
第一章 命令行工具 mysqladmin:MySQL服务器管理工具 mysql:MySQL客服端链接工具 mysqldump 演示链接到服务器host=127.0.0.1,用户名为root,密码为空 ...
- python day10 数据库(mysql基础)
一.数据库的概念 数据:事物的特征 数据库的本质是:通过套接字进行通信,来读存数据的一种软件,由于每次开发人员写程序都得写数据的套接字,所以诞生了数据库这个软件,减少重复劳动.(sql语句通用) 数据 ...
- 关系型数据库之MySQL基础总结_part1
一:数据库的操作语言的种类 MySQL 是我们最常使用的关系型数据库,对于MySQL的操作的语言种类又可以分为:DDL,DML,DCL,DQL DDL:是数据库的定义语言:主要对于数据库信息的一些定义 ...
- 数据库及MySQL基础(1)
1.数据库概述 关系型数据库:面对关系,Java面向对象. ·常见数据库 Oracle(神喻):甲骨文 DB2:IBM SQL Server:微软 Sybase:赛尔斯 MySQL:甲骨文,最早是开源 ...
- Java基础93 JDBC连接MySQL数据库
本文知识点(目录): 1.什么是jdbc 2.jdbc接口的核心API 3.使用JDBC技术连接MySQL数据库的方法 4.使用Statement执行sql语句(DDL.DML. ...
- Java数据库基础(JDBC)
JDBC(Java Data Base Connectivity):SUN公司为了简化统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC: 这样应用程序就不需要关注数据库底层的详细 ...
- 创建本地数据库mySQL并连接JDBC
转自: http://blog.csdn.net/wei_chong_chong/article/details/44830491 如何创建本地数据库MySQL并连接JDBC 转载 2015年04月0 ...
随机推荐
- qt 添加程序插件目录
QApplication::addLibraryPath(QApplication::applicationDirPath()); QApplication::addLibraryPath(QAppl ...
- OpenJudge计算概论-骑车与走路
/*============================================================ 骑车与走路 总时间限制: 1000ms 内存限制: 65536kB 描述 ...
- IO操作之BIO、NIO、AIO
一.BIO Blocking IO: 同步阻塞的编程方式. BIO编程方式通常是在JDK1.4版本之前常用的编程方式.编程实现过程为:首先在服务端启动一个ServerSocket来监听网络请求,客户端 ...
- angular组件数据
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'app-news', templateUrl: ' ...
- python2,socket多进程的错误pickle.PicklingError: Can't pickle
python2,socket多进程的错误pickle.PicklingError: Can't pickle 源码: #coding:utf-8 import socket import pickle ...
- VS2015 osgEarth 编译
E:\OpenSourceGraph\CURL_install\includeE:\GDAL\includeE:\Geos\geos_3_5_install\includeE:\OpenSourceG ...
- myeclipse打开jsp后卡死的问题详解
myeclipse打开jsp后卡死的问题详解 1,打开 Window -> Preferences -> General -> Editors -> File Associ ...
- WinSCP 上传文件至Cetos 7 后用户无权限
WinSCP是一个支持SSH的SCP文件传输软件. 可以用Windows环境向Linux环境传输文件,今天给新的Elasticsearch 服务器(cetos 7 )部署新的集群节点的时候,发现传输后 ...
- 定时杀死warn进程
6 6 * * * /root/wz/mysqlRestart.sh #MySQL restart7 6 * * * /bin/sh /home/warn/kill_.sh8 6 * * * / ...
- Linux下开发常用配置
JDK /etc/profile export JAVA_HOME=/usr/local/jdk1.8.0_181export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.ja ...