Web阶段--JDBC基础知识总结

本文详细介绍了JDBC的基础知识,包括JDBC的概念、组成、常用JAR包以及环境搭建。接着讲解了编写第一个JDBC程序的六个步骤,带参SQL命令的执行,以及如何创建工具类JdbcUtil提高效率。此外,还涉及到了O-R映射、JDBC的增删改查模板、DAO数据访问对象、Service业务层的事务控制,视图层的作用和代码结构,以及连接池的原理和应用。最后,讨论了JDBC中日期值的处理方法。
摘要由CSDN通过智能技术生成

一、Web–什么是JDBC?

1.概念
是java程序连接数据的桥梁,通过jdbc驱动java程序可以操作访问数据库软件
2.JDBC的组成
由两种:
	1.接口:是由Sun公司定义在JDK中,提供(java.sql包和javax.sql包)给程序员开发使用
	2.实现类:由数据库厂商以JAR包的形式商提供
3.JDBC中常用的JAR包
有两种:
	1.ojdbc5.jar---jdk5和jdk6的环境中使用
	2.ojdbc6.jar---jdk7和jdk8的环境中使用
4.环境的搭建(导入JAR包)
两种方式:
	1.普通文本编辑工具:将JAR包所在的路径配置到CLASSPATH环境变量中。例如:CLASSPATH=.;D:\文件目录名\jar包名
	2.使用集成开发工具(例如:MyEclipse或者Eclipse):
		项目配置JAR包:
			第一步:在项目路径下新建一个lib文件夹,将JAR包到文件夹下
			第二步:右键选中导入的JAR包,选择build path选项,选择add to build path
		项目配置数据库操作窗口:
			第一步:选中菜单window-->show view-->others-->在搜索框中搜索db browser并选中
			第二步:找到db browser窗口,并右击MyEclipse Derby-->选择new-->在弹出界面中填写name(随意起)、url(数据库地址)、 数据库登录的账号和密码-->点击Add JARs引入jar包的路径-->Save PassWord(保存密码)可选可不选,如果不选,下次要重新输入密码-->最后点击完成
			第三步:在项目的src目录下新建一个sql包,里面放入sql文件

二、第一个JDBC程序(六个步骤)

1.注册Driver(加载驱动类)
Class.forName("驱动类的全类名")
	eg:Oracle数据库驱动类全类名:oracle.jdbc.OracleDriver
	注意:一个JDBC程序中可以注册多个Driver驱动类
2.获取数据库链接
代码:Connection conn = DriverManager.getConnection( 地址,用户名,密码);
注意: 实际负责建立数据库连接的程序是Driver实现类,DriverManager只是一个工具类
3.创建Statement(Sql命令的传送工具)
代码:  Statement  stm  = conn.createStatement();
4.执行sql命令(传送)
三种方法:
	1)executeUpdate(sql) : 用来执行insert update delete命令,返回int值(命令影响了几行数据)
	2)executeQuery(sql) : 用来执行select命令,返回值为ResultSet(包含了查询结果)
	3execute(sql) : 可以用来执行所有的sql命令,返回boolean值(标志是否有结果集返回)
5.处理结果集
ResultSet接口中提供了next()、getXxx()等方法,处理结果。
注意:一般用于查询数据库中的所有数据(即使用select语句查询)时使用,如果不select语句查询,则一般不处理结果。增删改看情况需不需要处理结果集。
6.释放资源
释放资源事按照生成顺序反向释放。eg:ResultSet引用.close-->Statement引用.close-->Connection引用.close

三、带参sql命令的执行

1.使用Statement执行带参sql
缺点:
	1.命令字符串的拼接比较繁琐
	2.sql注入
2.使用PreparedStatement执行带参的sql
1.PreparedStatement 是Statement的子接口,可以解决sql注入(字符串拼接)的问题
2.三个步骤:
	I:创建PreparedStatement对象( 需要直接指定执行的sql ) 
		代码:PreparedStatement pstm = conn.prepareStatement(sql);
			注意:PreparedStatement允许指定 “半成品” 的sql , 允许在sql命令中使用?作为占位符,来代替暂时不方便给定的值
	2.PreparedStatement提供了一系列的setXxx()方法为?设置值
    	eg:	PreparedStatement的引用.setInt( ?的下标,?的值 )/setString()/setDouble() /setDate()
    3.执行sql通用的两种方法:
    	PreparedStatement的引用.executeQuery()
    	PreparedStatement的引用.executeUpdate()  

