JDBC基础知识梳理

JDBC入门

Java DataBase Connectivity
持久化概念引入(persistence):
	把数据保存到可掉电式存储设备(断电之后数据还在 )中
数据持久化意味着将内存中的数据保存到硬盘上加以 固化

可以做持久化的:
	记事本
	XML
	数据库

1. JDBC 简介

是一种用于执行SQL语句的java API ,可以为多种关系数据库提供统一访问.
它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口
JDBC是接口,基准,工具-- 说明Java做了一组规范,它本身不实现这组规范。
让各大厂商去实现这组规范 具体实现代码由厂商提供 驱动程序

在java中 数据库存取技术只能通过JDBC访问数据库 其它技术是JDBC封装
JDBC访问数据库的形式主要有两种:
JDBC是一种最原生的访问方式
	直接使用JDBC的API去访问数据库服务器
	间接使用JDBC的API去访问数据库服务器 使用其他框架 第三方O/R Mapping
	工具,如Hibernate Mybatis JPA等

2. JDBC连接

记得导入数据库连接包  一般在数据库官网有提供下载

连接步骤:
    贾(加载注册驱动) Class.forName(“com.mysql.jdbc.Driver”)
    琏(获取连接)     DriverManager.getConnection(url,username,password)
    欲(获取语句对象) Statement st = conn.createStatement();
    执(执行)        st.executeUpdate/executeQuery(sql)
    事(释放资源)     st.close()/rs.close()/conn.close()

2.1 加载注册驱动

    从Java6开始,规范要求每一个JDBC驱动的包, 都必须带有
    META-INF/services/java.sql.Driver文件  可以不用注册驱动
    建议手动的加载注册驱动.如此,可以兼容之前的JDK版本
    
	注册驱动的三种方式: 
	A .DriverManager.registerDriver(new com.mysql.jdbc.Driver());
		会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。 
	具体来说就是: 
		1,加载的时候注册一次驱动(原因请看第三中注册方式),实例化的时候又注册一
		次。所以两次。 
		2,由于实例化了com.mysql.jdbc.Driver.class,导致必须导入该类(就是要
		把这个类import进去),从而具体驱动产生了依赖。不方便扩展代码。 
		
	B. System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver"); 
		通过系统的属性设置注册驱动  如果要注册多个驱动,则 System.setProperty
	("jdbc.drivers","com.mysql.jdbc.Driver:com.oracle.jdbc.Driver"); 
	虽然不会对具体的驱动类产生依赖;但注册不太方便,所以很少使用。 
     
	C. Class.forName("com.mysql.jdbc.Driver")
		推荐这种方式,不会对具体的驱动类产生依赖(就是不用import package了)
	关键点:
		com.mysql.jdbc.Driver类中 因为这个静态代码块 在加载类时就会执行了
		static{ 
               try{ 
            	java.sql.DriverManager.registerDriver(new Driver()); 
            }catch(SQLException e){ 
               throw new RuntimeException("can't register driver!"); 
            	} 
            } 

2.2 取连接对象

String url="jdbc:mysql://127.0.0.1:3306/mysqltest"
Connection conn=DriverManager.getConnection(url,uname,password);

解释:	jdbc:mysql指连接的数据库是mysql数据库
	 127.0.0.1:3306指的是数据库所在主机地址 和数据库端口号
	 uname 指的是数据库用户名
	 password 值得是数据库密码
	 
注意:
	在MySQl8.0及更高版本中 使用高版本的驱动包时有所变化
	驱动注册包变为com.mysql.cj.jdbc.Driver  同时在获取数据库连接时也有所不同  如下:
	Class.forName("com.mysql.cj.jdbc.Driver");
	Connection conn = 	
	DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysqltest?
	useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT",
	"root","root");

2.3 获取语句

	String sql="";

