JDBC的基础操作
JDBC
JDBC API 允许用户访问任何形式的表格数据,尤其是存储在关系数据库中的数据。
执行流程:
-
连接数据源,如:数据库。
-
为数据库传递查询和更新指令。
-
处理数据库响应并返回的结果。
JDBC 架构
分为双层架构和三层架构:
双层:- 作用:此架构中,Java Applet 或应用直接访问数据源。
- 条件:要求 Driver 能与访问的数据库交互。
- 机制:用户命令传给数据库或其他数据源,随之结果被返回。
- 部署:数据源可以在另一台机器上,用户通过网络连接,称为 C/S配置(可以是内联网或互联网)。
三层:
(侧架构特殊之处在于,引入中间层服务。)
-
流程:命令和结构都会经过该层。
-
吸引:可以增加企业数据的访问控制,以及多种类型的更新;另外,也可简化应用的部署,并在多数情况下有性能优势。
-
历史趋势: 以往,因性能问题,中间层都用 C 或 C++ 编写,随着优化编译器(将 Java 字节码 转为 高效的 特定机器码)和技术的发展,如EJB,Java 开始用于中间层的开发这也让 Java 的优势突显出现出来,使用 Java 作为服务器代码语言,JDBC随之被重视。
JDBC 编程步骤
- 将驱动装进内存中
- 连接数据库
- 执行SQL语句
- 执行查询,返回到结果集中
- 处理数据
- 关闭连接和其他对象 有堆的时候进行关闭,没堆只有栈的时候调用会出现空指针错误
查询所有
@Test
public void queryByUsername() {
//select * from user where username like 'zhangc%'
Connection conn = null;//用来进行连接MySQL
PreparedStatement pstmt = null;//预处理语句,向数据库发送要执行的SQL语句
ResultSet rs = null;//用来装结果集
try {
//1.将驱动装进内存中
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true",
"root", "root");
//3.执行SQL语句
String sql = "select * from user where username like ? order by id ";
//3.把SQL语句加载到内存中去
pstmt = conn.prepareStatement(sql);
pstmt.setString(1, "zhangc%");
//4.执行查询,返回到结果集rs中
rs = pstmt.executeQuery();
//5.处理数据
while (rs.next()) {
System.out.printf("%s---%s---%.2f\n",
rs.getString("username"),
rs.getString("password"),
rs.getFloat("salary"));
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
//6.关闭连接和其他对象 有堆的时候进行关闭,没堆只有栈的时候调用会出现空指针错误
if (rs != null) {
rs.close();
}
if (pstmt != null) {
pstmt.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
带有限制的查询
@Test
public void proc(){
//1 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "{call p_5(?,?)}";
Connection conn=null;
CallableStatement cs=null;
ResultSet rs=null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
cs=conn.prepareCall(sql);
cs.setString(1,"weikun%");
cs.registerOutParameter(2, Types.INTEGER);
boolean flag=cs.execute();//是否执行成功
while(flag){
rs=cs.getResultSet();
while(rs.next()){
System.out.printf("%s---%s---%f\n",
rs.getString("username"),
rs.getString("password"),
rs.getFloat("salary"));
}
System.out.println(cs.getObject(2));//取出输出参数
flag=cs.getMoreResults();//是否有更多的结果集
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (rs != null) {
rs.close();
}
if (cs != null) {
cs.close();
}
//5 关闭连接和其他对象
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
增加数据
@Test
public void add() {
String sql = "insert into user(username,password,salary) values (?,?,?)";
try {
Class.forName("com.mysql.jdbc.Driver");//1加载驱动
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try (//try括号内必须实现AutoCloseable接口才可以放在里面,就是说具有自动关闭功能,不再需要进行主动close关闭
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true",
"root",
"root");
PreparedStatement pstmt = conn.prepareStatement(sql);
) {
//3 执行sql语句
pstmt.setString(1, "songweihua");
pstmt.setString(2, "000000");
pstmt.setFloat(3, 9999999);
System.out.println(pstmt.executeUpdate() > 0 ? "成功" : "失败");//返回值是一个数,如果数据变多返回的是1
} catch (Exception e) {
e.printStackTrace();
}
}
删除数据
@Test
public void del() throws ClassNotFoundException {
//1 加载驱动
Class.forName("com.mysql.jdbc.Driver");
String sql = "delete from user where id>?";
try (
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
PreparedStatement pstmt = conn.prepareStatement(sql);
) {
pstmt.setInt(1, 7);
System.out.println(pstmt.executeUpdate() > 0 ? "成功" : "失败");
} catch (Exception e) {
e.printStackTrace();
}
}
修改数据(手动提交事物)
@Test
public void update() throws ClassNotFoundException {
//1 加载驱动
Class.forName("com.mysql.jdbc.Driver");
String sql = "update user set username=? where id=?";
Connection conn = null;
PreparedStatement pstmt = null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
pstmt = conn.prepareStatement(sql);
conn.setAutoCommit(false);//将自动提交关闭
pstmt.setString(1, "哈尔滨");
pstmt.setInt(2, 1);
System.out.println(pstmt.executeUpdate() > 0 ? "成功" : "失败");
conn.commit();//提交
} catch (Exception e) {
try {
conn.rollback();//回滚
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if (pstmt != null) {
pstmt.close();
}
//5 关闭连接和其他对象
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
操作存储过程
@Test
public void proc(){
//1 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "{call p_6(?,?)}";//p_6是一个存储过程
Connection conn=null;
CallableStatement cs=null;
ResultSet rs=null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
cs=conn.prepareCall(sql);
cs.setString(1,"zhang%");//"{call p_6(?,?)}" 第一个问号 setString:输入参数
cs.registerOutParameter(2, Types.INTEGER);//"{call p_6(?,?)}" 第二个问号 registerOutParameter:注册输出参数
boolean flag=cs.execute();//是否执行成功
while(flag){
rs=cs.getResultSet();
//(1)带有结果集的
while(rs.next()){
System.out.printf("%s---%s---%f\n",
rs.getString("username"),
rs.getString("password"),
rs.getFloat("salary"));
}
//(2)纯输出参数的
System.out.println(cs.getObject(2));
flag=cs.getMoreResults();//是否有更多的结果集,没有flag为假
}
}catch(Exception e){
e.printStackTrace();
}finally{
try {
//5 关闭连接和其他对象
if (rs != null) {
rs.close();
}
if (cs != null) {
cs.close();
}
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
调用方法
@Test
public void func(){
//1 加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
String sql = "{?=call f_6(?)}";
// String sql="select f_6(prod_price) from products";
Connection conn=null;
CallableStatement cs=null;
try {
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/bz?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
cs = conn.prepareCall(sql);
cs.registerOutParameter(1,Types.FLOAT);
cs.setFloat(2,200);
cs.execute();
System.out.println(cs.getObject(1));
}catch(Exception e){
e.printStackTrace();
}finally{
try {
if (cs != null) {
cs.close();
}
//5 关闭连接和其他对象
if (conn != null) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}