java-JDBC技术

java-JDBC技术

jdbc我们首先先看百度百科对jdbc的定义:
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用**Java语言编写的类和接口组成。**JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名。
简单的来说JDBC就是java连接数据库,获取数据库对象的一种技术,JDBC技术是数据库与应用程序之间的桥梁,是数据库与应用程序的中间件。但是JDBC所有的操作部分几乎都是固定的,需要掌握这莫的几个类和接口来帮助我们进一步了解JDBC:

1、DriverManager : 驱动管理对象 - - ->>类
1、功能:注册驱动
Static void registerDriver ( Driver driver ); == = =Class.forName( “com.mysql.jdbc.Driver” );
a注:MySql5之后的jar包可以省略注册驱动这一步
装载MySql驱动:Class.forName(“com.mysql.jdbc.Driver”);
装载Oracle驱动:Class.forName(“oracle.jdbc.driver.OracleDriver”);
2、获取数据库连接
方法:public static Connection getConnection( String url , String user, String password );
url:指定连接的路径。(ip,端口)
MySQL:jdbc:mysql://ip地址(域名):端口号/数据库名称---->一般如过不写ip和端口默认是本机和3306端口
Oracle: oracle.jdbc.driver.OracleDriver
user:用户
password:密码
2、Connection : 数据库连接对象
获取执行Sql的对象。 public Statement stmt = coon.createStatement();
public preparedStatement preparedStatement (String sql);
管理事务:
开启事务:void setAutoComment(boolean b );//将该方法的事务设为False,即为开启事务
提交事务:void commit();
回滚事务:void rollback();
3、Statement : 执行SQL的对象---->接口interface—执行静态SQL
1、执行sql:boolean execte(String sql);
2、 int executeUpdate(String sql) :执行DML(insert \ update\ delete)语句、DDL语句(Create\alter、drop)
返回的值为影响的行数。
3、 ResultSet executeQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。
返回的结果集对象,语句表查询(select)
4、 addBatch(String sql) :把多条sql语句放到一个批处理中。
5、 executeBatch():向数据库发送一批sql语句执行。
3.1、PreparedStatement : —>属于接口(执行动态SQL对象)
1、sql注入问题 输入的用户随便 select * from user_test where username = ‘随便’ and password = ‘a’ or ‘a’ = ‘a’;
字符串拼接存在sql的关键字问题
解决:PreparedStatement 对象解决 —>预编译sql,参数使用?为占位符
这里获取sql方法就变成PreparedStatement Connection.preparedStatement( sql );
这里需要注意为?赋值:
方法:setXxx( 参数1,参数2 )
参数1: ? 的位置编号从1 开始 也是问号的值
参数2:?的值
这里在执行sql的时候不需要传递Sql已经传过了
4、ResultSet : 结果集对象 — 封装查询结果
boolean next();//方法 指针向下移动
Xxx getXxx( 参数 );//获取数据 Xxx表数据类型
1. getString(int index)、getString(String columnName):获得在数据库里是varchar、char等类型的数据对象。
2. getFloat(int index)、getFloat(String columnName):获得在数据库里是Float类型的数据对象。
3. getDate(int index)、getDate(String columnName):获得在数据库里是Date类型的数据。
4. getBoolean(int index)、getBoolean(String columnName):获得在数据库里是Boolean类型的数据。
5. getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。
参数的情况:
1、int :代表列的编号,( 这里注意是编号,从1开始 )
2、String : 代表列的名称

注:使用后依次关闭对象及连接:ResultSet → Statement → Connection
上面说到JDBC一般的流程都是固定的,一般为:
1、注册驱动=Class.forName( “com.mysql.jdbc.Driver” )
Oracle: oracle.jdbc.driver.OracleDriver
2、获取数据库连接对象 public Statement stmt = coon.createStatement();
3、设置sql语句,执行SQL的对象,PreparedStatement
4、ResultSet集合 : 结果集对象 — 封装查询结果**
紧接着我们先简短的看一个程序:

import java.sql.*;
import com.mysql.jdbc.Statement;

/**
 * 
 * <p>Title:Dome02.java</p>
 * <p>Description:JDBC练习</p>
 * @author 会飞的鱼
 *	注:这里的资源操作应该会有异常抛出,用try catch finally
 *	可以再finally中加入关闭流的操作
 */
public class Dome02 {

