• 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);
    		}
    	}
    }
    
    
  • 相关阅读:
    MongoDB配置多个ConfigDB的问题(笔记)
    Python访问PostGIS(建表、空间索引、分区表)
    Python访问MySQL数据库
    Python访问MongoDB数据库
    Mapnik读取PostGIS数据渲染图片
    Python批量处理CSV文件
    Spring Mongo配置多个Mongos
    hadoop2.2.0_hbase0.96_zookeeper3.4.5全分布式安装文档下载
    【Git】(1)---工作区、暂存区、版本库、远程仓库
    微信扫码支付功能(2)---用户扫码支付成功,微信异步回调商户接口
  • 原文地址:https://www.cnblogs.com/JeasonIsCoding/p/13232600.html
Copyright © 2020-2023  润新知