1.JDBC有几种驱动类型:
type 1:jdbc-odbc桥
type 2:本地api驱动
type 3:网络协议驱动
type 4:本地协议驱动
Type 1: jdbc-odbc桥
Jdbc-odbc桥是sun公司提供的,是jdk提供的的标准api. 这种类型的驱动实际是把所有jdbc的调用传递给odbc ,再由odbc调用本地数据库驱动代码.( 本地数据库驱动代码是指由数据库厂商提供的数据库操作二进制代码库,例如在oracle for windows中就是oci dll 文件)
jdbc-odbc桥 ---- odbc---- 厂商DB代码 ----- 数据库Server
(图一)
只要本地机装有相关的odbc驱动那么采用jdbc-odbc桥几乎可以访问所有的数据库,jdbc-odbc方法对于客户端已经具备odbc driver的应用还是可行的.但是,由于jdbc-odbc先调用odbc再由odbc去调用本地数据库接口访问数据库.所以,执行效率比较低,对于那些大数据量存取的应用是不适合的.而且,这种方法要求客户端必须安装odbc 驱动,所以对于基于internet ,intranet的应用也是不合适的.因为,你不可能要求所有客户都能找到odbc driver.
Type 2: 本地Api驱动
本地api驱动直接把jdbc调用转变为数据库的标准调用再去访问数据库.这种方法需要本地数据库驱动代码.
本地api驱动----厂商DB代码-----数据库Server
(图二)
这种驱动比起jdbc-odbc桥执行效率大大提高了.但是,它仍然需要在客户端加载数据库厂商提供的代码库.这样就不适合基于internet的应用.并且,他的执行效率比起3,4型的jdbc驱动还是不够高.
Type3:网络协议驱动
这种驱动实际上是根据我们熟悉的三层结构建立的. jdbc先把对数局库的访问请求传递给网络上的中间件服务器. 中间件服务器再把请求翻译为符合数据库规范的调用,再把这种调用传给数据库服务器.如果中间件服务器也是用java开发的,那么在在中间层也可以使用1,2型 jdbc驱动程序作为访问数据库的方法.
网络协议驱动---------中间件服务器------------数据库Server
( 图三)
由于这种驱动是基于server的.所以,它不需要在客户端加载数据库厂商提供的代码库.而且他在执行效率和可升级性方面是比较好的.因为大部分功能实现都在server端,所以这种驱动可以设计的很小,可以非常快速的加载到内存中. 但是,这种驱动在中间件层仍然需要有配置其它数据库驱动程序,并且由于多了一个中间层传递数据,它的执行效率还不是最好.
Type4 本地协议驱动
这种驱动直接把jdbc调用转换为符合相关数据库系统规范的请求.由于4型驱动写的应用可以直接和数据库服务器通讯.这种类型的驱动完全由java实现,因此实现了平台独立性.
本地协议驱动---------数据库Server
( 图四)
由于这种驱动不需要先把jdbc的调用传给odbc或本地数据库接口或者是中间层服务器.所以它的执行效率是非常高的.而且,它根本不需要在客户端或服务器端装载任何的软件或驱动. 这种驱动程序可以动态的被下载.但是对于不同的数据库需要下载不同的驱动程序.
以上对四种类型的jdbc驱动做了一个说明.那么它们适合那种类型的应用开发呢?Jdbc-odbc桥由于它的执行效率不高,更适合做为开发应用时的一种过度方案,或着对于初学者了解jdbc编程也较适用. 对于那些需要大数据量操作的应用程序则应该考虑2,3,4型驱动.在intranet方面的应用可以考虑2型驱动,但是由于3,4型驱动在执行效率上比2型驱动有着明显的优势,而且目前开发的趋势是使用纯java.所以3,4型驱动也可以作为考虑对象. 至于基于internet方面的应用就只有考虑3,4型驱动了. 因为3型驱动可以把多种数据库驱动都配置在中间层服务器.所以3型驱动最适合那种需要同时连接多个不同种类的数据库, 并且对并发连接要求高的应用. 4型驱动则适合那些连接单一数据库的工作组应用.
今天项目中碰到一个科学计算法的问题,我保存到数据库的是数字,但是从数据库中取出来在页面展现的时候确变成了科学计算法的形式了。最后查了下,发现<bean:write/>里有个属性format="##.00"这样可以就正确显示保存的数字。因为我的涉及到小数点的问题,所以我保留了两位有效数字。
Date.prototype.isLeapYear 判断闰年
Date.prototype.Format 日期格式化
Date.prototype.DateAdd 日期计算
Date.prototype.DateDiff 比较日期差
Date.prototype.toString 日期转字符串
Date.prototype.toArray 日期分割为数组
Date.prototype.DatePart 取日期的部分信息
Date.prototype.MaxDayOfDate 取日期所在月的最大天数
Date.prototype.WeekNumOfYear 判断日期所在年的第几周
StringToDate 字符串转日期型
IsValidDate 验证日期有效性
CheckDateTime 完整日期时间检查
daysBetween 日期天数差
js 代码
-
-
-
- Date.prototype.isLeapYear = function()
- {
- return (0==this.getYear()%4&&((this.getYear()%100!=0)||(this.getYear()%400==0)));
- }
-
-
-
-
-
-
-
-
-
-
-
- Date.prototype.Format = function(formatStr)
- {
- var str = formatStr;
- var Week = ['日','一','二','三','四','五','六'];
-
- str=str.replace(/yyyy|YYYY/,this.getFullYear());
- str=str.replace(/yy|YY/,(this.getYear() % 100)>9?(this.getYear() % 100).toString():'0' + (this.getYear() % 100));
-
- str=str.replace(/MM/,this.getMonth()>9?this.getMonth().toString():'0' + this.getMonth());
- str=str.replace(/M/g,this.getMonth());
-
- str=str.replace(/w|W/g,Week[this.getDay()]);
-
- str=str.replace(/dd|DD/,this.getDate()>9?this.getDate().toString():'0' + this.getDate());
- str=str.replace(/d|D/g,this.getDate());
-
- str=str.replace(/hh|HH/,this.getHours()>9?this.getHours().toString():'0' + this.getHours());
- str=str.replace(/h|H/g,this.getHours());
- str=str.replace(/mm/,this.getMinutes()>9?this.getMinutes().toString():'0' + this.getMinutes());
- str=str.replace(/m/g,this.getMinutes());
-
- str=str.replace(/ss|SS/,this.getSeconds()>9?this.getSeconds().toString():'0' + this.getSeconds());
- str=str.replace(/s|S/g,this.getSeconds());
-
- return str;
- }
-
-
-
-
- function daysBetween(DateOne,DateTwo)
- {
- var OneMonth = DateOne.substring(5,DateOne.lastIndexOf ('-'));
- var OneDay = DateOne.substring(DateOne.length,DateOne.lastIndexOf ('-')+1);
- var OneYear = DateOne.substring(0,DateOne.indexOf ('-'));
-
- var TwoMonth = DateTwo.substring(5,DateTwo.lastIndexOf ('-'));
- var TwoDay = DateTwo.substring(DateTwo.length,DateTwo.lastIndexOf ('-')+1);
- var TwoYear = DateTwo.substring(0,DateTwo.indexOf ('-'));
-
- var cha=((Date.parse(OneMonth+'/'+OneDay+'/'+OneYear)- Date.parse(TwoMonth+'/'+TwoDay+'/'+TwoYear))/86400000);
- return Math.abs(cha);
- }
-
-
-
-
-
- Date.prototype.DateAdd = function(strInterval, Number) {
- var dtTmp = this;
- switch (strInterval) {
- case 's' :return new Date(Date.parse(dtTmp) + (1000 * Number));
- case 'n' :return new Date(Date.parse(dtTmp) + (60000 * Number));
- case 'h' :return new Date(Date.parse(dtTmp) + (3600000 * Number));
- case 'd' :return new Date(Date.parse(dtTmp) + (86400000 * Number));
- case 'w' :return new Date(Date.parse(dtTmp) + ((86400000 * 7) * Number));
- case 'q' :return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number*3, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());
- case 'm' :return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());
- case 'y' :return new Date((dtTmp.getFullYear() + Number), dtTmp.getMonth(), dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());
- }
- }
-
-
-
-
- Date.prototype.DateDiff = function(strInterval, dtEnd) {
- var dtStart = this;
- if (typeof dtEnd == 'string' )
- {
- dtEnd = StringToDate(dtEnd);
- }
- switch (strInterval) {
- case 's' :return parseInt((dtEnd - dtStart) / 1000);
- case 'n' :return parseInt((dtEnd - dtStart) / 60000);
- case 'h' :return parseInt((dtEnd - dtStart) / 3600000);
- case 'd' :return parseInt((dtEnd - dtStart) / 86400000);
- case 'w' :return parseInt((dtEnd - dtStart) / (86400000 * 7));
- case 'm' :return (dtEnd.getMonth()+1)+((dtEnd.getFullYear()-dtStart.getFullYear())*12) - (dtStart.getMonth()+1);
- case 'y' :return dtEnd.getFullYear() - dtStart.getFullYear();
- }
- }
-
-
-
-
- Date.prototype.toString = function(showWeek)
- {
- var myDate= this;
- var str = myDate.toLocaleDateString();
- if (showWeek)
- {
- var Week = ['日','一','二','三','四','五','六'];
- str += ' 星期' + Week[myDate.getDay()];
- }
- return str;
- }
-
-
-
-
-
- function IsValidDate(DateStr)
- {
- var sDate=DateStr.replace(/(^\s+|\s+$)/g,'');
- if(sDate=='') return true;
-
-
- var s = sDate.replace(/[\d]{ 4,4 }[\-/]{ 1 }[\d]{ 1,2 }[\-/]{ 1 }[\d]{ 1,2 }/g,'');
- if (s=='')
- {
- var t=new Date(sDate.replace(/\-/g,'/'));
- var ar = sDate.split(/[-/:]/);
- if(ar[0] != t.getYear() || ar[1] != t.getMonth()+1 || ar[2] != t.getDate())
- {
-
- return false;
- }
- }
- else
- {
-
- return false;
- }
- return true;
- }
-
-
-
-
-
- function CheckDateTime(str)
- {
- var reg = /^(\d+)-(\d{ 1,2 })-(\d{ 1,2 }) (\d{ 1,2 }):(\d{ 1,2 }):(\d{ 1,2 })$/;
- var r = str.match(reg);
- if(r==null)return false;
- r[2]=r[2]-1;
- var d= new Date(r[1],r[2],r[3],r[4],r[5],r[6]);
- if(d.getFullYear()!=r[1])return false;
- if(d.getMonth()!=r[2])return false;
- if(d.getDate()!=r[3])return false;
- if(d.getHours()!=r[4])return false;
- if(d.getMinutes()!=r[5])return false;
- if(d.getSeconds()!=r[6])return false;
- return true;
- }
-
-
-
-
- Date.prototype.toArray = function()
- {
- var myDate = this;
- var myArray = Array();
- myArray[0] = myDate.getFullYear();
- myArray[1] = myDate.getMonth();
- myArray[2] = myDate.getDate();
- myArray[3] = myDate.getHours();
- myArray[4] = myDate.getMinutes();
- myArray[5] = myDate.getSeconds();
- return myArray;
- }
-
-
-
-
-
-
- Date.prototype.DatePart = function(interval)
- {
- var myDate = this;
- var partStr='';
- var Week = ['日','一','二','三','四','五','六'];
- switch (interval)
- {
- case 'y' :partStr = myDate.getFullYear();break;
- case 'm' :partStr = myDate.getMonth()+1;break;
- case 'd' :partStr = myDate.getDate();break;
- case 'w' :partStr = Week[myDate.getDay()];break;
- case 'ww' :partStr = myDate.WeekNumOfYear();break;
- case 'h' :partStr = myDate.getHours();break;
- case 'n' :partStr = myDate.getMinutes();break;
- case 's' :partStr = myDate.getSeconds();break;
- }
- return partStr;
- }
-
-
-
-
- Date.prototype.MaxDayOfDate = function()
- {
- var myDate = this;
- var ary = myDate.toArray();
- var date1 = (new Date(ary[0],ary[1]+1,1));
- var date2 = date1.dateAdd(1,'m',1);
- var result = dateDiff(date1.Format('yyyy-MM-dd'),date2.Format('yyyy-MM-dd'));
- return result;
- }
-
-
-
-
- Date.prototype.WeekNumOfYear = function()
- {
- var myDate = this;
- var ary = myDate.toArray();
- var year = ary[0];
- var month = ary[1]+1;
- var day = ary[2];
- document.write('< script language=VBScript\> \n');
- document.write('myDate = DateValue(''+month+'-'+day+'-'+year+'') \n');
- document.write('result = DatePart('ww', myDate) \n');
- document.write(' \n');
- return result;
- }
-
-
-
-
-
- function StringToDate(DateStr)
- {
-
- var converted = Date.parse(DateStr);
- var myDate = new Date(converted);
- if (isNaN(myDate))
- {
-
- var arys= DateStr.split('-');
- myDate = new Date(arys[0],--arys[1],arys[2]);
- }
- return myDate;
- }
有时候在我们的网络应用中,防止程序自动登录搞破坏,我们一般都会加上验证码,这些验证码一般来说都是由人来识别的,当然,如果验证码很有规律,或者说很清楚,漂亮,那么也是可能被程序识别的,我以前就识别过某网站的验证码,因为比较有规律,所以被识别了,并且识别率达到99%左右,其实我们可以制作很复杂一点的验证码,添加一些干扰的线条或者字体变形,使程序识别的难度加大,这样,我们的目的也就达到了.
下面是生成的图片:
代码如下,JSP代码
<%@page contentType="image/jpeg"%>
<%@page pageEncoding="UTF-8"%>
<%@ page import="java.awt.*,javax.imageio.*,java.io.*,java.util.*,java.awt.image.*" %>
<%--
The taglib directive below imports the JSTL library. If you uncomment it,
you must also add the JSTL library to the project. The Add Library action
on Libraries node in Projects view can be used to add the JSTL 1.1 library.
--%>
<%--
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
--%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<%!String s="";%>
<%
java.util.List<String> fonts=new ArrayList<String>();
GraphicsEnvironment.getLocalGraphicsEnvironment().preferLocaleFonts();
String[] names=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.CHINA);
for(String s:names){
char c=s.charAt(0);
if(Character.isLowerCase(c)||Character.isUpperCase(c)){
}else{
fonts.add(s);
}
}
BufferedImage bi=new BufferedImage(200,50,BufferedImage.TYPE_INT_RGB);
Graphics2D g=bi.createGraphics();
char[] cs={'0','1','2','3','4','5','6','7','8','9'};
char[] use=new char[4];
g.setColor(new Color(240,240,240));
g.fillRect(0,0,200,50);
for(int i=0;i<4;i++){
Point p=new Point(5+(i*((int)(Math.random()*10)+40)),40);
int size=0;
int[] sizes=new int[20];
for(int j=0;j<20;j++){
sizes[j]=30+j;
}
size=sizes[(int)(Math.random()*sizes.length)];
int face=0;
if(Math.random()*10>5){
face=Font.BOLD;
}else{
face=Font.ITALIC;
}
use[i]=cs[(int)(Math.random()*cs.length)];
g.setPaint(new GradientPaint(p.x,p.y,new Color((int)(Math.random()*256),0,(int)(Math.random()*256)),
p.x,p.y-size,new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256))));
g.setFont(new Font(fonts.get((int)(Math.random()*fonts.size())),face,size));
g.drawString(""+use[i],p.x,p.y);
}
s=new String(use);
session.setAttribute("code", s);
g.setPaint(null);
for(int i=0;i<4;i++){
g.setColor(new Color((int)(Math.random()*0x00FFFFFFF)));
g.drawLine((int)(Math.random()*200),(int)(Math.random()*50),(int)(Math.random()*200),(int)(Math.random()*50));
}
Random random = new Random();
for (int i=0;i<88;i++) {
int x = random.nextInt(200);
int y = random.nextInt(50);
g.setColor(new Color((int)(Math.random()*0x00FFFFFFF)));
g.setStroke(new BasicStroke((float)(Math.random()*3)));
g.drawLine(x,y,x,y);
}
OutputStream ot=response.getOutputStream();
ImageIO.write(bi,"JPEG",ot);
g.dispose();
ot.close();
%>
以下是Servlet代码
/*
* Code.java
*
* Created on 2007年9月21日, 下午12:08
*/
package com.hadeslee;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Paint;
import java.awt.Point;
import java.awt.Stroke;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.*;
import javax.servlet.http.*;
/**
*
* @author lbf
* @version
*/
public class Code extends HttpServlet {
/** Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
* @param request servlet request
* @param response servlet response
*/
private List<String> fonts=new ArrayList<String>();
public Code(){
initFonts();
}
private void initFonts(){
GraphicsEnvironment.getLocalGraphicsEnvironment().preferLocaleFonts();
String[] names=GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(Locale.CHINA);
for(String s:names){
char c=s.charAt(0);
if(Character.isLowerCase(c)||Character.isUpperCase(c)){
}else{
fonts.add(s);
}
}
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("image/jpeg;charset=UTF-8");
OutputStream out=response.getOutputStream();
BufferedImage bi=new BufferedImage(200,50,BufferedImage.TYPE_INT_RGB);
Graphics2D g=bi.createGraphics();
char[] cs={'0','1','2','3','4','5','6','7','8','9'};
char[] use=new char[4];
g.setColor(new Color(240,240,240));
g.fillRect(0,0,200,50);
for(int i=0;i<4;i++){
Point p=getPoint(i);
int size=getSize();
use[i]=cs[(int)(Math.random()*cs.length)];
// g.setColor(new Color((int)(Math.random()*256),0,(int)(Math.random()*256)));
g.setPaint(getPaint(p,size));
g.setFont(new Font(fonts.get((int)(Math.random()*fonts.size())),getFace(),size));
g.drawString(""+use[i],p.x,p.y);
}
g.setStroke(new BasicStroke(1.0f));
g.setPaint(null);
for(int i=0;i<4;i++){
g.setColor(new Color((int)(Math.random()*0x00FFFFFFF)));
g.drawLine((int)(Math.random()*200),(int)(Math.random()*50),(int)(Math.random()*200),(int)(Math.random()*50));
}
Random random = new Random();
for (int i=0;i<88;i++) {
int x = random.nextInt(200);
int y = random.nextInt(50);
g.setColor(new Color((int)(Math.random()*0x00FFFFFFF)));
g.setStroke(getStroke());
g.drawLine(x,y,x,y);
}
ImageIO.write(bi,"JPEG",out);
out.close();
g.dispose();
}
private Stroke getStroke(){
BasicStroke bs=new BasicStroke((float)(Math.random()*3));
return bs;
}
private Point getPoint(int index){
return new Point(5+(index*((int)(Math.random()*10)+40)),40);
}
private Paint getPaint(Point p,int size){
GradientPaint gp=new GradientPaint(p.x,p.y,new Color((int)(Math.random()*256),0,(int)(Math.random()*256)),
p.x,p.y-size,new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256)));
return gp;
}
private int getFace(){
if(Math.random()*10>5){
return Font.BOLD;
}else{
return Font.ITALIC;
}
}
private int getSize(){
int[] sizes=new int[20];
for(int i=0;i<20;i++){
sizes[i]=30+i;
}
return sizes[(int)(Math.random()*sizes.length)];
}
// <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
/** Handles the HTTP <code>GET</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/** Handles the HTTP <code>POST</code> method.
* @param request servlet request
* @param response servlet response
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
processRequest(request, response);
}
/** Returns a short description of the servlet.
*/
public String getServletInfo() {
return "Short description";
}
// </editor-fold>
}
摘要: 一 常用的SQL语句
select name,count(*) from table where .. group by ... 中能查询的字段只能为group by的字段.
select * from table where rownum < 5 order by id 中查询出来的结果不是按数据中的ID排序的,而只是将select * from t... 阅读全文
function remove(){
document.body.removeChild(document.getElementById("showDive"));
}
function insert(hid,showid){
var elment=document.getElementById(showid);
var elmentid=document.getElementById(hid).value;
if(document.getElementById("showDive")!=null){
remove();
}
var div=window.document.createElement("div");
div.innerHTML = "<font color='red'>"+elmentid+"</font>";
div.setAttribute("id","showDive");
div.className ="css2";
div.style.height="100px";
div.style.height = "30px";
div.style.top=document.body.scrollLeft+event.clientY;
div.style.left=document.body.scrollLeft+event.clientX;
window.document.body.appendChild(div);
}
最近在做一个项目,因为考虑的主要是实现查询,所以没有用到Hibernate。直接用的jdbc,里面涉及到分页,所以用到rownum了。
比如,写个最简单的用法:select *from (select *from adjustrequsition a order by a.applydate desc) where rownum<6;这样才是正确的想法,往往像我这样的新手,喜欢这样写:select *from adjustrequsition a where rownum<6 order by a.applydate desc; 这样是最容易范的错误。。因为rownum是先从数据库中任意取的数据,然后在按条件排序。。HOHO。。
下面是我写的我工作4个月来最长的sql代码,毕竟我不是DBA哦。。呵呵
select *
from (select row_number() over(order by t.BEGIN_DATE) ranging,
decode(action_seq,
2,
t.person_name,
3,
(select name from account where id = s1.main_account_seq),
(select name from account where id = s1.main_account_seq)) as debit_name,
decode(action_seq,
7,
t.person_name,
4,
(select name from account where id = s1.main_account_seq),
(select name from account where id = s2.main_account_seq)) as credit_name,
(SELECT action_name FROM action_type WHERE t.action_seq = ID) AS action_name,
decode(action_seq,
2,
decode(bank_seq,
null,
'邮局',
(select bank_name
from bank_info
where id = t.bank_seq)),
(select bank_name from bank_info where id = t.bank_seq)) bankname,
decode(action_seq,
2,
t.card_no,
(select decode(a.email, null, a.mobile, a.email)
from account a, sub_account s
where a.id = s.main_account_seq
and s.id = t.debit_seq)) as debit_no,
decode(action_seq,
4,
t.card_no,
7,
t.card_no,
(select decode(a.email, null, a.mobile, a.email)
from account a, sub_account s
where a.id = s.main_account_seq
and s.id = t.credit_seq)) as credit_no,
t.amount,
to_char(t.BEGIN_DATE, 'YYYY-MM-DD hh24:mi') as begin_date,
t.remark,
t.id,
t.voucher_code,
t.DEBIT_FEE,
t.CREDIT_FEE
from transaction t, sub_account s1, sub_account s2
where t.voucher_code is not null
and exists
(select s.id
from account a, sub_account s
where s.main_account_seq = a.id
and a.account_type = 'B'
and (t.credit_seq = s.id or t.debit_seq = s.id))
and t.DEBIT_SEQ = s1.ID
and t.CREDIT_SEQ = s2.ID
and t.action_seq = 3)
where ranging between 1 and 100