2.4 获取执行语句对象

	Statement st=conn.createStatement(); 
	或prepareStatement pst=conn.prepareStatement();
	
	prepareStatement使用方法:
			//用?占位
			String sql ="select * from student where username=? and password=?";
			// 预先连接数据库 
			PreparedStatement ps = conn.prepareStatement(sql );
			ps.setString(1," 填充第一问号占位 ");
			ps.setString(2, " 填充第2问号占位 ");
			ResultSet rs = ps.executeQuery();

	区别:
		关系:PreparedStatement继承自Statement,都是接口
		区别:PreparedStatement可以使用占位符,是预编译的,批处理比Statement效率高    

    PreparedStatement利用预编译的机制将sql语句的主干和参数分别传输给数据库服务器,从而使数据库分辨的出
    哪些是sql语句的主干哪些是参数,这样一来即使参数中带了sql的关键字,数据库服务器也仅仅将他当作参数值使用,
    关键字不会起作用,从而从原理上防止了sql注入的问题

	PreparedStatement主要有如下的三个优点:
       1.可以防止sql注入
       2.由于使用了预编译机制,执行的效率要高于Statement
       3.sql语句使用?形式替代参数,然后再用方法设置?的值,比起拼接字符串,代码更加优雅.

	PreparedStatement 与Statment比较
                   1)语法不同:PreparedStatement可以使用预编译的sql,而Statment只能使用静态的sql
                   2)效率不同: PreparedStatement可以使用sql缓存区,效率比Statment高
                   3)安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注
                   入。

2.5 获取结果映射集 ResultSet

    ResultSet resultSet = prepareStatement.executeQuery();
    或ResultSet resultSet= statement.execute(sql);

	查询数据库时,返回的是一个二维的结果集,我们需要用到ResultSet来遍历结果集,获取每一行的数据
	
	常用方法:
		boolean next() 将光标从当前位置向前移一行。
		
		String  getString(int columnIndex)  以java编程语言中String的形式获取此ResultSet对象的
		当前行中指定列的值
		
		String  getString(String columnLabel)  以java编程语言中String的形式获取此ResultSet对
		象的当前行中指定列的值
		
		ResultSetMetaData data = resultSet.getMetaData();
		int i=data.getColumnCount();//返回数据行数
		data.getColumnName(j)  //获取列名

2.6 释放资源

		public void close(Connection con, PreparedStatement ps, ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (ps != null)
					ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
				try {
					if (con != null)
						con.close();
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

完整示例代码

mysql5.5 驱动包版本5.1 jdk 1.8

public class JdbcUtil {
	public static Connection getConnection() {
		String url = "jdbc:mysql://127.0.0.1:3306/mysqltest";
		String user = "root";
		String password = "root";
		Connection conn = null;
		try {
			Class.forName("com.mysql.jdbc.Driver");
			conn = (Connection) DriverManager.getConnection(url, user, password);
		} catch (Exception e) {

			e.printStackTrace();
		}
		return conn;
	}

	public static void close(Connection con, PreparedStatement ps, ResultSet rs) {
		try {
			if (rs != null)
				rs.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {

			try {
				if (ps != null)
					ps.close();
			} catch (SQLException e) {
				e.printStackTrace();
			} finally {
					try {
					if (con != null)
						con.close();
					} catch (SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
			}
		}
	}
}

public class JdbcUse {
	@Test
	public void tes() throws Exception {
		Connection conn=JdbcUtil.getConnection();
		String sql="select * from dlltest ";
		PreparedStatement prepareStatement = (PreparedStatement) conn.prepareStatement(sql);
		ResultSet resultSet = prepareStatement.executeQuery();
		ResultSetMetaData data = resultSet.getMetaData();
		int i=data.getColumnCount();
		
		while(resultSet.next()) {
			for(int j=1;j<=i;j++)
			 System.out.print(resultSet.getObject(j)+" ");
			System.out.println();
			
		}
		JdbcUtil.close(conn, prepareStatement, resultSet);
	} 
}

参考链接:
https://blog.csdn.net/wangxintong_1992/article/details/80768067
https://blog.csdn.net/lsx2017/article/details/82630838
https://www.cnblogs.com/chenning/p/5030790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值