泛型,注解,反射配合优化BaseDao的猜想
package test; import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set; import org.apache.commons.dbutils.QueryRunner;
import org.junit.Test; import cn.itcast.tool.jdbc.TXQueryRunner; public class Demo2 {
@Test
public void fun1() throws Exception{
UserDao bd=new UserDao();
User user=new User();
user.setId("guodaxia");
user.setUsername("guozhen");
user.setPassword("961012gz");
user.setState(true);
bd.add(user);
} }
class UserDao extends BaseDAO<User>{ }
class BaseDAO<T>{
QueryRunner qr=new TXQueryRunner();
Class<T> beanClass;
String id; public BaseDAO(){
beanClass=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
} public int add(T bean) throws Exception{
/*
* 首先我们思考,表名如何得到呢?
* 我们假定将所有的bean类名都与表名相同,那样就变成了求类名
*
* values里面的?个数是多少呢?
* 我们又假定所有的bean的属性字段对应数据库表的字段,这样所有属性的个数就对应了?的个数
*
* 参数的值如何得到呢?
* 既然我们都得到了对应的bean属性,调用其中每个属性的的getXxx方法即可
*
* 刚才我们简单地推出了sql语句和简单地推出了参数值,这样就可以执行我们的操作了。
* 但是我们的类名和表名,属性名和数据库字段名就一定会对应吗?比如我得表名是“db_user”
* 我们可以使用配置文件达到效果,这里我们使用注解实现
*
*/
// String tableName=beanClass.getSimpleName();
String tableName=beanClass.getAnnotation(Table.class).value();
Field[] fields=beanClass.getDeclaredFields();
Map<String,Object> map=new LinkedHashMap<String, Object>();//这个是为了有序
for(Field f:fields){
Annotation[] anns=f.getAnnotations();
for(Annotation a:anns){
if(a.annotationType()==ID.class){
id=f.getAnnotation(ID.class).value();//这里只是针对简单的单个id的情况
map.put(id, f.getName());
break;
}else if(a.annotationType()==Column.class){
map.put(f.getAnnotation(Column.class).value(), f.getName());
break;
}
}
}
String sql="insert into "+tableName+" values (";
// for(int i=0;i<fields.length;i++){
// sql=sql+"?";
// if(i<fields.length-1){
// sql=sql+",";
// }
// }
for(int i=0;i<map.size();i++){
sql=sql+"?";
if(i<map.size()-1){
sql=sql+",";
}
}
sql=sql+")";
System.out.println(sql);
// String sql="insert into "+"标名"+" values ("+"几个?"+")";
// Object[] params={};
/*
* 当字段类型为boolean类型的时候,其getXxx或者isXxx都有可能
*
*
*/
// Object[] params=new Object[fields.length];
ArrayList<Object> params=new ArrayList<Object>();
// for(int i=0;i<fields.length;i++){
// Field f=fields[i];
//
// String methodName="get"+f.getName().substring(0, 1).toUpperCase()+f.getName().substring(1);
// Method method = null ;
// try {
// method = beanClass.getMethod(methodName);
// } catch (NoSuchMethodException e) {
// if(f.getType().getName().equals("boolean")){
// methodName="is"+f.getName().substring(0, 1).toUpperCase()+f.getName().substring(1);
// method=beanClass.getMethod(methodName);
// }
// }
//
// params[i]=method.invoke(bean);
// }
Set<String> keys=map.keySet();
for(String key:keys){
String filedName=(String) map.get(key);
Field f=beanClass.getDeclaredField(filedName);
String methodName="get"+filedName.substring(0, 1).toUpperCase()+filedName.substring(1);
Method method=null;
try {
method = beanClass.getMethod(methodName);
} catch (NoSuchMethodException e) {
if(f.getType().getName().equals("boolean")){
methodName="is"+filedName.substring(0, 1).toUpperCase()+filedName.substring(1);
method=beanClass.getMethod(methodName);
}else{
throw e;
}
}
params.add(method.invoke(bean));
} System.out.println(params.toString());
return 0;
// return qr.update(sql,params);
} public int delete(String uuid) throws SQLException{
String sql="";
Object[] params={};
return qr.update(sql,params);
} public int update(T bean) throws SQLException{
String sql="";
Object[] params={};
return qr.update(sql,params);
} public T load(String uuid) throws SQLException{
String sql="";
Object[] params={};
return null;
} public List<T> findAll(){
String sql="";
Object[] params={};
return null;
} } package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
String value();
} package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ID {
String value();
} package test; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Table {
String value();
} package test; @Table("tb_user")
public class User {
@ID("id")
private String id;
@Column("uname")
private String username;
@Column("pwd")
private String password;
@Column("state")
private boolean state;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public boolean isState() {
return state;
}
public void setState(boolean state) {
this.state = state;
}
public User() {
super();
}
public User(String id, String username, String password, boolean state) {
super();
this.id = id;
this.username = username;
this.password = password;
this.state = state;
} }
泛型,注解,反射配合优化BaseDao的猜想的更多相关文章
- Android高效率编码-findViewById()的蜕变-注解,泛型,反射
Android高效率编码-findViewById()的蜕变-注解,泛型,反射 Android的老朋友findViewById()篇! 先看看他每天是在干什么 //好吧,很多重复的,只不过想表达项目里 ...
- 编写高质量代码:改善Java程序的151个建议(第7章:泛型和反射___建议106~109)
建议106:动态代理可以使代理模式更加灵活 Java的反射框架提供了动态代理(Dynamic Proxy)机制,允许在运行期对目标类生成代理,避免重复开发.我们知道一个静态代理是通过主题角色(Prox ...
- C# 之 反射性能优化1
反射是一种很重要的技术,然而它与直接调用相比性能要慢很多,因此如何优化反射性能也就成为一个不得不面对的问题. 目前最常见的优化反射性能的方法就是采用委托:用委托的方式调用需要反射调用的方法(或者属性. ...
- C# 之 反射性能优化3
阅读目录 开始 用Delegate优化反射的缺点 用Delegate优化反射的优点 用CodeDOM优化反射的优点 如何用好CodeDOM? 用CodeDOM优化反射的缺点 能不能不使用委托? 根据反 ...
- C# 之 反射性能优化2
问题回顾 在上篇博客中,我介绍了优化反射的第一个步骤:用委托调用代替直接反射调用. 然而,那只是反射优化过程的开始,因为新的问题出现了:如何保存大量的委托? 如果我们将委托保存在字典集合中,会发现这种 ...
- Java学习:注解,反射,动态编译
狂神声明 : 文章均为自己的学习笔记 , 转载一定注明出处 ; 编辑不易 , 防君子不防小人~共勉 ! Java学习:注解,反射,动态编译 Annotation 注解 什么是注解 ? Annotat ...
- .NET反射的优化
写在前面 1)本篇博客并非原创,而是我针对.NET反射相关知识的总结.本篇内容来源汇总于3篇博客.在后面的介绍中会在开头给出对应的链接,方便读者自行学习.2)本篇博客主要针对表达式树代码进行详细讲解. ...
- JAVA的泛型与反射的联合应用
通过泛型与反射的结合,可以编写框架来使开发更容易,这里演示的是BaseDao部分的简单使用. BaseDao部分代码: public abstract class BaseDao<T>{ ...
- 枚举类&&注解&&反射
什么是枚举类? 枚举类是优化定义固定对象的一种特殊的类. 换句话说,在需要类的实例为一个或者多个并且相对固定的时候,使用枚举类.(枚举类可扩展) 类的实例相对来说固定的有日期,客观不变的一些数字等等. ...
随机推荐
- vuforia 中摄像机的开启与关闭
本文主要讲解的是Unity对Vuforia的开发中在原生调用摄像头上遇到的坑~Unity中调用设备摄像头打开或则关闭,或则开关扫描识别问题等等一些情况~ 下面先说说趟过的坑,再说说解决办法,或则目前没 ...
- Java学习笔记——java介绍
Java开源语言 C语言闭源语言 IOS闭源系统 采用object-c语言开发 应用程序分类(从类型分类) C/S(Client Server):不联网的软件也属于C/S B/S(Browser S ...
- 九度OJ 1252:回文子串 (字符串处理、DP)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:387 解决:224 题目描述: 输入一个字符串,输出该字符串中对称的子字符串的最大长度. 比如输入字符串"google" ...
- GCD多线程在swift中的变化
1.异步线程加载主线程刷新 DispatchQueue.global().async { // TODO:执行异步线程网络请求 DispatchQueue.main.async(execute: { ...
- php本周、本月的第一天 / 最后一天的时间
//week $time1 = mktime(0, 0, 0, date("m"), date("d") - date("w") + 1, ...
- PAT 1051. 复数乘法 (15)
复数可以写成(A + Bi)的常规形式,其中A是实部,B是虚部,i是虚数单位,满足i2 = -1:也可以写成极坐标下的指数形式(R*e(Pi)),其中R是复数模,P是辐角,i是虚数单位,其等价于三角形 ...
- 2.Django命令行工具搭建项目(django-admin.py & manage.py)
1.概念: django-admin.py是django的用于管理任务的命令行工具 manage.py是对django-admin.py的简单包装,每个project里会有一个自己的manage.py ...
- python基础1 ---python简介
python基础 一.python前言 1.什么是编程语言 编程语言是程序员与计算机之间沟通的介质. 2.编程语言的分类 机器语言:机器语言是用二进制代码表示的计算机能直接识别和执行的一种机器指令的集 ...
- [转]详解Java解析XML的四种方法
XML现在已经成为一种通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便.对于XML本身的语法知识与技术细节,需要阅读相关的技术文献,这里面包括的内容有DOM ...
- 20145229吴姗珊《Java程序设计》第二周学习总结
教材学习内容总结 一.类型.变量与运算符 1.类型 整数:可细分为short整数.int整数和long整数.不同长度的整数可储存的整数范围也不同. 字节:byte类型顾名思义.长度就是一字节,需要逐字 ...