1.首先我会问自己?
为什么我需要学习JDBC?
因为JDBC是java语言用来连接数据库进行操作的一种API机制,而如今的网站后台,Android的APP差不多都是使用java开发的,如果我知道了其中的任何操作,例如Oracle的基本的查询,更新,删除,添加,事务,锁、、、等等操作,那么再加上脚本语言Python,我就可以做教务管理系统,相当于.Net的形式。
江山如此多娇,使得无数英雄尽折腰!
2.我该如何学习?
学习目的明确了,我问自己如何去学习???
我绝对不相信老师教给我的那些Oracle访问机制,代码那么少,安全性肯定不高,是个人都会找出破解的方法,我一向很看重安全方面,还是需要找找网上的源代码读一读,看一看,这是个循序渐进的过程,我需要的是坚持,攻破俩不误,达到国内顶尖的水平再说。
so~ 先把基础搞好,然后向深层的技术进军。
我分块讲述JDBC的各个基础的操作。
- 建立连接 @
- 更新操作 @
- 删除操作 @
- 添加操作 @
- 查询操作 @
I:数据库的准备
1.配置文件 1.在项目下的src文件下创建一个以properties为后缀的文件,例如db.properties driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl user=scott password=a 然后在任意下文件夹创建一个MyProperties.java文件 以下是代码部分:::::::::::::::::::::::::::::::::: package JDBC; import java.io.IOException; import java.io.InputStream; import java.util.Properties; /** * 单例模式:可以保证系统中一个类只有一个实例并且这个实例容易被外界调用。好处就是节省系统的资源 **如果希望系统中的对象只有一个,这个时候你可以选择用单例*/ public class MyProperties extends Properties{ private static MyProperties mypro=null; /*对外提供的实例*/ private MyProperties() { /*从db.properties中读取所有的配置*/ /*通过类的反射实例获取classpath路径下的资源文件db.prooperties,并建立一个流*/ InputStream is=this.getClass().getResourceAsStream("/db.properties"); try { this.load(is); //从输入流中读取属性列表(键和元素对)。 } catch (IOException e) { e.printStackTrace(); LogUtil.logger.error(e.toString()); }finally{ if(is!=null){ try { is.close(); } catch (IOException e) { e.printStackTrace(); LogUtil.logger.error(e.toString()); } } } } /*对外提供一个获取唯一实例的方法*/ public static MyProperties getMyProperties(){ if(mypro==null){ new MyProperties(); } return pro; } } /**************************************************************************************************************************************************/ DriverManager.getConnection(url, user, password) 然后连接部分可以这样写了。 Class.forName(MyProperties.getMyProperties().getProperty("driver")); con = DriverManager.getConnection(MyProperties.getMyProperties().getProperty("url"), MyProperties.getMyProperties()); 为什么后面只需要一个语句就行了? 因为在db.properties配置文件时已经写好了。 driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:orcl user=scott password=a 如果把user或者password改成别的,那就需要这样写了. con = DriverManager.getConnection(MyProperties.getMyProperties().getProperty("url"),MyProperties.getMyProperties().getProperty("user"),MyProperties.getMyProperties().getProperty("password")); 我的感觉:DriverManager是驱动,Class.forName(“x”)是用来初始化X对象的。 既然是驱动,那么不止这一个? 既然是对象,不止这一个? |
2.设置静态块,静态块在程序运行就运行了。比构造函数还先运行。
static
{
try
{
Class.
forName(MyProperties.
getMyProperties().getProperty(
"driver")); /*
driver=
oracle.jdbc.driver.OracleDriver*/
}
catch
(ClassNotFoundException e) {
e.printStackTrace();
LogUtil.
logger
.error(e.toString());
}
}
|
2.获取连接 public void getConnection(){ con=DriverManager.getConnection(MyProperties.getMyProperties().getProperty("url"),MyProperties. getMyProperties()); }
/*为什么不要写三个而是俩个? 为什么后面只需要一个语句就行了? 因为在db.properties配置文件时已经写好了*/
|
2.1 注参函数 public void setvalue(PreparedStatement pstmt, List<Object> params) {
if
(params !=
null
&& params.size() > 0) {
for
(
int
i = 0; i < params.size(); i++) {
try
{
pstmt.setString(i + 1, params.get(i) +
""
);
}
catch
(SQLException e) {
e.printStackTrace();
LogUtil.
logger
.error(e.toString());
}
}
}
}
|
3.更新操作有俩种,一种是带参的,一种是不带参的。 都适合多条sql语句。
/**第一种,最简单的。带参的
* 单句更新语句,后面可以带参 执行流程 1.连接 2.预编译 3.注参 4.执行 5.获得结果
* */
public int doUpdate(String sql, List<Object> params) {
int result=0;
try {
con= this.getConnection();
pstmt= con.prepareStatement(sql);
this.setValue(pstmt , params);
result= pstmt.executeUpdate();
if(result>0){
System. out.println("success" );
} else{
System. out.println("fail" );
}
} catch (SQLException e) {
e.printStackTrace();
LogUtil. logger.error(e.toString());
} finally{
this.closeAll(null, pstmt, con);
}
return result;
} |
/**多条语句,无参数,像update和insert这样的语句
* 1.连接 2.关闭自动提交 3.预编译 4.提交事务
* 5.执行 6.出错回滚 7.获取结果 8.开启自动提交
* 需要一条一条的执行。
* */
public boolean doUpdate(List<String> sqls){
int result=0;
try {
con= this .getConnection();
con.setAutoCommit( false );/*关闭自动提交*/
if (sqls!=null &&sqls.size()>0&&sqls.get(0)!=null){
for (int i=0;i<sqls.size();i++){
pstmt= con.prepareStatement(sqls.get(i));
result=
pstmt
.executeUpdate(); /*为什么result在这里????*/
}
}
con.commit(); /**提交修改,相当于一次性提交*/
} catch (SQLException e) {
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
LogUtil. logger .error(e.toString());
} /**如果出错了,那么回滚*/
e.printStackTrace();
} finally {
try {
con.setAutoCommit( true );
} catch (SQLException e) {
e.printStackTrace();
LogUtil. logger .error(e.toString());
}
this .closeAll(null, pstmt, con);
}
if (result>0){
System. out .println("success" );
return true ;
} else {
System. out .println("fail" );
return false ;
}
}
|
/**
* 1.连接 2.预编译 3.检验再注参 4.执行
* */
public boolean doUpdate1(List<String> sqls, List<List<Object>> params) {
con = this.getConnection();
int result = 0;
try {
con.setAutoCommit( false);
if (sqls != null && sqls.size() > 0 && sqls.get(0) != null ) {
for (int i = 0; i < sqls.size(); i++) {
pstmt = con.prepareStatement(sqls.get(i));
if (params != null && params.size() > 0
&& params.get(i) != null) {
this.setValue(pstmt , params.get(i));
}
}
}
result = pstmt.executeUpdate();
con.commit();
} catch (SQLException e) {
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
LogUtil. logger.error(e.toString());
}
} finally {
try {
con.setAutoCommit( true);
} catch (SQLException e) {
e.printStackTrace();
LogUtil. logger.error(e.toString());
}
this.closeAll(null, pstmt, con);
}
if (result > 0) {
System. out.println("success" );
return true ;
} else {
System. out.println("fail" );
return false ;
}
}
|
4.查询操作 单句的聚合查询 单句的查询带参语句(个人认为最重要)
/**1.连接 2.预编译
* 3.注参 4.执行
* 5.判断,取聚合值
* */
public double selectPolyer(String sql,List<Object> params){
con= this.getConnection();
try {
pstmt= con.prepareStatement(sql);
this.setValue(pstmt , params);
rs= pstmt.executeQuery();
if(rs .next()){
return rs .getDouble(1);
} else{
return -1;
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
this.closeAll(null, pstmt, con);
}
return -1;
}
|
/**
* 返回为一个List集合,而List集合里面还包括Map集合 1.连接 2.预编译 3.注参 4.执行
* 4.获得ResultSetMetaData,通过 rsmd把所有的列值赋给一个String数组
* 5.通过ResultSet逐个将一行一行的信息存储到HashMap里去
* 6.将map集合添加到list里去
* */
public List<Map<String, String>> selectDate(String sql, List<Object> params) {
List<Map<String, String>> list = new ArrayList<Map<String, String>>();
try {
con = this.getConnection();
pstmt = con.prepareStatement(sql);
this.setValue(pstmt , params);
rs = pstmt.executeQuery();
/*获取关于 ResultSet 对象中列的类型和属性信息的对象*/
ResultSetMetaData rsmt = rs.getMetaData();
String[] cols = new String[rsmt.getColumnCount()];
for (int i = 0; i < cols.length; i++) {
cols[i] = rsmt.getCatalogName(i + 1);
/*获得指定列的名称,例如 dept表里的 depno,deptname, loc*/
}
Map<String, String> map;
while (rs .next()) {
map = new HashMap<String, String>();
/*这个for语句是用来获取一行的所有信息*/
for (int i = 0; i < cols.length; i++) {
map.put(rsmt.getCatalogName(i).toLowerCase(),
rs.getString(cols[i]));
}
list.add(map);
/*一行一行的添加,一次添加一行的信息*/
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
|
II:实践
ATM系统
建表思想=》界面设计=》具体流程=》总结
新技术:MDF加密算法,配置文件。