- 浏览: 448377 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
飞天奔月:
我来个简单点的代码 使用 LinkedHashSetpubli ...
ArrayList去重 -
飞天奔月:
public static <T> List< ...
ArrayList去重 -
aaron7524:
事务隔离级别 -
月陨殇:
wlh269 写道rswh110 写道lz内容写的不错,就是略 ...
事务隔离级别 -
lnx1824:
我的更奇怪,在本地静态的可以,放jetty里的页面后就不然,都 ...
JS得到上传图片尺寸
该文章所解决的问题是Oracle下,乱码问题
描述:
1.库服务端编码是US7ASCII,
2.我们也有一套程序,这套程序的所有DAO操作都是类型这么做的:
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.13.123:1521:infosys", "infosys" , "infosys");
stmt = conn.createStatement();
.... stmt.executeUpdate(sql);
... stmt.executeQuery(sql);
程序和库结合,发现查询出来的结果是乱码!更新之后的结果也是乱码!!!
解决的方法就是从客户端得到的参数经过重新编码后更新入库(插入和更新),从数据库查询到的数据经过反向编码再展示,其实就是:
入库:new String(param.getBytes("GB18030"),"ISO-8859-1");
出库:new String(param.getBytes("ISO-8859-1"),"GB18030");
在我们的程序中DAO层有很多数据库的操作,难道我们一处一处去改吗?不,这样太累了,而且还容易出错!
怎么做呢,我们给出动态代理的解决方案,其实也就是AOP的思想!
具体如下:
====数据库连接的代理类====
Statement代理类
结果集代理类
数据库工具类
测试类
描述:
1.库服务端编码是US7ASCII,
2.我们也有一套程序,这套程序的所有DAO操作都是类型这么做的:
Class.forName("oracle.jdbc.driver.OracleDriver");
conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.13.123:1521:infosys", "infosys" , "infosys");
stmt = conn.createStatement();
.... stmt.executeUpdate(sql);
... stmt.executeQuery(sql);
程序和库结合,发现查询出来的结果是乱码!更新之后的结果也是乱码!!!
解决的方法就是从客户端得到的参数经过重新编码后更新入库(插入和更新),从数据库查询到的数据经过反向编码再展示,其实就是:
入库:new String(param.getBytes("GB18030"),"ISO-8859-1");
出库:new String(param.getBytes("ISO-8859-1"),"GB18030");
在我们的程序中DAO层有很多数据库的操作,难道我们一处一处去改吗?不,这样太累了,而且还容易出错!
怎么做呢,我们给出动态代理的解决方案,其实也就是AOP的思想!
具体如下:
====数据库连接的代理类====
package com.wlh.test; import java.sql.*; import java.lang.reflect.*; /* * * 数据库连接的代理类 * @author Liudong */ public class _Connection implements InvocationHandler{ private Connection targetConn;//原对象 private Connection proxyConn;//代理对象 //指定是否进行字符串转码操作 private boolean coding = false; //构造方法 public _Connection(Connection targetConn, boolean coding){ this.targetConn = targetConn; this.coding = coding; this.proxyConn=(Connection)Proxy.newProxyInstance( targetConn.getClass().getClassLoader(), targetConn.getClass().getInterfaces(), this); } //得到代理对象 public Connection getConnection() { return this.proxyConn; } /** * 动态代理对象执行接口中定义每个方法都将触发该方法 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //调用相应的操作 Object obj = null; try{ obj = method.invoke(targetConn, args); //如果代理类实例proxyConn调用了prepareStatement或者createStatement, //则调用如下代码得到Statement(Statement是Preparestatement的父亲接口) if((CS.equals(methodName)||PS.equals(methodName))&&coding) { return new _Statement((Statement)obj,true).getStatement(); } } catch(InvocationTargetException e) { throw e.getTargetException(); } return obj; } private final static String PS = "prepareStatement"; private final static String CS = "createStatement"; }
Statement代理类
package com.wlh.test; import java.sql.*; import java.lang.reflect.*; /** * 数据库语句对象实例的代理类 * @author Liudong */ class _Statement implements InvocationHandler{ private Statement targetStatement ; //原对象 private Statement proxyStatement;//代理对象 private boolean decode = false; //指定是否进行字符串转码 public _Statement(Statement targetStatement,boolean decode) { this.targetStatement = targetStatement; this.decode = decode; this.proxyStatement=(Statement)Proxy.newProxyInstance( targetStatement.getClass().getClassLoader(), targetStatement.getClass().getInterfaces(), this); } /** * 得到代理对象 * @return */ public Statement getStatement() { return this.proxyStatement; } /** * 方法接管 */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String methodName = method.getName(); //接管setString方法(PrepareStatement相关) if(decode && SETSTRING.equals(methodName)) { try{ String param = (String)args[1]; if(param!=null) param = new String(param.getBytes("GB18030"),"ISO-8859-1"); return method.invoke(targetStatement,new Object[]{args[0],param}); } catch(InvocationTargetException e){ throw e.getTargetException(); } } //接管executeQuery方法(查询相关) if(decode && EXECUTEQUERY.equals(methodName)){ try{ ResultSet rs = (ResultSet)method.invoke(targetStatement,args); return new _ResultSet(rs,decode).getResultSet(); }catch(InvocationTargetException e){ throw e.getTargetException(); } } //接管executeUpdate方法(更新相关) if(decode && EXECUTEUPDATE.equals(methodName)){ try{ String param = (String)args[0]; if(param!=null) param = new String(param.getBytes("GB18030"),"ISO-8859-1"); return method.invoke(targetStatement,new Object[]{param}); } catch(InvocationTargetException e){ throw e.getTargetException(); } } try{ return method.invoke(targetStatement, args); } catch(InvocationTargetException e) { throw e.getTargetException(); } } //两个要接管的方法名 private final static String SETSTRING = "setString"; private final static String EXECUTEQUERY = "executeQuery"; private final static String EXECUTEUPDATE = "executeUpdate"; }
结果集代理类
package com.wlh.test; import java.sql.ResultSet; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 数据库结果集的代理类 * @author Liudong */ class _ResultSet implements InvocationHandler{ //原对象 private ResultSet targetRS = null; private boolean decode = false; public _ResultSet(ResultSet targetRS,boolean decode) { this.targetRS = targetRS; this.decode = decode; } //得到代理对象 public ResultSet getResultSet(){ Class[] interfaces = targetRS.getClass().getInterfaces(); if(interfaces==null||interfaces.length==0){ interfaces = new Class[1]; interfaces[0] = ResultSet.class; } ResultSet proxyRS = (ResultSet)Proxy.newProxyInstance(targetRS.getClass().getClassLoader(), interfaces,this); return proxyRS; } /** * 结果getString方法 */ public Object invoke(Object proxy, Method m, Object[] args) throws Throwable { String method = m.getName(); if(decode && GETSTRING.equals(method)){ try{ String result = (String)m.invoke(targetRS,args); if(result!=null) return new String(result.getBytes("iso-8859-1"),"GB18030"); //return result; return null; }catch(InvocationTargetException e){ throw e.getTargetException(); } } try{ return m.invoke(targetRS, args); }catch(InvocationTargetException e){ throw e.getTargetException(); } } private final static String GETSTRING = "getString"; }
数据库工具类
package com.wlh.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; /** * 数据库操作类 * @author wulihai * */ public class DBUtil { public static Connection getConn() { Connection conn = null; try { Class.forName("oracle.jdbc.driver.OracleDriver"); conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.13.123:1521:infosys", "infosys" , "infosys"); } catch (ClassNotFoundException e) { e.printStackTrace(); throw new java.lang.RuntimeException(); } catch (SQLException e) { e.printStackTrace(); throw new java.lang.RuntimeException(); } return conn; } /*public static Connection getConn() { Connection conn = null; InitialContext ctx; try { ctx = new InitialContext(); DataSource ds = (DataSource) ctx.lookup("java:comp/env/jdbc/dpw"); conn = ds.getConnection(); } catch (NamingException e) { e.printStackTrace(); }catch (SQLException e) { e.printStackTrace(); } return conn; }*/ public static Statement createStmt(Connection conn) { Statement stmt = null; try { stmt = conn.createStatement(); } catch (SQLException e) { e.printStackTrace(); } return stmt; } public static int executeUpdate(Connection conn, String sql) { int ret = 0; Statement stmt = null; try { stmt = conn.createStatement(); ret = stmt.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } finally { close(stmt); } return ret; } public static PreparedStatement prepareStmt(Connection conn, String sql) { PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement(sql); } catch (SQLException e) { e.printStackTrace(); } return pstmt; } public static PreparedStatement prepareStmt(Connection conn, String sql, int autoGeneratedKeys) { PreparedStatement pstmt = null; try { pstmt = conn.prepareStatement(sql, autoGeneratedKeys); } catch (SQLException e) { e.printStackTrace(); } return pstmt; } public static void close(Connection conn) { if(conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } conn = null; } } public static void close(Statement stmt) { if(stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } stmt = null; } } public static void close(ResultSet rs) { if(rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } rs = null; } } }
测试类
package com.wlh.test; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class Test { /** * @param args */ public static void main(String[] args) { try { test(); } catch (SQLException e) { e.printStackTrace(); } } public static void test() throws SQLException{ Connection conn = DBUtil.getConn(); //获取数据库连接 boolean coding = true; //从配置或者其他地方读取是否进行转码的配置 // 接管数据库连接实例 _Connection _conn = new _Connection(conn,coding); // 获得接管后的数据库连接实例,以后直接使用conn2而不是conn Connection conn2 = _conn.getConnection(); //================executeQuery getString============================================// Statement stmt=conn2.createStatement(); ResultSet rs=stmt.executeQuery("select t.prvid,t.name from p_privilege t"); if(rs.next()){ System.out.println(rs.getString(1)); System.out.println(rs.getString(2)); System.out.println("-------------------"); } //===================executeQuery setString =========================================// PreparedStatement pstmt=conn2.prepareStatement("update p_privilege t set t.name=? where t.prvid=?"); pstmt.setString(1, "临时2"); pstmt.setString(2, "5"); pstmt.execute(); PreparedStatement pstmt2=conn2.prepareStatement("select t.PRVID,t.name from p_privilege t where t.prvid=?"); pstmt2.setString(1, "5"); ResultSet rs2=pstmt2.executeQuery(); if(rs2.next()){ System.out.println(rs2.getString(1)); System.out.println(rs2.getString(2)); System.out.println("-------------------"); } //==================executeUpdate==========================================// Statement stmt3=conn2.createStatement(); stmt3.executeUpdate("update p_privilege t set t.name='临时菜单' where t.prvid='5'"); Statement stmt4=conn2.createStatement(); ResultSet rs4=stmt4.executeQuery("select t.prvid,t.name from p_privilege t"); if(rs4.next()){ System.out.println(rs4.getString(1)); System.out.println(rs4.getString(2)); System.out.println("-------------------"); } } }
评论
3 楼
liwanfeng
2010-07-29
解决了,原因是由于T4CConnection类并没有直接实现Connection接口,而是继承一个实现Connection接口的类,为了能够将反射的对象强转成Connection接口类型,所以需要在Proxy.newProxyInstance的过程中,在接口列表中加上Connection类型即可!
感受颇深啊……
感受颇深啊……
2 楼
wlh269
2010-07-28
不好意思刚看到你发的评论,问题解决没有啊?
1 楼
liwanfeng
2010-07-23
请原谅我看的不够仔细,我现在有个一文,就是当我为oracle的数据库连接做代理时,实现的方法与你的非常相似,可是总是在这段代码中报错,请问你是怎么解决的?
以上代码的摘抄:
错误是:java.lang.ClassCastException:$proxy0
…… …… ……
我查看了一下,获取的数据库连接是 oracle.jdbc.T4CConnection(oracle.jdbc.driver.T4CConnection),由于该类没有直接实现Connection接口,所以无法将生成的代理对象强转成Connection类型,所以程序没有通过,不知道有什么技巧或好的解决办法,请帮忙解决一下吧!非常感谢!
以上代码的摘抄:
this.proxyConn=(Connection)Proxy.newProxyInstance( targetConn.getClass().getClassLoader(), targetConn.getClass().getInterfaces(), this);
错误是:java.lang.ClassCastException:$proxy0
…… …… ……
我查看了一下,获取的数据库连接是 oracle.jdbc.T4CConnection(oracle.jdbc.driver.T4CConnection),由于该类没有直接实现Connection接口,所以无法将生成的代理对象强转成Connection类型,所以程序没有通过,不知道有什么技巧或好的解决办法,请帮忙解决一下吧!非常感谢!
发表评论
-
java开发实战视频详解
2017-07-02 08:09 492java开发实战视频详解 链接: http://pan.bai ... -
mysql在window下备份
2013-02-03 09:25 1017命令:mysqldump –uroot –ppassword ... -
NoSQL非关系型数据库
2011-08-23 10:25 1477NoSQL(NoSQL = Not Only SQL ), ... -
Oracle 编码再回顾
2011-02-15 10:53 1129一、什么是Oracle字符集 ... -
位图索引与 B-tree 索引:选择与时间
2010-08-26 10:58 1539位图索引与 B-tree 索引:选择与时间 了解每个索引的正 ... -
Oracle的redo 和undo的区别
2010-07-28 15:33 1009redo--> undo-->datafile i ... -
Oracle归档模式与非归档模式设置
2010-07-16 16:14 1700Oracle的日志归档模式可以有效的防止instance和d ... -
比较牛逼的插入SQL语句
2010-06-02 10:22 1856MessageDaoImpl.java$saveMessa ... -
oracle的分析函数over 及开窗函数
2010-03-07 20:53 1049一:分析函数over Oracle从8.1.6开始提 ... -
Oracle Case 条件函数
2010-03-02 10:53 1278select dx.docid, case ... -
关于两表关联的update
2010-02-23 13:38 1668-- update 一个字段 update a ... -
oracle客户端编码修改
2010-02-04 12:15 1865从注册表修改:HKEY_LOCAL_MACHINE\SOFTW ... -
Oracle两个数据库间的数据同步 (DBLink 、计划任务)
2010-01-31 19:42 7228--配置本地数据库服务器的tnsnames.ora文 ... -
Oracle数据库字符集问题解析
2009-12-14 16:15 1010经常看到一些朋友问OR ... -
Oracle函数大全
2009-12-14 16:13 920SQL中的单记录函数 1.ASCII 返回与指定的字 ... -
导入导出
2009-11-10 09:50 894导入命令: 1.cmd进入命令行; (1)无连接登录o ... -
两种外连接
2009-10-26 13:54 927select cpxx.cp_xh, ... -
Oracle Blob (二进制文件的读写)
2009-10-18 23:16 6116import java.io.FileNotFoundEx ... -
Oracle时间操作
2009-08-21 16:04 946一.插入当前日期 //构造系统时间的字符串 Str ... -
创建表空间和用户
2009-08-09 13:36 646--创建临时表空间 create temporar ...
相关推荐
JDK动态代理,关于jdk动态代理的问题!详细的说明!JDK动态代理JDK动态代理
对jdk中的动态代理执行过程进行了详细跟踪,并反编译了动态代理调用自动生成的代理类,并对其进行了详细讲解。
jdk 的动态代理和CGLIB代理
JDK动态代理源码下载,动态产生代理,实现对【不同类】,【不同方法】的代理
jdk动态代理技术详解,可以学习一下,不错的
java jdk 动态代理 演示demo
通过一个简单例子来理解JDK动态代理的思想,资源为拷贝的视频讲解的内容。
Jdk动态代理,基于接口的代理示例 InovactionHandler Proxy
动态代理是使用jdk的反射机制,创建对象的能力, 创建的是代理类的对象。 而不用你创建类文件。不用写java文件。 动态:在程序执行时,调用jdk提供的方法才能创建代理类的对象。jdk动态代理,必须有接口,目标类必须...
NULL 博文链接:https://jummy.iteye.com/blog/255628
AOP之JDK动态代理和CGLib动态代理 ,具体效果和过程看博文 http://blog.csdn.net/evankaka/article/details/45195383
模拟JDK动态代理内部实现
spring aop jdk 动态代理的底层实现解析模拟
java代理机制 JDK动态代理和cglib代理 详解
JDK动态代理proxy的基本工作原理代码!!
java静态代理 jdk动态代理 cglib动态代理 代理原理
java jdk 动态代理演示demo
oracle最新驱动适用于jdk1.6和jdk1.7以上版本,jdk1.6使用ojdbc6.jar;jdk1.7或以上版本使用ojdbc7.jar。欢迎下载
基于java的jdk动态代理, 比较了静态代理与动态代理的区别,以及动态代理的底层实现,反编译class文件 jdk动态代理和cglib的区别
jdk 和 cglib的简单动态代理,闲来无事 写写。有需要的朋友可以看看