四、编写工具类JdbcUtil

1.基本原则
java代码复用的基本原则:
	1.方法封装:
		经常反复出现在程序中的一段功能代码(冗余代码),通过方法封装可以提高代码复用性
	2.尽量减少“硬编码” : 
		将可能会发生改变的值直接定义在java程序中(值的改变会导致程序的重新编译)将变化的值定义在“配置文件”
2.配置文件 (properties文件)
1.概念:
	用来保存程序运行过程中所需要的一些数据,文件通常用properties/xml结尾
2.properties文件内容格式:
	 每一行定义一个值,一行由两部分name和value,中间等号或者空格连接
3.集合类Properties :
	 是Hashtable的子类,主键和值默认都是String类型,处理properties文件的工具,并提供了load( 字节输入流 )函数来读取保存配置文件内容
3.提高工具类的效率
1.将读取文件的代码从函数里移植到静态代码块中 static{ .... }
2.改变流的获取方式:
	由
		InputStream is = new FileInputStream("bin/jdbc.properties");
	变成          
		InputStream is = 类对象.getResourceAsStream(" 路径从/,/代表src目录 ");

五、O-R mapping映射

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Uk89yHDT-1589167148846)(C:\Users\ASUS\AppData\Local\Temp\1557707605524.png)]

1. 实体类作用:
用来封装数据库数据,属性名最好与表中字段名保持一致
2. 函数的返回值:
正常情况必须返回指定类型的值,非正常情况,异常对象可以作为一种返回值形式来表示

六、JDBC的增删改查模板

1.工具类JdbcUtil
public class JdbcUtil {
	private static DataSource ds = null;
	private static Properties prop = new Properties();
	private static final ThreadLocal<Connection> tol = new ThreadLocal<Connection>();
	static{
		try {
			InputStream is = JdbcUtil.class.getResourceAsStream("/cn/Jdbc/Tel_Book/conf/jdbc.properties");
			prop.load(is);  // 文件所有数据被保存在map里
			ds = BasicDataSourceFactory.createDataSource(prop);
			Class.forName( prop.getProperty("driverClassName") );
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static Connection getConnection() throws Exception{
		Connection conn = tol.get();
		if( conn== null ){
			  conn = ds.getConnection();
			   tol.set(conn);
			}
			return conn;
	}
	public static void close(ResultSet rs,Statement stm ){
		if(rs!=null) try{rs.close();}catch(Exception e){}
		if(stm!=null) try{stm.close();}catch(Exception e){}
	}
	public static void close( Connection conn){
		if(conn!=null) try{conn.close(); tol.remove(); }catch(Exception e){}
	}
}
2.增
public void insert(实体类名(Person) 实体类引用(person)){
    Connection conn = null;
		PreparedStatement pstm = null;
		try {
			conn = JdbcUtil.getConnection();
			String sql = "insert into person values(person_seq.nextval,?,?,?,?,?)";
			pstm = conn.prepareStatement(sql);
			pstm.setString(1, person.getName());
			pstm.setString(2, person.getMobile());
			pstm.setString(3, person.getTelphone());
			pstm.setString(4, person.getEmail());
			pstm.setString(5, person.getCity());
			pstm.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException("系统忙,请稍后再试");
		}finally{
			JdbcUtil.close(null, pstm);
		}
}
3.删
public void deletePerson(参数为主键(Integer id)) {
	Connection conn = null;
	PreparedStatement pstm = null;
	try{
		conn = JdbcUtil.getConnection();
		String sql="delete from person where id=?";
		pstm = conn.prepareStatement(sql);
		pstm.setInt(1, id);
		pstm.executeUpdate();
	}catch(Exception e){
		e.printStackTrace();
		throw new RuntimeException("系统忙,请稍后再试");
	}finally{
		JdbcUtil.close(null, pstm);
	}
}
4.改
public void updatePerson(Person person) {
		  	Connection conn = null;
			PreparedStatement pstm = null;
			try{
				conn = JdbcUtil.getConnection();
				String sql="update person set name=?,mobile=?,telphone=?,email=?,city=? where id=?";
				pstm = conn.prepareStatement(sql);
				pstm.setString(1, person.getName());
				pstm.setString(2, person.getMobile());
				pstm.setString(3, person.getTelphone());
				pstm.setString(4, person.getEmail());
				pstm.setString(5, person.getCity());
				pstm.setInt(6, person.getId());
				pstm.executeUpdate();
			}catch(Exception e){
				e.printStackTrace();
				throw new RuntimeException("系统忙,请稍后再试");
			}finally{
				JdbcUtil.close(null, pstm);
			}
	}
5.查
查一条数据案列:
	public Person QueryPersonById(Integer id) {
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		Person person = null;
		try{
			conn = JdbcUtil.getConnection();
			String sql = "select * from person where id=?";
			pstm = conn.prepareStatement(sql);
			pstm.setInt(1,id);
			rs = pstm.executeQuery();
			if(rs.next()){
				Integer cardId = rs.getInt("id");
				String name = rs.getString("name");
				String mobile = rs.getString("mobile");
				String telphone = rs.getString("telphone");
				String email = rs.getString("email");
				String city = rs.getString("city");
				person= new Person(cardId, name, mobile, telphone, email, city);
			}
	        return person ;
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("系统忙请稍后再试");
		}finally{
			JdbcUtil.close(rs, pstm);
		}   
	}
查所有数据案例:
	public List<Person> queryAllPersons() {
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		try{
			conn = JdbcUtil.getConnection();
			String sql = "select * from person";
			pstm = conn.prepareStatement(sql);
			rs = pstm.executeQuery();
			List<Person> list = new ArrayList<Person>();
			while(rs.next()){
				Integer cardId = rs.getInt("id");
				String name = rs.getString("name");
				String mobile = rs.getString("mobile");
				String telphone = rs.getString("telphone");
				String email = rs.getString("email");
				String city = rs.getString("city");
				Person person= new Person(cardId, name, mobile, telphone, email, city);
			    list.add(person);
			}
			return list;
			
		}catch(Exception e){
			e.printStackTrace();
			throw new RuntimeException("系统忙,请稍后再试");
		}finally{
			JdbcUtil.close(rs, pstm);
		}
}

7、DAO数据访问对象

1.作用
完成对数据库里一张表所有数据访问操作(增删改查)
2.命名规范
1) 为每一张表提供一个与之对应的DAO程序
2) 定义DAO接口,命名时  “表名+DAO"
3)为接口提供实现类,命名时 “接口名+Impl"
3.好处
对调用者屏蔽底层数据库的差异

