JavaWeb-15 (JDBC编程)
JavaWeb-15:JDBC编程
JDBC编程
一、JDBC简介
数据库驱动:SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。
JDBC全称为:Java Data Base Connectivity(java数据库连接),它主要由接口组成。
组成JDBC的2个包:
java.sql
javax.sql
开发JDBC应用需要以上2个包的支持外,还需要导入相应JDBC的数据库实现(即数据库驱动)。
二、第一个JDBC程序
演示JDBC的项目:
1、把数据库的驱动加入到classpath中
2、开发步骤:
开发步骤:(必须记住的)
(1、注册驱动
(2、获取与数据库的链接
(3、得到代表发送和执行SQL语句的对象 Statement
(4、执行语句
(5、如果执行的是查询语句,就会有结果集,处理
(6、释放占用的资源
3、具体代码
Test01.java
package com.itheima.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
/**
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(30),
email varchar(100),
birthday date
);
* @author wangli
*
*/
public class Test01 {
public static void main(String[] args) {
try {
//1.注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
//2.建立连接
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/day14", "root", "yw2633275");
//3.获取用于发送和执行SQL语句的对象 Statement
Statement st = con.createStatement();
//4.执行语句CRUD
//4.1添加记录
st.executeUpdate("insert into user(username,password,email,birthday) values(‘cgx‘,‘123‘,‘[email protected]‘,‘1980-10-1‘)");
//4.2更新
//st.executeUpdate("update user set username=‘aj‘ where id=1");
//4.3删除
//st.executeUpdate("delete from user where id=1");
ResultSet rs = st.executeQuery("select * from user");
//5.如果是查询,要处理结果集
while(rs.next()){
System.out.println(rs.getObject(1)+"\t"+rs.getObject(2)+"\t"+rs.getObject(3)+"\t"+rs.getObject(4)+"\t"+rs.getObject(5));
}
//6.关闭资源
rs.close();
st.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.1、程序详解:DriverManager
作用:a、注册驱动b、获取与数据库的链接
Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:
DriverManager.registerDriver(new Driver())
DriverManager.getConnection(url, user, password),
注意:在实际开发中并不推荐采用registerDriver方法注册驱动。原因有二:
a、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。
b、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。
改进注册驱动:(不能依赖具体的数据库驱动)
推荐方式:Class.forName(“com.mysql.jdbc.Driver”);
采用此种方式不会导致驱动对象在内存中重复出现,并且采用此种方式,程序仅仅只需要一个字符串,不需要依赖具体的驱动,使程序的灵活性更高。
同样,在开发中也不建议采用具体的驱动类型指向getConnection方法返回的connection对象。
获取与数据库的链接的三种方式:
方式一:(推荐)
DriverManager.getConnection("jdbc:mysql://localhost:3306/day17", "root", "sorry");
jdbc:mysql://localhost:3306/day17 :SUN和数据库厂商定义的协议,具体的参考数据库的文档。
jdbc:mysql:///day17 (链接本机的默认端口3306)= jdbc:mysql://localhost:3306/day17
方式二:
方式三:
3.2、程序详解:数据库URL
URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:jdbc:mysql:[]//localhost:3306/test ?参数名=参数值
3.3、程序详解—Connection
createStatement():创建向数据库发送sql的statement对象。
prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象。
3.4、程序详解—Statement
Jdbc程序中的Statement对象用于向数据库发送SQL语句, Statement对象常用方法:
executeQuery(String?sql) :用于向数据发送查询语句。
executeUpdate(String?sql):用于向数据库发送insert、update或delete语句
execute(String sql):用于向数据库发送任意sql语句
3.5、程序详解—ResultSet
Jdbc程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
ResultSet既然用于封装执行结果的,所以该对象提供的都是用于获取数据的get方法:
获取任意类型的数据
getObject(int index)
getObject(string columnName)
获取指定类型的数据,(封装数据时方便)例如:
getString(int index)
getString(String columnName)
常用数据类型转换表
ResultSet还提供了对结果集进行滚动的方法:
next():移动到下一行
Previous():移动到前一行
absolute(int row):移动到指定行
beforeFirst():移动resultSet的最前面。
afterLast() :移动到resultSet的最后面。
3.6、程序详解—释放资源
Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。
特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
3.7、使用JDBC对数据库进行CRUD
Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。
Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。
三、改善后的JDBC编程。
text02.java
package com.itheima.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.itheima.domain.User;
/**
create table user(
id int primary key auto_increment,
username varchar(20),
password varchar(30),
email varchar(100),
birthday date
);
* @author wangli
*
*/
public class Test02 {
public static void main(String[] args) {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
//1.注册驱动 缺点:1.导致二次注册驱动 2.严重依赖mysql jar文件
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
//2.建立连接
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15", "root", "yw2633275");
/*Properties props = new Properties();
props.put("user", "root");
props.put("password", "root");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15",props);*/
//Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/day15?user=root&password=root");
//3.获取用于发送和执行SQL语句的对象 Statement
st = con.createStatement();
//4.执行语句CRUD
//4.1添加记录 executeUpdate()专用于CUD操作
int i = st.executeUpdate("insert into user(username,password,email,birthday) values(‘cgx‘,‘123‘,‘[email protected]‘,‘1980-10-1‘)");
System.out.println(i);
//4.2更新
//st.executeUpdate("update user set username=‘aj‘ where id=1");
//4.3删除
//st.executeUpdate("delete from user where id=1");
//executeQuery()专注于查询操作
//ResultSet rs = st.executeQuery("select * from user");
//execute()执行所有SQL语句都 可以
/*boolean flag = st.execute("select * from user");
ResultSet rs =null;
if(flag){
rs = st.getResultSet();
//5.如果是查询,要处理结果集
while(rs.next()){
System.out.println(rs.getObject(1)+"\t"+rs.getObject(2)+"\t"+rs.getObject(3)+"\t"+rs.getObject(4)+"\t"+rs.getObject(5));
}
}*/
List<User> list = new ArrayList<User>();
rs = st.executeQuery("select * from user");
while(rs.next()){
//封装结果集到集合中
list.add(new User(rs.getInt("id"),rs.getString("username"),rs.getString("password")
,rs.getString("email"),rs.getDate("birthday")));
}
for(User user :list){
System.out.println(user);
}
System.out.println(list);
//boolean flag = st.execute("delete from user where id=4");
//System.out.println(flag);
} catch (Exception e) {
e.printStackTrace();
}finally{
//6.关闭资源
/* try {
if(rs!=null){
try {
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
rs = null;
if(st!=null){
try {
st.close();
} catch (Exception e) {
e.printStackTrace();
}
st = null;
if(con!=null){
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
con=null;
}
}
}
} catch (SQLException e) {
e.printStackTrace();
}*/
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
con = null;
}
}
}
}
四、标准JDBC模板
text03.java
package com.itheima.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Test03 {
public static void main(String[] args) {
Connection con =null;
Statement st = null;
ResultSet rs = null;
try {
Class.forName("");
con = DriverManager.getConnection("", "root", "root");
st = con.createStatement();
st.executeUpdate("");//CUD
rs = st.executeQuery("");//R
while(rs.next()){
}
} catch (Exception e) {
e.printStackTrace();
}finally{
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
con = null;
}
}
}
}
五、封装到JAVABEAN
遍历结果集打印到控制台没有意义,应该封装到JavaBean中:
user.java
package com.itheima.domain;
import java.util.Date;
public class User {
private int id;
private String username;
private String password;
private String email;
private Date birthday;
public User() {
super();
}
public User(int id, String username, String password, String email,
Date birthday) {
super();
this.id = id;
this.username = username;
this.password = password;
this.email = email;
this.birthday = birthday;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password="
+ password + ", email=" + email + ", birthday=" + birthday
+ "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
首先把之前的代码抽取出来封装成工具类,因为之前容易把配置给写死了,所以写一个jdbccfg.properties文件(配置里面的信息)
jdbccfg.properties
新建JdbcUtil.java(工具类,用来配置Jdbc连接的信息)
JdbcUtil.java
package com.itheima.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtil {
private static String DRIVER ;
private static String URL;
private static String USER;
private static String PASSWORD;
static{
InputStream is =JdbcUtil.class.getClassLoader().getResourceAsStream("jdbccfg.properties");
Properties p = new Properties();
try {
p.load(is);
DRIVER = p.getProperty("driver");
URL = p.getProperty("url");
USER = p.getProperty("user");
PASSWORD = p.getProperty("password");
Class.forName(DRIVER);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到连接
* @throws SQLException
*
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(URL,USER,PASSWORD);
}
/**
* 关闭资源
*/
public static void release(ResultSet rs,Statement st,Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
con = null;
}
}
}
为了只加载一次,使用静态代码块
在类里为得到方法、关闭资料封装成工具方法提供给我们使用、
新建test04去测试JDBCUtil.java
test04.java
package com.itheima.test;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import com.itheima.domain.User;
import com.itheima.util.JdbcUtil;
public class Test04 {
public static void main(String[] args) {
Connection con = null;
Statement st = null;
ResultSet rs = null;
try {
con = JdbcUtil.getConnection();
st = con.createStatement();
//CUD
//st.executeUpdate("");
//R
List<User> list = new ArrayList<User>();
rs = st.executeQuery("select * from user");
while(rs.next()){
//封装结果集到集合中
list.add(new User(rs.getInt("id"),rs.getString("username"),rs.getString("password")
,rs.getString("email"),rs.getDate("birthday")));
}
for(User user :list){
System.out.println(user);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.release(rs, st, con);
}
}
}
六、实例:利用JDBC改写之前的用户注册案例
七、理解Dao解耦的好处(很关键)
BeanFactory+接口实现类+Properties文件解决dao耦合性过强的弊端。在利用JDBC改写之前的用户注册案例中,我们利用了BeanFactory来导入用来配置信息的properties文件,用户可以手动更改properties的内容来切换系统和各种类型的数据库的连接,这种机制同时是借助于接口的特性还有接口和实现类之间的多态特性来完成,当程序员拿到了一个本来是使用别的数据库的项目时,由于项目使用了三层架构模型,那么就可以利用接口实现自己需要的数据库类型的实现类,并使用BeanFactory来进行切换。
八、大数据处理:使用JDBC编程进行对大容量数据进行上传下载
项目:blob03
jdbccfg.properties
driver=com.mysql.jdbc.Driver
url=jdbc\:mysql\://localhost\:3306/day15
user=root
password=root
JdbcUtil.java
package com.itheima.utils;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class JdbcUtil {
private static String DRIVER ;
private static String URL;
private static String USER;
private static String PASSWORD;
static{
InputStream is =JdbcUtil.class.getClassLoader().getResourceAsStream("jdbccfg.properties");
Properties p = new Properties();
try {
p.load(is);
DRIVER = p.getProperty("driver");
URL = p.getProperty("url");
USER = p.getProperty("user");
PASSWORD = p.getProperty("password");
Class.forName(DRIVER);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 得到连接
* @throws SQLException
*
*/
public static Connection getConnection() throws SQLException{
return DriverManager.getConnection(URL,USER,PASSWORD);
}
/**
* 关闭资源
*/
public static void release(ResultSet rs,Statement st,Connection con){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null;
}
if(st!=null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
st = null;
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
con = null;
}
}
}
Test.java
package com.itheima.test;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.itheima.utils.JdbcUtil;
/**
create table blobtest(
id int primary key,
content longblob
);
*
*/
public class Test {
public static void main(String[] args) {
//testWriter();
testReader();
}
private static void testReader() {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
String sql = "select * from blobtest where id=1";
try {
con = JdbcUtil.getConnection();
st = con.prepareStatement(sql);
rs = st.executeQuery();
if(rs.next()){
InputStream is = rs.getBinaryStream("content");
OutputStream os = new FileOutputStream("d:/2.jpg");
//写文件
int len=-1;
byte [] buffer = new byte[1024];
while((len=is.read(buffer))!=-1){
os.write(buffer,0,len);
}
os.close();
is.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.release(rs, st, con);
}
}
private static void testWriter() {
Connection con = null;
PreparedStatement st = null;
String sql = "insert into blobtest values(?,?)";
try {
con = JdbcUtil.getConnection();
st = con.prepareStatement(sql);
st.setInt(1, 1);
InputStream is =new FileInputStream("src/1.jpg");
st.setBinaryStream(2, is, is.available());
st.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.release(null, st, con);
}
}
}
Test02.java
package com.itheima.test;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.itheima.utils.JdbcUtil;
/**
create table clobtest(
id int primary key,
content longtext
);
*
*/
public class Test02 {
public static void main(String[] args) {
//testWriter();
testReader();
}
private static void testReader() {
Connection con = null;
PreparedStatement st = null;
ResultSet rs = null;
String sql = "select * from clobtest where id=1";
try {
con = JdbcUtil.getConnection();
st = con.prepareStatement(sql);
rs = st.executeQuery();
if(rs.next()){
Reader reader = rs.getCharacterStream("content");
FileWriter fw = new FileWriter("d:/2.txt");
int len=-1;
char []buffer = new char[1024];
while((len=reader.read(buffer))!=-1){
fw.write(buffer,0,len);
}
reader.close();
fw.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.release(rs, st, con);
}
}
private static void testWriter() {
Connection con = null;
PreparedStatement st = null;
String sql = "insert into clobtest values(?,?)";
try {
con = JdbcUtil.getConnection();
st = con.prepareStatement(sql);
st.setInt(1, 1);
File file = new File("src/1.txt");
FileReader reader = new FileReader(file);
st.setCharacterStream(2, reader, (int)file.length());//MySQL最多支持4G,而Oracle是可以的
st.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.release(null, st, con);
}
}
}
资料下载
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。