12.JDBC-mysql.md
API简述
Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。
- connect(url, properties): 连接数据库的方法。
- url: 连接数据库的URL
- URL语法: jdbc协议:数据库子协议://主机:端口/数据库
- user:数据库的用户名
DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序
- registerDriver(driver) : 注册驱动类对象
- Connection getConnection(url,user,password); 获取连接对象
Connection接口: 表示java程序和数据库的连接对象。
- Statement createStatement() : 创建Statement对象
- PreparedStatement prepareStatement(String sql)创建PreparedStatement对象
- CallableStatement prepareCall(String sql) 创建CallableStatement对象
Statement接口: 用于执行静态的sql语句
- int executeUpdate(String sql) :执行静态的更新sql语句(DDL,DML)
- ResultSet executeQuery(String sql) :执行的静态的查询sql语句(DQL)
PreparedStatement接口:用于执行预编译sql语句
- int executeUpdate() :执行预编译的更新sql语句(DDL,DML)
- ResultSet executeQuery() : 执行预编译的查询sql语句(DQL)
CallableStatement接口:用于执行存储过程的sql语句(call xxx)
- ResultSet executeQuery() :调用存储过程的方法
ResultSet接口:用于封装查询出来的数据
- boolean next() : 将光标移动到下一行
- getXX() : 获取列的值
连接
三种方式
Demo:
package per.liyue.code.connecttest;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
public class ConnectTest {
private static String url = "jdbc:mysql://localhost:3306/hi";
//jdbc协议:数据库协议:主机:端口:连接数据库
public static void main(String[] args) throws Exception {
//Driver
test1();
//驱动管理器
test2();
//类加载
test3();
}
private static void test3() throws ClassNotFoundException, SQLException {
Class.forName(url);
//连接
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println(conn);
}
private static void test1() throws SQLException {
/*
* Driver类管理
*/
//驱动
Driver driver = new com.mysql.jdbc.Driver();
Properties por = new Properties();
por.setProperty("user", "root");
por.setProperty("password", "root");
//String url = "jdbc:mysql://localhost:3306/hi";
Connection conn = driver.connect(url, por);
System.out.println(conn);
}
private static void test2() throws SQLException {
/*
* 驱动管理类
*/
//驱动
Driver driver = new com.mysql.jdbc.Driver();
//注册:这里的注册在new com.mysql.jdbc.Driver()已经运行!!!
//DriverManager.registerDriver(driver);
//连接
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println(conn);
}
}
执行DDL&DML
Deom DDL:
package per.liyue.code.connecttest;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class ConnectTest {
private static String url = "jdbc:mysql://localhost:3306/hi";
//jdbc协议:数据库协议:主机:端口:连接数据库
public static void main(String[] args) throws Exception {
updateSql();
}
private static void updateSql() {
Statement st = null;
Connection conn = null;
try {
//获取连接
Class.forName(url);
conn = DriverManager.getConnection(url, "root", "root");
//获取
st = conn.createStatement();
//执行
String sql = "CREATE TABLE person(id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(8));";
int count = st.executeUpdate(sql);
System.out.println("创建表影响行:" + count);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
finally {
if (null != st) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
}
private static void test3() throws ClassNotFoundException, SQLException {
Class.forName(url);
//连接
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println(conn);
}
private static void test1() throws SQLException {
/*
* Driver类管理
*/
//驱动
Driver driver = new com.mysql.jdbc.Driver();
Properties por = new Properties();
por.setProperty("user", "root");
por.setProperty("password", "root");
//String url = "jdbc:mysql://localhost:3306/hi";
Connection conn = driver.connect(url, por);
System.out.println(conn);
}
private static void test2() throws SQLException {
/*
* 驱动管理类
*/
//驱动
Driver driver = new com.mysql.jdbc.Driver();
//注册:这里的注册在new com.mysql.jdbc.Driver()已经运行!!!
//DriverManager.registerDriver(driver);
//连接
Connection conn = DriverManager.getConnection(url, "root", "root");
System.out.println(conn);
}
}
执行DQL
常用数据类型转换
Demo:
//执行
String sql = "";
ResultSet result = st.executeQuery(sql);
while(result.next()){
/*
* 按列索引
*/
int idByIndex = result.getInt(1);
/*
* 按列名称
*/
int idByName = result.getShort("id");
}
预编译
- 语法:可以预编译sql,Statment只能静态调用
- 效率:可以使用sql缓存,效率高
- 安全:防止sql注入
注意:
支持缓存的数据库:Oracle, Sql Server
不支持的数据库:mysql
Demo:
public class Demo1 {
/**
* 增加
*/
@Test
public void testInsert() {
Connection conn = null;
PreparedStatement stmt = null;
try {
//1.获取连接
conn = JdbcUtil.getConnection();
//2.准备预编译的sql
String sql = "INSERT INTO student(NAME,gender) VALUES(?,?)"; //?表示一个参数的占位符
//3.执行预编译sql语句(检查语法)
stmt = conn.prepareStatement(sql);
//4.设置参数值
/**
* 参数一: 参数位置 从1开始
*/
stmt.setString(1, "李四");
stmt.setString(2, "男");
//5.发送参数,执行sql
int count = stmt.executeUpdate();
System.out.println("影响了"+count+"行");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt);
}
}
/**
* 修改
*/
@Test
public void testUpdate() {
Connection conn = null;
PreparedStatement stmt = null;
try {
//1.获取连接
conn = JdbcUtil.getConnection();
//2.准备预编译的sql
String sql = "UPDATE student SET NAME=? WHERE id=?"; //?表示一个参数的占位符
//3.执行预编译sql语句(检查语法)
stmt = conn.prepareStatement(sql);
//4.设置参数值
/**
* 参数一: 参数位置 从1开始
*/
stmt.setString(1, "王五");
stmt.setInt(2, 9);
//5.发送参数,执行sql
int count = stmt.executeUpdate();
System.out.println("影响了"+count+"行");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt);
}
}
/**
* 删除
*/
@Test
public void testDelete() {
Connection conn = null;
PreparedStatement stmt = null;
try {
//1.获取连接
conn = JdbcUtil.getConnection();
//2.准备预编译的sql
String sql = "DELETE FROM student WHERE id=?"; //?表示一个参数的占位符
//3.执行预编译sql语句(检查语法)
stmt = conn.prepareStatement(sql);
//4.设置参数值
/**
* 参数一: 参数位置 从1开始
*/
stmt.setInt(1, 9);
//5.发送参数,执行sql
int count = stmt.executeUpdate();
System.out.println("影响了"+count+"行");
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt);
}
}
/**
* 查询
*/
@Test
public void testQuery() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//1.获取连接
conn = JdbcUtil.getConnection();
//2.准备预编译的sql
String sql = "SELECT * FROM student";
//3.预编译
stmt = conn.prepareStatement(sql);
//4.执行sql
rs = stmt.executeQuery();
//5.遍历rs
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
String gender = rs.getString("gender");
System.out.println(id+","+name+","+gender);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
//关闭资源
JdbcUtil.close(conn,stmt,rs);
}
}
}
存储过程
Demo:
/**
* 使用CablleStatement调用存储过程
* @author APPle
*
*/
public class Demo1 {
/**
* 调用带有输入参数的存储过程
* CALL pro_findById(4);
*/
@Test
public void test1(){
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
//准备sql
String sql = "CALL pro_findById(?)"; //可以执行预编译的sql
//预编译
stmt = conn.prepareCall(sql);
//设置输入参数
stmt.setInt(1, 6);
//发送参数
rs = stmt.executeQuery(); //注意: 所有调用存储过程的sql语句都是使用executeQuery方法执行!!!
//遍历结果
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
String gender = rs.getString("gender");
System.out.println(id+","+name+","+gender);
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt ,rs);
}
}
/**
* 执行带有输出参数的存储过程
* CALL pro_findById2(5,@NAME);
*/
@Test
public void test2(){
Connection conn = null;
CallableStatement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
//准备sql
String sql = "CALL pro_findById2(?,?)"; //第一个?是输入参数,第二个?是输出参数
//预编译
stmt = conn.prepareCall(sql);
//设置输入参数
stmt.setInt(1, 6);
//设置输出参数(注册输出参数)
/**
* 参数一: 参数位置
* 参数二: 存储过程中的输出参数的jdbc类型 VARCHAR(20)
*/
stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
//发送参数,执行
stmt.executeQuery(); //结果不是返回到结果集中,而是返回到输出参数中
//得到输出参数的值
/**
* 索引值: 预编译sql中的输出参数的位置
*/
String result = stmt.getString(2); //getXX方法专门用于获取存储过程中的输出参数
System.out.println(result);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
} finally {
JdbcUtil.close(conn, stmt ,rs);
}
}
}
加载配置
可以用Properties文件配置驱动信息,但是要注意一点不要用.来表示路径:
- 在Java项目下,.java命令运行目录从根目录开始
- 在Web项目下,.java命令运行目录从tomcat/bin下开始
所以获取路径使用:
/*
*使用类路径读取:
* 在Java项目下,classpath的根目录从bin根目录开始
* 在Web项目下,classpath的根目录从WEB-INF/classes目录开始
*/
ConnectTest.class.getResourceAsStream("/");
获取自增长
/*
* 指定返回自增长列
*/
PreparedStatement ps = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
/*
* 获取自增长列,自增长列只有一个
*/
ResultSet rs = ps.getGeneratedKeys();
int feneratedKey = rs.getInt(1);
批量操作
事务处理
关键API:
void setAutoCommit(boolean autoCommit) 是否自动提交
void commit() 提交
void rollback() 回滚void rollback(Savepoint savepoint) 回滚到指定位置```Java
Savepoint s = conn.setSavepoint("一个测试回滚点");
//回滚到指定的位置
conn.rollback(s);