8、Service( 业务层 )

1.作用
定义方法完成具体的业务需求
2.定义规则
1.每一个业务功能定义一个方法
2.程序的命名规范:
	接口:"表明+Service"
    实现类:"接口名+Impl"
3.JDBC中的事物控制
1. jdbc中默认的事务提交策略为 “一条命令提交一次”  --- 自动提交
2.手动提交 API
	I:conn.setAutoCommit(  boolean );    
		true--自动提交 false--手动提交   
				--- 一经设置,永久生效(在当前conn的生命周期中,一直有效)
	II: conn.commit();     conn.rollback(); 
3.代码结构
  try{
     conn.setAutoCommit(false);
   		/*业务代码....*/
     conn.commit();
  }catch(Exception e){
      conn.rollback();
      throw new RuntimeException(....)}
4.给service程序添加事务控制代码
1. 目标:为了事务控制,需要在一个事务内部的不同代码间,使用一个连接对象
2. 解决:使用参数传递的方式解决(将service层的连接对象传给dao层函数)
5.使用ThreadLocal对象解决service层事务控制问题
1.ThreadLocal --- 线程局部变量
	 一个ThreadLocal对象可以为每一个线程保存一个独占数据
2.使用API
	I: 创建对象  
		ThreadLocal<独占数据的类型>  tol = new ThreadLocal<....> ();
	II:存数据   
    	tol.set(  数据  );
	III:取数据 
    	tol.get() ---> 独占数据
     VI:解除与当前线程的绑定  
     	tol.remove()
3.作用
	I:wei一个线程锁定一个数据,使得我们在线程的任意代码组成部分里都可以获取到这个数据(一个数据)
	II:为不同的线程锁定不同的数据
