📄 day02.txt
字号:
JDBC_day02 langna 2007-9-7 星期五
wanghg@tarena.com.cn
回顾:
con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
"xjh0704", "xjh0704");
另外一种注册方法:
Properties p = new Properties();
p.setProperty("user", "xjhsd0704");
p.setProperty("password", "xjhsd0704");
Connection con = d.connect("jdbc:oracle:thin:@192.168.0.20:1521:tarena", p);
另外一种方式:
jdbc:oracle:thin:xjh0704/xjh0704@192.168.0.20:1521:tarena
java类型是静态类型,编译器检查类型;字符串只检查类型,不检查内容;
注意:
同一个statement 得到结果集之后没有去遍历结果集,
而是做了其他操作(插入或修改)的话,结果集就不能用了,为空了;
先做插入或修改操作,然后再得到结果集去遍历,不会有什么问题;
一、设计
封装:避免重复的代码;
抽象:将具体的细节、量抽出来,把逻辑,形式留下;
依赖倒转:原来的设计是写具体的类,依赖倒转就是将具体的抽取出来;
写一个工具类:JdbcUtil ,方法都设成静态方法;
加载驱动放到初始化代码块里;只加载一次就行;
public class JdbcUtil {
//静态代码块加载驱动;
static{
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//得到数据库连接
public static Connection getConnection(){
Connection con =null;
try {
con = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.201:1521:tarena",
"xjh0704", "xjh0704");
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
//释放数据库资源
public static void close(ResultSet rs,Statement stmt,Connection con){
if(rs!=null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stmt!=null){
try{
stmt.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(con!=null){
try{
con.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
//重载一个关闭方法
public static void close(Object o){
try{
if(o instanceof ResultSet){
((ResultSet)o).close();
}else if(o instanceof Statement){
((Statement)o).close();
}else if(o instanceof Connection){
((Connection)o).close();
}
}catch(SQLException e){
e.printStackTrace();
}
}
}
二、PreparedStatement概述;预编译的
1、概括:与Statement比较
效率高;
清晰(类型);
结构:1、SQL参数化(Statement中SQL是纯字符串的)
2、SQL预编译
Statement 将 SQL 送到数据库 ---> 编译---> 运行---> 再返回给应用程序
有1000条记录的话就送1000次;编译1000次,运行1000次;
相当于sqlplus ,一条命令执行一次;
Preparement "insert into t_test values(?,?)" //占位符;
---> 发到数据库可以编译但不能运行---> 等参数传过来再运行;
有1000条记录,编译一次,运行1000次;
************************************
Statement stmt=null;
stmt = con.createStatement();
sql="insert into t_test values(1,'tony')"
//直接送sql语句;象一个表达式
stmt.executeUpdate(sql);
***********************************
PreraredStatement ps=null;//象方法一样
sql="insert into t_test values(?,?)");
//1、准备一条sql语句
ps=con.prepareStatement(sql);
//2、往ps对象设置参数值;检查类型是否兼容;
ps.setInt(1,8);
ps.setString(2,"Tony");
//3、送到数据库执行
ps.executeUpdate();
2、SQL:同构;sql语句除了参数不同其他都一样;
异构:除了参数不同,其他地方有不同的就是异构的;
比如 insert 和 update;或者表不同也是异构的;
不管同构的还是异构的都用 PreparedStatement
同构的更能发挥它的优势;
select 一般是异构的,但是执行一次返回一个结果集就行了;
update/insert 一般都是同构的,用PreparedStatement;
对客户端来说并没有减少工作量,但是对数据库来说减少了工作量;
三、元数据:
1、 ResultSetMetaData
元数据是用来描述数据的数据,ResultSetMetaData就是来描述结果集的
列的类型和属性信息,比如可以通过它得到结果集的列数,列名等。
具体可在API中查阅java.sql.ResultSetMetaData。
ResultSetMetaData对象可以通过ResultSet对象的getMetaData()来得到。
ResultSetMetaData对象有以下三个方法比较常用:
getColumnCount():获得实际列数
getColumnName(int colnum):获得指定列的列名
getColumnType(int colnum):获得指定列的数据类型(Types里面的类型,存放的是整数)
getColumnTypeName(); 数据库的类型
JDBC API :JDBC --- JAVA --- 数据库类型
类型对照表:String 范围
//1、获取结果集元数据
ResultSetMetaData md=rs.getMetaData();
//2、从结果集元数据中读取字段个数
int column=md.getColumnCount();
//3、利用元数据读取字段名和字段值
for(int i=1;i<=column;i++) {
System.out.println(md.getColumnName(i)+"\t");
}
2、数据库元数据:
DatabaseMetaData
getURL(),获得连接数据库的URL
getDatabaseProductName() 获得数据库产品的名称
getDriverVersion() 获得JDBC驱动程序的String形式的版本号
getUserName() 获得数据库用户名。
ResultSet getTables(参数)获得数据库中该用户的所有表
参数:
catalog : null ,
schema : 用户名;如"OPENLAB"
table_name:表名,可以用通配符"%TEST"
types: 类型;是String[] 格式的;候选类型是:"TABLE"、"VIEW"、"SYSTEM TABLE"
//1获取数据库元数据
DatabaseMetaData dbmd=con.getMetaData();
//2读取特定表信息;获得结果集
String[] types=new String[1];
types[0]="TABLE";//必须是大写
rs=dbmd.getTables(null, "OPENLAB","%", types);
//3遍历结果集,输出
四、事务Transaction
1、原子操作:不可分割的操作;
atom: 原子操作,代表不可再分操作;
2、事务:
事务就是将一组数据库操作变为原子操作;事务是达成原子操作的一个途径;
事务是针对原子操作的,要求原子操作不可再分,要求原子操作必须同时成功同时失败。
事务是捆绑的原子操作的边界。
事务由数据库服务器来实现的,我们只是使用它;
我们写的代码,数据库都将其设为自动提交;插入10条记录就commit 10次;
使用事务的语法:
1) 关闭自动提交(开始一个用户的事务);
con.setAutoCommite(false); 打开事务就要关闭自动提交。
如果不关掉,则是数据库的事务,将每次提交作为一个事务;
不用事务时要把setAutoCommite(true);
2)正常的进行若干"相关"的数据库操作;
3)如果一切正常,用户可以选择提交 con.commit();
也可以选择回滚 con.rollback();
4)任何一个操作失败,就回滚;在catch语句块中con.rollback();
在提交和回滚时旧的事务结束,新的事务开始;
声明一下:
从我最近对大家的观察,发现有相当一部分同学上课并没有好好去记笔记;
这样对记忆还有学习的影响很不好,所以以后我不再给大家发笔记了,
希望大家自己上课好好听课,好好记笔记。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -