JAVA基础-JDBC使用

Posted 不愿透露姓名的王建森

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JAVA基础-JDBC使用相关的知识,希望对你有一定的参考价值。

JDBC

常用的包&接口

java.sql:JDBC 操作的时候,数据库相关的接口和类。

javax.sql:扩展包,可以提供额外的功能:连接池。

驱动包:mysql-connector-java-5.1.48.jar 一般都是厂家提供,厂家针对 JDBC 规范提供出来的接口, 进行实现。都是写好的 Java 源码。(https://dev.mysql.com/downloads/connector/j/)

DriverManager:主要用来管理和注册驱动,获取数据库连接对象。

Connection 接口:负责与数据库进行连接

Statement 接口:执行者对象,主要把 SQL 语句发送到数据库进行交互。

PreparedStatement 接口:执行者对象,Statement 的子类,更安全。

ResultSet 接口:用来封装从数据库中获得的数据,进而可以将数据封装到 JavaBean。

JDBC的注册和连接

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCDemo1 {
	//项目创建成功后
	//项目右键选择new-》folder》创建目录lib
	//把mysql驱动包复制到lib目录xia
	//右键mysql驱动文件  点击buildepath=》add build path 加载jar包到项目中
	//这样才可以使用这个jar包文件
	
	//建立连接
	//1.第一步 注册驱动
	//2. 得到建立连接对象(Connection) 驱动管理对象中的方法得到连接对象
	//3.需要传入三个参数 第一个参数url 包含了协议 本地ip端口号 指定数据库
	// 参数2 用户名  参数3 密码
	public static void main(String[] args) {
		//第一步注册驱动
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}//三个参数
		//URL
		String url="jdbc:mysql://localhost:3306/mybase02";
		//用户名
		String user="root";
		//密码
		String password="root";
		try {
			//第二步 得到建立连接对象
			Connection c1=DriverManager.getConnection(url, user, password);
			System.out.println();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		//错误:1.Unknown database \'stu\' 没有名字叫stu的数据库
		//2.conection refused connet 服务未启动 或者端口号错误连接失败
		//3.classnotfoundException :com.mysql.jdbc.Drvier 没有找到jar包 找到不到这个类
		//4.Access.... user ‘root’ @‘localhost’(using password:YEs) 用户名密码不正确
		
	}
}

Connection接口

Connection 主要是数据库连接对象。调用 createStatement() 方法,可以获得执行者对象,发送 SQL 到数据库执行。

Statement 执行者接口

PreparedStatement 执行者子类接口

如果使用了 PreparedStatement 类,首先会将你的 SQL 发送到数据库中进行预编译动作,然后会直接

引用预编译之后的结果,如果你的 SQL 需要传递参数的话,也可以多次传入不同的参数给这个对象并

执行。

不管有多少条 SQL 插入语句,数据库只需要预编译一次即可,可以传入多次参数,并执行。这里主要

是减少了预编译的次数,提高了执行的效率。

JDBC使用示例程序

这里我们把注册连接功能和关闭连接功能进行了封装,首先封装如下:

package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCUtils {

	//因为每次操作都需要连接数据库这一步骤 所以我们可以把这部分内容封装成工具类
	//书写一个方法  方法的返回类型 connection对象
	//把参数声明常量
	public static final String JDBCDRVIER="com.mysql.jdbc.Driver";
	public static final String URL="jdbc:mysql://localhost:3306/mybase01";
	public static final String USER="root";
	public static final String PASSWORD="root";
	
	
	//注册驱动 放到静态代码块中 只注册一次
	static {
		try {
			Class.forName(JDBCDRVIER);
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		System.out.println(getConnection());
	}
	public static Connection getConnection() {
		
		
		try {
			return DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
		
		
	}
	
	//关闭资源
	public static void closeJDBC(Connection c1,Statement s1,ResultSet rs) {
		if(c1!=null) {
			try {
				c1.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(s1!=null) {
			try {
				s1.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		if(rs!=null) {
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
}

随后我们按照数据库中每一行的格式,构建相应的对象,并重写相关的tostring方法

package Bean;

//classes表的实体类 
public class Classes {
	
	//基本类型封装 使用他的引用类型类(包装类)
	private Integer id;
	//例如存储学生成绩 0分  缺考  int  null
	private String name;
	
	
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "Classes [id=" + id + ", name=" + name + "]";
	}
	

}

最后我们使用junit进行简单的JDBC运行。

package com.kkb2;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import org.junit.Test;
import Bean.Classes;
import utils.JDBCUtils;

public class JDBCDemo1 {

	//查询
	@Test
	public void fun1() throws Exception {
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		System.out.println(c1);

		//区别 :
		//statement: 执行静态sql语句,每次执行语句数据库都要执行sql的编译操作
		//效率低下   并且有参数的时候还需要去拼接字符串就很麻烦  不能防止sql注入
		//preparedstatement:执行动态sql语句 ,预编译sql语句,执行效率高,安全好
		//可以防止sql注入  代码可读性高 有参数的时候可以使用占位符更方便
		//select * from user where username=张三 and password=1234 or 1=1
		//第二步 书写sql语句
		String sql="select * from classes";
		//第三步 得到执行sql对象 statement preparedstatement(重点)
		PreparedStatement prepareStatement = c1.prepareStatement(sql);
		//第四步  得到数据库中查询的数据 
		//  执行查询操作并返回结果  必须使用结果集接收
		ResultSet rs = prepareStatement.executeQuery();
		System.out.println(rs);
		while(rs.next()) {
			//第一种  列名 虽然getstring能得到其他类型数据建议使用自己类型 建议使用列名
			//例如int getInt方法
			// double  getDouble
			System.out.println("列名"+rs.getString("id"));
			System.out.println("列名"+rs.getString("name"));

			//第二种  放置 列号
			System.out.println("列号"+rs.getInt(1));
			System.out.println("列号"+rs.getString(2));
			//
		}

		//释放资源
		JDBCUtils.closeJDBC(c1, prepareStatement, rs);


	}

	//添加
	@Test
	public void fun2() throws Exception {
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		//第二步 书写sql语句
		String sql="insert into classes values(11,\'十一班\')";
		//第三步 得到sql执行对象 并传入sql字符串
		PreparedStatement ps = c1.prepareStatement(sql);
		//第四步 查看结果
		int rows=ps.executeUpdate();
		if(rows>0) {
			System.out.println("添加成功!");
			System.out.println(rows);
		}
		//释放资源
		JDBCUtils.closeJDBC(c1,ps, null);

	}
	//修改
	@Test
	public void fun3() throws Exception {
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		//第二步 书写sql语句
		String sql="update classes set name=\'11班\' where id=11";
		//第三步 得到sql执行对象 并传入sql字符串
		PreparedStatement ps = c1.prepareStatement(sql);
		//第四步 查看结果
		int rows=ps.executeUpdate();
		if(rows>0) {
			System.out.println("修改成功!");
			System.out.println(rows);
		}
		//释放资源
		JDBCUtils.closeJDBC(c1,ps, null);

	}
	//删除
	@Test
	public void fun4() throws Exception {
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		//第二步 书写sql语句
		String sql="delete from classes where id=11";
		//第三步 得到sql执行对象 并传入sql字符串
		PreparedStatement ps = c1.prepareStatement(sql);
		//第四步 查看结果
		int rows=ps.executeUpdate();
		if(rows>0) {
			System.out.println("删除成功!");
			System.out.println(rows);
		}
		//释放资源
		JDBCUtils.closeJDBC(c1,ps, null);

	}
	//删除升级版 参数使用占位符
	@Test
	public void fun41() throws Exception {
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入您要删除的班级id:");
		int id=scanner.nextInt();
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		//第二步 书写sql语句 预编译对象 有参数时 用占位符去拼接  ?
		String sql="delete from classes where id=?";
		//第三步 得到sql执行对象 并传入sql字符串
		PreparedStatement ps = c1.prepareStatement(sql);
		//使用ps 里面的方法 可以给占位符赋值
		ps.setInt(1, id);
		//第四步 查看结果
		int rows=ps.executeUpdate();
		if(rows>0) {
			System.out.println("删除成功!");
			System.out.println(rows);
		}
		//释放资源
		JDBCUtils.closeJDBC(c1,ps, null);

	}

	//模拟登陆案例
	@Test
	public void fun5() throws Exception {
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入您的用户名:");
		String name=scanner.next();
		System.out.println("请输入您的密码:");
		String pwd=scanner.next();
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		//第二步 书写sql语句 预编译对象 有参数时 用占位符去拼接  ?
		String sql="select * from user where username=? and password=?";
		//第三步 得到sql执行对象 并传入sql字符串
		PreparedStatement ps = c1.prepareStatement(sql);
		//使用ps 里面的方法 可以给占位符赋值 从1 
		ps.setString(1, name);//1 参数就是给第一个占位符赋值
		ps.setString(2, pwd);//给第二个占位符赋值

		//第四步 查看结果 现实生活中用户名是唯一  查询登陆正常返回一条语句
		//我们知道结果只有一条语句 遍历的时候 可以使用if效率更高
		//ps.executeQuery(sql);
		//注意 无参executeQuery();
		ResultSet rs = ps.executeQuery();
		if(rs.next()) {
			System.out.println("登陆成功"+rs.getString("username"));
		}
		//释放资源
		JDBCUtils.closeJDBC(c1,ps, null);

	}
	//classes 表查询 升级版 根据id查询
	//表在java工程中的实体类只实例化对象只能存储一条数据 
	//如果我们结果是多条怎么办?  使用集合解决我们问题  集合泛型是实体类型
	@Test
	public void fun6() throws Exception {
		Classes cc1=new Classes();
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入您要查询班级的id:");
		int id=scanner.nextInt();
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		String sql="select * from classes where id=?";
		//第三步 得到执行sql对象 statement preparedstatement(重点)
		PreparedStatement prepareStatement = c1.prepareStatement(sql);
		prepareStatement.setInt(1, id);
		//第四步  得到数据库中查询的数据 
		//  执行查询操作并返回结果  必须使用结果集接收
		ResultSet rs = prepareStatement.executeQuery();
		if(rs.next()) {
			cc1.setId(rs.getInt("id"));
			cc1.setName(rs.getString("name"));
			
		}
		System.out.println(cc1);
		System.out.println(cc1.getName());
		System.out.println(cc1.getId());
	}
	//查询classes多条数据  使用集合封装数据
	@Test
	public void fun7() throws Exception {
		//声明集合 存储多个数据
		List<Classes> list=new ArrayList<Classes>();
		//第一步  建立连接
		Connection c1=JDBCUtils.getConnection();
		String sql="select * from classes";
		//第三步 得到执行sql对象 statement preparedstatement(重点)
		PreparedStatement prepareStatement = c1.prepareStatement(sql);
		//第四步  得到数据库中查询的数据 
		//  执行查询操作并返回结果  必须使用结果集接收
		ResultSet rs = prepareStatement.executeQuery();
		
		while(rs.next()) {
			Classes cc1=new Classes();
			cc1.setId(rs.getInt("id"));
			cc1.setName(rs.getString("name"));
			list.add(cc1);
		}
		System.out.println(list);
	}

}

jdbc的事务回滚操作

同样,我们也利用上面封装好的JDBC工具程序:

package jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

import util.JDBCUtils;

//模拟转账案例
public class JDBCDemo1 {

	//一个账户减钱  另一个账户加钱
	//通过sql语句 其实执行修改语句 根据账户id 去修改表中金额
	public static void main(String[] args) {
		//第一步 建立连接
		Connection c1 = JDBCUtils.getConnection();
		
		PreparedStatement ps=null;
		try {
			c1.setAutoCommit(false);
			//第二步  书写sql语句 10010 要给10086 转500块
			String sql="update bankcard set money=money-500 where id=10010";
			//第三步 得到执行sql对象 并把SQL语句传入
				ps= c1.prepareStatement(sql);
				int rows = ps.executeUpdate();
				if(rows>0) {
					System.out.println("10010减钱成功");
					System.out.println(rows);
				}
				//
//				int i=1/0;
				//10086加钱
				String sql2="update bankcard set money=money+500 where id=10086";
				ps=c1.prepareStatement(sql2);
				int rows3=ps.executeUpdate();
				if(rows3>0) {
					System.out.println("10086加钱成功");
					System.out.println(rows3);
				}
				
				c1.commit();
				System.out.println("提交事务");
				
		} catch (Exception e) {
			//事务回滚
			try {
				c1.rollback();
				System.out.println("转账失败");
			} catch (SQLException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
		
		}finally {
			//关闭资源
			JDBCUtils.closeJDBC(c1, ps, null);
		}
	}
}

以上是关于JAVA基础-JDBC使用的主要内容,如果未能解决你的问题,请参考以下文章

JDBC基础

Java年度总复习基础部分

JavaJDBC基础使用教程

JavaJDBC基础使用教程

大数据必学Java基础(九十二):JDBC初识

关于mysql驱动版本报错解决,Cause: com.mysql.jdbc.exceptions.jdbc4Unknown system variable ‘query_cache_size(代码片段