4.使用ThreadLocal改写JdbcUtil
	案例:
	private static final ThreadLocal<Connection> tol = new ThreadLocal<>();
	public static Connection getConnection() throws Exception {
		// 从配置文件中获取values值链接数据库
		Connection conn = tol.get();
		if (conn == null) {
			conn = DriverManager.getConnection(prop.getProperty("url"),
					prop.getProperty("username"), prop.getProperty("password"));
			tol.set(conn);
		}
		return conn;
5.理论上,conn应该在线程结束时被关闭,实际开发中,线程结束位置不固定,一般会在事务结束时就关闭连接,关闭同时切记解除conn和当前线程的绑定关系( dao层函数千万不能关闭连接 )	
6.业务层开发步骤
	I:获取数据库连接,并且控制提交策略为手动提交
	II:完成业务功能( 数据校验 , 数据库的访问操作 --- 需要dao的对象 )
	III:提交 或者 回滚
	VI:释放资源,解绑线程

9、View( 视图层 , 显示逻辑 , 界面)

1.作用
提供一个与用户交互的通道
2.常见代码
1.数据采集
2.调用service层函数完成用户业务需求
3.展示结果数据(正常的结果, 异常对象 )
3.现有程序结构
测试类--视图层--业务层--数据访问层--数据库
4.项目结构
  项目包名:
  |-- src
  	|-- com.baizhi.telbook
  		|-- util包         存放工具类的位置
  		|-- conf包         存放项目中的配置文件
  		|-- sql包          存放sql文件(常规sql命令--建表语句)
  		|-- entity包       存放实体类
  		|-- dao包          存放与dao相关程序
  			|-- dao interface
  			|-- impl包       存放dao接口的实现类
  		|-- service包      存放service相关程序
  			|-- service接口
  			|-- impl包       存放service接口的实现类
  		|-- view包         存放view程序
  		|-- test包         存放测试程序
  		|-- excp包         存放业务异常程序(自定义异常类型)
  |-- lib    项目开发过程中需要使用的jar包

10.连接池

1.原理
提前建立好一组数据库连接提供给用户循环使用
2.连接池里的连接与普通连接的区别
1.boolean标志位 : 标志连接池里的连接状态(空闲,繁忙)
2.conn的close方法被改写,不是真正断开连接,而是修改标志位,将连接还给连接池
3.使用dbcp连接池软件
1.入相关jar包(3个)--> lib --> add to build path
	commons-collections-3.2.1.jar
	commons-dbcp-1.4.jar
	commons-pool-1.5.4.jar
2.引入配置文件(dbcp.properties) --> src/conf/.....
    driverClassName=oracle.jdbc.OracleDriver
	url=jdbc:oracle:thin:@localhost:1521:xe
	username=hr
	password=hr
	initialSize=10
	maxActive=50
	maxIdle=20
	minIdle=5
	maxWait=60000
	connectionProperties=useUnicode=true;characterEncoding=utf-8
	defaultAutoCommit=true
	defaultTransactionIsolation=READ_COMMITTED
3.修改JdbcUtil程序 ( 改变连接的获取方式)
	public class JdbcUtil {
	private static DataSource ds = null;
	private static Properties prop = new Properties();
	private static final ThreadLocal<Connection> tol = new ThreadLocal<Connection>();
	static{
		try {
			InputStream is = JdbcUtil.class.getResourceAsStream("/cn/Jdbc/Tel_Book/conf/jdbc.properties");
			prop.load(is);  // 文件所有数据被保存在map里
			ds = BasicDataSourceFactory.createDataSource(prop);
			Class.forName( prop.getProperty("driverClassName") );
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	public static Connection getConnection() throws Exception{
		Connection conn = tol.get();
		if( conn== null ){
			  conn = ds.getConnection();
			   tol.set(conn);
			}
			return conn;
	}
	public static void close(ResultSet rs,Statement stm ){
		if(rs!=null) try{rs.close();}catch(Exception e){}
		if(stm!=null) try{stm.close();}catch(Exception e){}
	}
	public static void close( Connection conn){
		if(conn!=null) try{conn.close(); tol.remove(); }catch(Exception e){}
	}
}

11.jdbc里日期值的处理

1.ava.util.Date(java程序中的日期)转化成java.sql.Date(数据库中的日期)需要借助getTime()方法
	案例:
		java.util.Date time1  = new java.util.Date();
		long time = time1.getTime();
		java.sql.Date time2 = new java.sql.Date(time);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值