回调模式
在回调中使用范型
数据封装
内省操作JavaBean
BeanInfo ...
用Beanutils来操作JavaBean
对QueryRunner的增强
集中处理异常。
条件允许的情况下,使用注解处理数据的封装。
时间允许的情况下,使用ThreadLocal维护线程局部的Connection
CMD+Service+Dao三层模型。
在Service层管理事务。
在Dao中处理数据库操作。
在CMD层接收并与用户进行交互。
JTA分布式事务
JOTM (Java Open Transaction Manager)
XAPool连接池。
2、回调模式
a) 回调是指程序员在开发程序时,按指定的标准(接口),开发所需要的实现类。在运行时。程序员不需要去调用。而是由系统已经定义好的结构去调用接口的具体实现类。
具有以下组件:
1:核心组件,由程序开发。且在调用时由程序员传递回调的实现类。
QueryRunner.
2:回调规范- 接口-
ResultSetHandler
以下是一个示例:
用ResultSetHandler实现数据的封装:
3、模拟回调
两个核心类:
1:主类。
2:回调规范。接口- 里面应该有一个方法让子类去实现。
public class CallBackDemo2 {
public static void main(String[] args) {
QR qr = new QR();
RH rh = new RH(){
public void hand(String str){
System.err.println("2:这是Hello..."+str);
}
};
System.err.println("1:准备开始调用。。");
qr.run("张adfasdf三同学",rh);
}
}
//声明回调主类
class QR{
public void run(String ss,RH rh){
rh.hand(ss);
}
}
//声明回调接口
interface RH{
void hand(String str);
}
4、通过范型设置一个方法可以返回各种类型-用户指定的
实现用回调封装数据,但不指定类型。直接返回Object。
通过以下示例,说明了如何通过一个方法,就可以返回各种不同类型。通过范型来设置的。
package cn.oracle.callback;
import java.lang.reflect.Type;
import java.util.List;
//Class-Type
public class CallBackDemo3<T> {
public static void main(String[] args) {
QR3 qr = new QR3();
//定义返回的具体类型
RH3<String> rh3 = new RH3<String>(){
@Override
public String hand(String str) {
return "sfasd";
}
};
String ss=qr.run("dsfasd",rh3);
}
}
//声明回调主类
class QR3{
public <T>[微软用户1] T run(String ss,RH3<T> rh){
T t = rh.hand(ss);
return t;
}
}
//声明回调接口
interface RH3<T>[微软用户2] {
T[微软用户3] hand(String str);
}
5、模拟dbutils的回调-封装数据用的
1:QueryRunner是核心类。 - 自己开发一个类- MyQueryRunner.
在MyQueryRunner中有一个方法;select
在select方法中接收几个参数呢:
Select(String sql,MyResultSetHandler<T> mr)
2:声明一个MyResultSetHandler<T>接口
里面就必须要一个方法
接收 :接收结集对象,ResultSet。
做什么工作:将结果集封装到指的范型类型中 –具体的实现类中。
返回什么东西:返回这个封装好的数据。
package cn.oracle.callback;
//这儿略去了很多导入
public class CallbackDemo4 {
@Test
public void testQuery(){
MyQueryRunner run =
new MyQueryRunner(C3p0Utils.getDataSource());
String sql = "select * from jobs";
//执行调用
List<Map<String,Object>> list = run.select(sql,new MyMapListHandler[王健4] ());
System.err.println("List is :"+list);
}
}
//----------------以下是核心类-----------
//声明回调主类
class MyQueryRunner{
private DataSource ds;
public MyQueryRunner(DataSource ds){
this.ds=ds;
}
//方法
public <T> T select(String sql,MyResultSetHandler<T> mrs){
//执行查询才可以获取到 rs结果集
Connection con = null;
//声明返回类型
T t = null;
try{
//获取rs
con = ds.getConnection();
Statement st = con.createStatement();
ResultSet rs = st.executeQuery(sql);
t = mrs.sealed(rs);
rs.close();
st.close();
}catch(Exception e){
throw new RuntimeException(e);
}finally{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return t;
}
}
//声明回调接口
interface MyResultSetHandler<T>{[微软用户5]
public T sealed(ResultSet rs) throws SQLException;
}
//实现一个可以直接封装成list-map类型的类
class MyMapListHandler implements MyResultSetHandler<List<Map<String, [王健6] Object>>>{
@Override
public List<Map<String, Object>> sealed(ResultSet rs) throws SQLException {
List<Map<String, Object>> list = new ArrayList<>();
//获取rs的元数据
ResultSetMetaData rsmd = rs.getMetaData();
int cols = rsmd.getColumnCount();
while(rs.next()){
Map<String,Object> mm = new HashMap<String, Object>();
for(int i=1;i<=cols;i++){
String colName = rsmd.getColumnName(i);
Object obj = rs.getObject(i);
mm.put(colName, obj);
}
list.add(mm);
}
return list;
}
}
6、返回Bean的
开发两个JavaBean
7、JavaBean的操作 – 用第三方工具类 – beanutils.
Beanutils _ apache开发,专门用于操作javabean.
在beanUtils工具包中,记下一个核心类:
BeanUtils
同时需要导入以下jar包:
Beanutils特点:
1:提供了String到其他各种的自动的转换
String-> int,Integer,double,- 到所以基本及它的对象类的转换。
2:JavaBean可以只提供setXxx方法而不提供getXxx方法也可以设置成功。
3:级联设置
4:指设置
可以直接接收一个Map
5:兼容数组到基本类型的转换
6、没有设置时间成功
自己转换:
@Test
public void testBeanUtils5() throws Exception{
String dd = "2009-09-09 12:34:23";
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date dt =sdf.parse(dd);
Object o = new Emp();
BeanUtils.setProperty(o, "brith",dt);
System.err.println(o);
}
在beanutils中还有一个核心类:转换核心类
此类需要设置一次,在任意的地方,设置一次,对所有beantuisl有效:
@Test
public void testBeanUtils6() throws Exception{
//声明可以从String->Date转换
ConvertUtils.register(new Converter() {
@Override
public Object convert(Class type, Object value) {
System.err.println("开始转换:"+type+","+value);
if(type==Date.class){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(""+value);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}, Date.class);
//----
Object o = new Emp();
BeanUtils.setProperty(o, "brith","2008-09-12 12:56:23");
System.err.println(o);
}