hadoop学习序曲之mysql基础篇--mysql之JDBC

JDBC全称为:Java DataBase Connectivity(java数据库连接)。 SUN公司为了简化、统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC。
1: 编写JDBC程序
     编程从student表中读取数据,并打印在命令行窗口中。     
     一、搭建实验环境 :    
         1、在mysql中创建一个库,并创建student表和插入表的数据。    
         2、新建一个Java工程,并导入数据驱动。
     二、编写程序,在程序中加载数据库驱动     DriverManager. registerDriver(Driver driver) 
     三、建立连接(Connection)     Connection conn = DriverManager.getConnection(url,user,pass); 
     四、创建用于向数据库发送SQL的Statement对象,并发送sql     Statement st = conn.createStatement();     ResultSet rs = st.executeQuery(sql); 
    五、从代表结果集的ResultSet中取出数据,打印到命令行窗口
    六、断开与数据库的连接,并释放相关资源 

2:JDBC编程步骤
 装载驱动程序 
 建立连接 
 操作数据 
 释放资源 

3:JDBC访问数据库的流程
通过DriverManager加载驱动程序driver; 
通过DriverManager类获得表示数据库连接的Connection类对象; 
通过Connection对象绑定要执行的语句,生成Statement类对象; 
执行SQL语句,接收执行结果集ResultSet; 
可选的对结果集ResultSet类对象的处理; 
必要的关闭ResultSet、Statement和Connection 

4: 程序详解—DriverManager
  Jdbc程序中的DriverManager用于加载驱动,并创建与数据库的链接,这个API的常用方法:    DriverManager.registerDriver(new Driver())    DriverManager.getConnection(url, user, password), 注意:在实际开发中并不推荐采用registerDriver方法注册驱动。
原因有二:
一、查看Driver的源代码可以看到,如果采用此种方式,会导致驱动程序注册两次,也就是在内存中会有两个Driver对象。 
二、程序依赖mysql的api,脱离mysql的jar包,程序将无法编译,将来程序切换底层数据库将会非常麻烦。 推荐方式:Class.forName(“com.mysql.jdbc.Driver”);采用此种方式不会导致驱动对象在内存中重复出现,并且采用此种方式,程序仅仅只需要一个字符串,不需要依赖具体的驱动,使程序的灵活性更高。 同样,在开发中也不建议采用具体的驱动类型指向getConnection方法返回的connection对象。

5:数据库URL
URL用于标识数据库的位置,程序员通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:    jdbc:mysql://  localhost:3306/test ?key=value
常用数据库URL地址的写法: Oracle写法:    jdbc:oracle:thin:@localhost:1521:sid MySql写法:    jdbc:mysql://localhost:3306/sid Mysql的url地址的简写形式: jdbc:mysql:///sid 常用属性:useUnicode=true&characterEncoding=UTF-8

6:Connection
Jdbc程序中的Connection,它用于代表数据库的链接,Collection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过connection对象完成的,这个对象的常用方法: createStatement():创建向数据库发送sql的statement对象 prepareStatement(sql) :创建向数据库发送预编译sql的PrepareSatement对象 prepareCall(sql):创建执行存储过程的callableStatement对象。
 --- 存储过程  setAutoCommit(boolean autoCommit):设置事务是否自动提交。 
                      commit() :在链接上提交事务。
 ---与事务相关!! rollback() :在此链接上回滚事务。

7: Statement  -- 一次操作
  Jdbc程序中的Statement对象用于向数据库发送SQL语句, Statement对象常用方法: executeQuery(String sql) :用于向数据发送查询语句。 executeUpdate(String sql):用于向数据库发送insert、update或delete语句 execute(String sql):用于向数据库发送任意sql语句 
批处理操作
 addBatch(String sql) :把多条sql语句放到一个批处理中。 
executeBatch():向数据库发送一批sql语句执行。

8: ResultSet
  Jdbc程序中的ResultSet用于代表Sql语句的执行结果。Resultset封装执行结果时,采用的类似于表格的方式。ResultSet 对象维护了一个指向表格数据行的游标cursor,初始的时候,游标在第一行之前,调用ResultSet.next() 方法,可以使游标指向具体的数据行,进而调用方法获取该行的数据。 ResultSet既然用于封装执行结果的,所以该对象提供的大部分方法都是用于获取数据的get方法: 获取任意类型的数据 getObject(int index)
  getObject(string columnName) 获取指定类型的数据,例如: getString(int index) getString(String columnName) 

