jdbc就是一套连接数据库服务器的一套接口。
一 jdbc基础
1.1 连接数据库
导包:导入mysql的驱动程序jar包(mysql-connector-5.1.7-bin.jar),可以去mysql官网下载
,如果是orcal数据库要导入orcal的驱动程序包
使用方法
//通过驱动管理器可以注册多个驱动,如:mysql,orcal
class test2
{
//Driver driver = new com.mysql.jdbc.Driver();
//通过得到字节码对象的方式加载静态代码块,从而注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
//注册驱动程序(可以注册多个驱动程序)
//DriverManager.registerDriver(driver);
//连接到具体的数据库 通过url判断连接到哪个数据库
Connection conn = DriverManager.getConnection(url,"用户名","密码");
}
1.2 statement对象
作用:执行静态的sql语句
public class demo
{
//链接数据库的url 格式:jdbc协议:数据库子协议://主机:端口/数据库名
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
String user = "登陆数据库用户名";
String password = "登陆数据库密码";
public void testDemo()
{
Connection conn = null;
Statement stmt = null;
try {
//注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
//获取connection对象
conn = DriverManager.getConnection(url,user,password);
//创建statement对象
stmt = conn.createStatement();
//编写sql语句
String sql = "create table student(id int primary key auto_increment,name varchar(20),gender varchar(2))";
//执行sql语句 count影响的行数
int count = stmt.executeUpdate(sql);
}
catch(Exception e)
{
throw new RuntimException(e);
}
finally
{
//关闭链接 顺序:后打开的先关闭
if(stmt!=null)stmt.close();
if(conn!=null)conn .close();
}
}
}
注释:stmt.executeUpdate(sql)可以执行创建表,修改数据,插入数据,删除数据的sql语句,stmt.executeQuery(sql)可执行查询的语句。
查询操作示例:
public class demo2
{
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
String user = "登陆数据库用户名";
String password = "登陆数据库密码";
public void testDemo()
{
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
//获取connection对象
conn = DriverManager.getConnection(url,user,password);
//编写sql语句
String sql = "select * from student";
//执行sql语句 ResultSet结果集
ResultSet rs = stmt.executeQuery(sql);
while(rs.next())
{
int id = rs.getInt("id");
String name = rs.getString("name");
String gender = rs.getString("gender");
}
}
catch(Exception e)
{
throw new RuntimException(e);
}
finally
{
//关闭链接 顺序:后打开的先关闭
if(stmt!=null)stmt.close();
if(conn!=null)conn .close();
if(rs!=null)rs .close();
}
}
}
1.3 PreparedStatement对象
作用:执行预编译的sql语句
public class demo2
{
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
String user = "登陆数据库用户名";
String password = "登陆数据库密码";
public void testDemo()
{
Connection conn = null;
PrepareStatement Statement stmt = null;
try {
//注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
//获取connection对象
conn = DriverManager.getConnection(url,user,password);
//编写sql语句
String sql = "insert into student(name,gender)values(?,?)";//?表示一个参数的占位符
//执行预编译sql语句(检查语法)
stmt = conn.prepareStatement(sql);
//设置参数 第一个参数:参数位置,从1开始
stmt.setString(1,'李四');
stmt.setString(2,'男');
stmt.executeUpdate();
}
catch(Exception e)
{
throw new RuntimException(e);
}
finally
{
//关闭链接 顺序:后打开的先关闭
if(stmt!=null)stmt.close();
if(conn!=null)conn .close();
}
}
}
Statement和PreparedStatement区别:
- PreparedStatement可以利用数据库的缓冲区,效率更高。
- statement有被注入的风险,PreparedStatement没有。
1.4 CallableStatement(继承自PreparedStatement)
作用:调用存储过程
public class demo3
{
String url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8";
String user = "登陆数据库用户名";
String password = "登陆数据库密码";
public void testDemo()
{
Connection conn = null;
CallableStatement Statement stmt = null;
try {
//注册驱动程序
Class.forName("com.mysql.jdbc.Driver");
//获取connection对象
conn = DriverManager.getConnection(url,user,password);
//编写sql语句
String sql = "pro_findById(?,?)";//?表示一个参数的占位符
//执行预编译sql语句(检查语法)
stmt = conn.prepareCall(sql);
//注册输出参数
stmt.registerOutParameter(2,java.sql.Types.VARCHAR);
//设置参数 第一个参数:参数位置,从1开始
stmt.setString(1,2);
//如果是查询操作的存储过程 要用 stmt.executeQuery();
stmt.executeUpdate();
//如果存储过程有输出参数用以下方法获取
String name = stmt.getString(2);
}
catch(Exception e)
{
throw new RuntimException(e);
}
finally
{
//关闭链接 顺序:后打开的先关闭
if(stmt!=null)stmt.close();
if(conn!=null)conn .close();
}
}
}
1.5 批处理
作用:可以向数据库发送一批sql语句,避免一条一条的发送执行,以提示执行效率。
示例代码:
public void save(List<Admin> list) {
// SQL
String sql = "INSERT INTO admin(userName,pwd) values(?,?)";
try {
// 获取连接
con = JdbcUtil.getConnection();
// 创建stmt
pstmt = con.prepareStatement(sql); // 【预编译SQL语句】
for (int i=0; i<list.size(); i++) {
Admin admin = list.get(i);
// 设置参数
pstmt.setString(1, admin.getUserName());
pstmt.setString(2, admin.getPwd());
// 添加批处理
pstmt.addBatch();// 【不需要传入SQL】
// 测试:每5条执行一次批处理
if (i % 5 == 0) {
// 批量执行
pstmt.executeBatch();
// 清空批处理
pstmt.clearBatch();
}
}
// 批量执行
pstmt.executeBatch();
// 清空批处理
pstmt.clearBatch();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, rs);
}
}
1.6 插入数据时获取自增长值
con = JdbcUtil.getConnection();
/*****获取自增长*******/
// 【一、需要指定返回自增长标记】
pstmt = con.prepareStatement(sql_dept,Statement.RETURN_GENERATED_KEYS);
// 设置参数
pstmt.setString(1, emp.getDept().getDeptName());
// 执行
pstmt.executeUpdate();
// 【二、获取上面保存的自增长的主键】
rs = pstmt.getGeneratedKeys();
// 得到返回的自增长字段
if (rs.next()) {
deptId = rs.getInt(1);
}
1.7 事务执行
事务使指一组最小逻辑操作单元,里面有多个操作组成。 组成事务的每一部分必须要同时提交成功,如果有一个操作失败,整个操作就回滚。
使用事务主要的api:
void setAutoCommit(boolean autoCommit) ; 设置事务是否自动提交,如果设置为false,表示手动提交事务。
void commit() (); 手动提交事务
void rollback() ;
示例代码
public void trans() {
String sql_zs = "UPDATE account SET money=money-1000 WHERE accountName='张三';";
String sql_ls = "UPDATE1 account SET money=money+1000 WHERE accountName='李四';";
try {
con = JdbcUtil.getConnection(); // 默认开启的隐士事务
// 一、设置事务为手动提交
con.setAutoCommit(false);
/*** 第一次执行SQL ***/
pstmt = con.prepareStatement(sql_zs);
pstmt.executeUpdate();
/*** 第二次执行SQL ***/
pstmt = con.prepareStatement(sql_ls);
pstmt.executeUpdate();
} catch (Exception e) {
try {
// 二、 出现异常,需要回滚事务
con.rollback();
} catch (SQLException e1) {
}
e.printStackTrace();
} finally {
try {
// 三、所有的操作执行成功, 提交事务
con.commit();
JdbcUtil.closeAll(con, pstmt, null);
} catch (SQLException e) {
}
}
}
1.8 操作长文本数据和二进制数据
Oracle中大文本数据类型:
Clob 长文本类型 (MySQL中不支持,使用的是text)
Blob 二进制类型
MySQL数据库:
Text 长文本类型
Blob 二进制类型
//创建表
CREATE TABLE test(
id INT PRIMARY KEY AUTO_INCREMENT,
content LONGTEXT,
img LONGBLOB
);
大文本数据的保存和读取
示例代码:
public class App_text {
// 全局参数
private Connection con;
private Statement stmt;
private PreparedStatement pstmt;
private ResultSet rs;
@Test
// 1. 保存大文本数据类型 ( 写longtext)
public void testSaveText() {
String sql = "insert into test(content) values(?)";
try {
// 连接
con = JdbcUtil.getConnection();
// pstmt 对象
pstmt = con.prepareStatement(sql);
// 设置参数
// 先获取文件路径
String path = App_text.class.getResource("tips.txt").getPath();
FileReader reader = new FileReader(new File(path));
pstmt.setCharacterStream(1, reader);
// 执行sql
pstmt.executeUpdate();
// 关闭
reader.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, null);
}
}
@Test
// 2. 读取大文本数据类型 ( 读longtext)
public void testGetAsText() {
String sql = "select * from test;";
try {
// 连接
con = JdbcUtil.getConnection();
// pstmt 对象
pstmt = con.prepareStatement(sql);
// 读取
rs = pstmt.executeQuery();
if (rs.next()) {
// 获取长文本数据, 方式1:
//Reader r = rs.getCharacterStream("content");
// 获取长文本数据, 方式2:
System.out.print(rs.getString("content"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, null);
}
}
}
二进制数据的保存和读取
public class App_blob {
// 全局参数
private Connection con;
private Statement stmt;
private PreparedStatement pstmt;
private ResultSet rs;
@Test
// 1. 二进制数据类型 ( 写longblob)
public void testSaveText() {
String sql = "insert into test(img) values(?)";
try {
// 连接
con = JdbcUtil.getConnection();
// pstmt 对象
pstmt = con.prepareStatement(sql);
// 获取图片流
InputStream in = App_text.class.getResourceAsStream("7.jpg");
pstmt.setBinaryStream(1, in);
// 执行保存图片
pstmt.execute();
// 关闭
in.close();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, null);
}
}
@Test
// 2. 读取二进制数据类型 ( 读longblob)
public void testGetAsText() {
String sql = "select img from test where id=2;";
try {
// 连接
con = JdbcUtil.getConnection();
// pstmt 对象
pstmt = con.prepareStatement(sql);
// 读取
rs = pstmt.executeQuery();
if (rs.next()) {
// 获取图片流
InputStream in = rs.getBinaryStream("img");
// 图片输出流
FileOutputStream out = new FileOutputStream(new File("c://1.jpg"));
int len = -1;
byte b[] = new byte[1024];
while ((len = in.read(b)) != -1) {
out.write(b, 0, len);
}
// 关闭
out.close();
in.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtil.closeAll(con, pstmt, null);
}
}
}