	//这里需要定义全局变量,方便关闭它
	private static Connection conn = null;
	private static Statement stat = null;
	/*
	 * user表的添加操作 insert
	 */
	public static void main(String[] args) {
		
		try {
			//1、注册驱动
			String dbdriver = "com.mysql.jdbc.Driver";
			//String dbdriver = "oracle.jdbc.driver.OracleDriver";
			Class.forName(dbdriver);//表注册驱动
			//连接的url----》最后为端口号/数据库名称
			String dburl = "jdbc:mysql://localhost:3306/mydate";
			//3306为数据库的默认连接端口
			//mydtae 为数据库的名称
			//String dburl = "jdbc:oracle:thin:@localhost:1521:mydate";
			String user = "root";
			String password = "yl981120";
			conn = DriverManager.getConnection(dburl, user, password);//connection对象是用来连接数据库对象的
			//定义Sql
			String sql = "insert into user values(null,'anyu','女','161031','10111601','123','123456')";
			stat = (Statement) conn.createStatement();
			int n  = stat.executeUpdate(sql);
			if(n > 0){
				System.out.println("影响的行数"+n);
				System.out.println("添加成功");
			}else{
				System.out.println("操作失败");
			}
			
		} catch (SQLException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}finally{
			//这里可能会出现空指针异常
			if(stat!=null){
				try {
					stat.close();
				} catch (SQLException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
			}
			if(conn!=null){
				try {
					conn.close();
				} catch (SQLException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				}
			}
		}	
	}
}

这里需要注意使用的是什么数据库,就需要用什么来注册驱动,一定要对症下药
装载MySql驱动:Class.forName(“com.mysql.jdbc.Driver”);
装载Oracle驱动:Class.forName(“oracle.jdbc.driver.OracleDriver”);
以及获取url都需要自己来写
连接MySql数据库:Connection conn = DriverManager.getConnection(“jdbc:mysql://host:port/database”, “user”, “password”);
  连接Oracle数据库:Connection conn = DriverManager.getConnection(“jdbc:oracle:thin:@host:port:database”, “user”, “password”);
  连接SqlServer数据库:Connection conn = DriverManager.getConnection(“jdbc:microsoft:sqlserver://host:port; DatabaseName=database”, “user”, “password”);

在学习完这些之后,当然会自己也写一个JDBC的工具类,用来方便自己以后的使用

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;

public class jdbcUtils {

	private static String url ;
	private static String user ;
	private static String password ;
	private static String dbDriver ;
	
	//千万记住,如果资源操作仅访问一次,别忘记了static代码块
	static{
		try {
			//文件的读取
			Properties pro = new Properties();
			//加载文件
			//这里有获取src路径下文件的方式=======ClassLoader-->类加载器
			ClassLoader cl = jdbcUtils.class.getClassLoader();
			URL res = cl.getResource("jdbc.properties");//url对象表示统一资源标识符
			String path = res.getPath();
//			pro.load(new FileInputStream("src/jdbc.properties"));
			//System.out.println(path);
			pro.load(new FileInputStream(path));
			//获取值
			url = pro.getProperty("url");
			user = pro.getProperty("user");
			password = pro.getProperty("password");
			dbDriver = pro.getProperty("driver");
			//注册驱动
			Class.forName(dbDriver);
		} catch (FileNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
		
	}
	/**
	 * 获取连接
	 * @return
	 * @throws SQLException 
	 */
	public static Connection getConnection() throws SQLException{
		
		return (Connection) DriverManager.getConnection(url, user, password);
		
	}
	
	
	/**
	 * 如果是查(select)用这个
	 */
	public static void close(ResultSet rs,Connection conn,Statement stat){
		
		if(rs != null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		close(conn,stat);
	}
	/**
	 * 如果是sql的操作增删改用这个抛异常
	 * @param conn
	 * @param stat
	 */
	//先写异常加载<如果是增删改>
	public static void close(java.sql.Connection conn,Statement stat){
		
		if(stat!=null){
			try {
				stat.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
		if(conn!=null){
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
	}
}

上述就是一个简单的javaJDBC的工具包
接下来刚才提到了事务(回滚,提交,开启)的相关东西,一起来看下把事务了解一下
事务:不是一个实实在在存在的东西,如果一个包含多个业务的操作,被事务管理,这些事务要么同时成功,要么同时失败。
提交事务,失败后回滚,提交事务。
操作:1、开启事务:start transaction;======>事务就相当于上锁
2、回滚:rollback
3、提交:commit

SELECT @@autocommit ; 查看事务----1:代表自动提交 2:手动提交
一个DML(是默认自动提交)
而Oracle数据库就是手动提交的
事务一旦开启,就需要手动提交S
set @@autocommit = 0 ; —就修改了事务的默认提交方法

不提交事务,就不会有事务的永久性commit;

事务的四大特征:
1、原子性:是不可分割的最小操作单位。要么同时成功,要么同时失败
2、持久性:当事务提交或者回滚后,数据库会持久性的保存数据。
3、隔离性:多个事务之间相互独立,
4、一致性:表示事务操作前后,总数不改变。
二:事务的隔离性级别:----相当于并发的操作
概念:多个事务之间,相互独立。但是多个事务操作同一批数据,则会发生一些问题
设置不同的隔离级别,就会解决这些问题
问题:
1、脏读;(读脏数据),一个事务,读取到另一个事务没有提交的事务
2、不可重复度(虚读):在一同种事务中,两个读取到的数据不一样,
3、幻读:一个事务操作(DML)数据表中的所有记录,另一个事务添加一条数据,则第一个事务查询不到自己的修改
隔离级别:
1、read uncommitted:读未提交
产生的问题,脏读,不可重复读、幻读
2、read commited : 读以提交 (Oracle数据库默认)
产生的问题:不可重复读、幻读
3、repeatable read : 可重复度 (MYSQL数据库默认的)
产生的问题:幻读
4、serializable : 串行化 —可解决所有的问题
。注意:隔离级别从小到大安全性越来越高,但是效率越来越低

数据库设置级别:
selsect @@tx_isolation—查询
set global transaction isolation level (级别);-----修改
也就是说你在进行jdbc操作的时候,特别是类似于存取钱的场景,如果在取钱的过程中,事务中间发生异常中断,事务没有回滚,那你的钱岂不是不翼而飞了?所以在一般情况下都会加上事务的开启,回滚,提交的动作
这样才能保证事务执行的安全性。

**三:**还有就是数据库连接池的操作,简化JDBC的操作
Spring : jdbc —>技术:jdbc Template
概念:其实就是一个容器(集合),存放数据库连接的容器
系统中初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户
访问完后,归还给容器
好处:节约资源,用户访问高效
DataSource(interface接口) :获取连接:getConnection( );
归还连接池:如果连接对象Connection是从连接池中获取的,那么
close();方法不会再关闭连接,而时归还
由数据库厂商实现:
1、c3p0 : 数据库连接池CombooledDataSource
2、Druid : 数据库连接池(阿里巴巴)

这里以Druid为例— 需要导入Druid的jar包
书写配置文件Druid.properties,内容包括最大连接数,最大线程数等待

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mydate
username=root
password=yl981120
initialSize=5 //初始化连接数
maxActive=10 //最大对象数
maxWait=3000 //最长等待时间(ms)

以及一个工具类

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSourceFactory;

//数据库连接池工具类----阿里Druid
public class jdbc_Utils {

	private static DataSource ds;
	
	static{
		
		try {
			//加载配置文件 -- 书写配置文件
			//包括url,
			Properties pro = new Properties();
			pro.load(jdbc_Utils.class.getClassLoader().getResourceAsStream("druid.properties"));
			//2 获取dataSource
			ds = DruidDataSourceFactory.createDataSource(pro);
			
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		} catch (Exception e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		
	}
	/*
	 * 获取连接池对象
	 */
	public static Connection getConnection() throws SQLException{
		return ds.getConnection();
	}
	
	//单例化设计,提供对外的静态获取对象方法
	public static DataSource getDataSource(){
		return ds;
	}
	/*
	 * 关闭流,sql执行对象,和链接对象
	 */
	public static void close(Statement stat ,Connection conn ){
		
		if(stat != null){
			try {
				stat.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		if(conn != null){
			try {
				conn.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		
	}
	//关闭资源
public static void close(ResultSet res,Statement stat ,Connection conn ){
		
		if(res != null){
			try {
				res.close();
			} catch (SQLException e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}
		close(stat,conn);

}
}

对比于上述的代码,现在的代码两就少了好多,来一个测试类

import org.springframework.jdbc.core.JdbcTemplate;

import TEXT01.jdbc_Utils;

/**
 * 
 * <p>Title:初见Spring.java</p>
 * <p>Description:duijdbc的进一步简化</p>
 * @author 會飛的魚
 *
 */
public class Dome01 {

	public static void main(String[] args) {
		
		//首先先导入jar包
		//创建jdbcTemplate---前提是接受DataSource
		JdbcTemplate template = new JdbcTemplate(jdbc_Utils.getDataSource());
		//调用方法:
		String sql = "update user_test set count = ? where id = ?";
		int n = template.update(sql,5000,2);//这里方法简洁,可直接获取
		System.out.println(n);
		//这个方法内部封装有归还连接池对像的操作
		
	}	
}

我对jdbc的理解有限,欢迎指教!

发布了11 篇原创文章 · 获赞 8 · 访问量 1589

猜你喜欢

转载自blog.csdn.net/weixin_44627238/article/details/90714527