9:遍历查询结果 


10: CRUD操作-create
  Statement st = conn.createStatement();     
 String sql = "insert into student(….) values(…..) ";    
 int num = st.executeUpdate(sql);    
 if(num>0){         
 System.out.println("插入成功!!!");  
  }
 
11: CRUD操作-updata
Statement st = conn.createStatement();    
 String sql = “update student set name=‘’ where name=‘’";     
 int num = st.executeUpdate(sql);    
 if(num>0){      
   System.out.println(“修改成功!!!");    
 } 

12: CRUD操作-delete
  Statement st = conn.createStatement();    
 String sql = “delete from student where id=1;    
  int num = st.executeUpdate(sql);   
  if(num>0){        
 System.out.println(“删除成功!!!");     
}

13: CRUD操作-read
Statement st = conn.createStatement();
String sql = “select * from student where id=1; 
ResultSet rs = st.executeQuery(sql);     
while(rs.next()){         
//根据获取列的数据类型,分别调用rs的相应方法         //映射到java对象中   
  } 

14: PreparedStatement
PreparedStatement是Statement的子接口,它的实例对象可以通过调用Connection.preparedStatement(sql)方法获得,相对于Statement对象而言: PreperedStatement:可以避免SQL注入的问题。 Statement会使数据库频繁编译SQL,可能造成数据库缓冲区溢出。PreparedStatement 可对SQL进行预编译,从而提高数据库的执行效率。 并且PreperedStatement对于sql中的参数,允许使用占位符的形式进行替换,简化sql语句的编写。

15: ResultSet 滚动结果集
  ResultSet还提供了对结果集进行滚动和更新的方法 Statement stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
 next():移动到下一行
 previous():移动到前一行 
absolute(int row):移动到指定行 
beforeFirst():移动resultSet的最前面 
afterLast() :移动到resultSet的最后面 
updateRow() :更新行数据
结果集类型 ResultSet.TYPE_FORWARD_ONLY 只能向前,只能调用next 不能向回滚动 ResultSet.TYPE_SCROLL_INSENSITIVE 支持结果集向回滚动,不能查看修改结果 ResultSet.TYPE_SCROLL_SENSITIVE  支持结果集向回滚动,查看修改结果 
结果集并发策略  
ResultSet.CONCUR_READ_ONLY 只读 
 ResultSet.CONCUR_UPDATABLE 支持修改  
常见三种组合 
ResultSet.TYPE_FORWARD_ONLY 和 ResultSet.CONCUR_READ_ONLY  (默认) 只读不支持向回滚动 ResultSet.TYPE_SCROLL_INSENSITIVE 和 ResultSet.CONCUR_READ_ONLY  只读,支持向回滚动 ResultSet.TYPE_SCROLL_SENSITIVE 和 ResultSet.CONCUR_UPDATABLE 支持向回滚动,支持对数据修改

16: 释放资源
Jdbc程序运行完后,切记要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet, Statement和Connection对象。
特别是Connection对象,它是非常稀有的资源,用完后必须马上释放,如果Connection不能及时、正确的关闭,极易导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
为确保资源释放代码能运行,资源释放代码也一定要放在finally语句中。
工具类提取。
 
17: 事务
事务的概念 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功。 例如:A——B转帐,对应于如下两条sql语句 
update from account set money=money-100 where name=‘a’;  
update from account set money=money+100 where name=‘b’; 
数据库默认事务是自动提交的,也就是发一条sql它就执行一条。如果想多条sql放在一个事务中执行,则需要使用如下语句。
数据库开启事务命令 start transaction  开启事务 Rollback  回滚事务 Commit   提交事务 
当Jdbc程序向数据库获得一个Connection对象时,默认情况下这个Connection对象会自动向数据库提交在它上面发送的SQL语句。若想关闭这种默认提交方式,让多条SQL在一个事务中执行,可使用下列语句: 
JDBC控制事务语句 
Connection.setAutoCommit(false); //  相当于start transaction Connection.rollback();  //rollback Connection.commit();  //commit 
设置事务回滚点 
Savepoint sp = conn.setSavepoint(); Conn.rollback(sp); Conn.commit();   //回滚后必须要提交 

事务的特性(ACID) 
原子性(Atomicity) 原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。  一致性(Consistency) 事务前后数据的完整性必须保持一致。 
隔离性(Isolation) 事务的隔离性是指多个用户并发访问数据库时,一个用户的事务不能被其它用户的事务所干扰,多个并发事务之间数据要相互隔离。 
持久性(Durability) 持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响。 

事务的隔离级别 
多个线程开启各自事务操作数据库中数据时,数据库系统要负责隔离操作,以保证各个线程在获取数据时的准确性。 如果不考虑隔离性,可能会引发如下问题

    脏读: 指一个事务读取了另外一个事务未提交的数据。     这是非常危险的,假设A向B转帐100元,对应sql语        句如下所示     
    1.update account set money=money+100 while name=‘b’;       
    2.update account set money=money-100 while name=‘a’;          
    当第1条sql执行完,第2条还没执行(A未提交时),如果此时B查询自己的帐户,就会发现自己多了100元钱。如果A等B走后再回滚,B就会损失100元。

     不可重复读: 在一个事务内读取表中的某一行数据,多次读取结果不同。     例如银行想查询A帐户余额,第一次查询A帐户为200元,此时A向帐户存了100元并提交了,银行接着又进行了一次查询,此时A帐户为300元了。银行两次查询不一致,可能就会很困惑,不知道哪次查询是准的。 和脏读的区别是,脏读是读取前一事务未提交的脏数据,不可重复读是重新读取了前一事务已提交的数据。 很多人认为这种情况就对了,无须困惑,当然是后面的为准。我们可以考虑这样一种情况,比如银行程序需要将查询结果分别输出到电脑屏幕和写到文件中,结果在一个事务中针对输出的目的地,进行的两次查询不一致,导致文件和屏幕中的结果不一致,银行工作人员就不知道以哪个为准了。 

    虚读(幻读):是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致。 如丙存款100元未提交,这时银行做报表统计account表中所有用户的总额为500元,然后丙提交了,这时银行再统计发现帐户为600元了,造成虚读同样会使银行不知所措,到底以哪个为准。
  
数据库共定义了四种隔离级别:
 Serializable:可避免脏读、不可重复读、虚读情况的发生。
(串行化) Repeatable read:可避免脏读、不可重复读情况的发生。
(可重复读)不可以避免虚读 Read committed:可避免脏读情况发生
(读已提交) Read uncommitted:最低级别,以上情况均无法保证。
(读未提交) set  session transaction isolation level 
设置事务隔离级别
     select @@tx_isolation    查询当前事务隔离级别 
18: 数据库连接池编写原理分析
  编写连接池需实现javax.sql.DataSource接口。DataSource接口中定义了两个重载的getConnection方法: Connection getConnection()  Connection getConnection(String username, String password)  

实现DataSource接口,并实现连接池功能的步骤: 
在DataSource构造函数中批量创建与数据库的连接,并把创建的连接保存到一个集合对象中 实现getConnection方法,让getConnection方法每次调用时,从集合对象中取一个Connection返回给用户。 
当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到连接池的集合对象中,而不要把conn还给数据库。

扩展Connection的close方法 在关闭数据库连接时,将connection存回连接池中,而并非真正的关闭

19: 其他数据库相关
 索引,使用索引可快速访问数据库表中的特定信息 为什么用索引? 书本的目录相当于索引,表的数据也需要这样一个目录,这就 是索引。用来加快查询速度。
  数据库索引 
1.添加PRIMARY KEY(主键索引)  mysql>ALTER TABLE `table_name` ADD PRIMARY KEY ( `column` )  
2.添加UNIQUE(唯一索引)  mysql>ALTER TABLE `table_name` ADD UNIQUE ( `column` ) 
 3.添加INDEX(普通索引)  mysql>ALTER TABLE `table_name` ADD INDEX index_name( `column` )  
4.添加FULLTEXT(全文索引)  mysql>ALTER TABLE `table_name` ADD FULLTEXT ( `column`)  
5.添加多列索引  mysql>ALTER TABLE `table_name` ADD INDEX index_name ( `column1`, `column2`, `column3` )
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值