浅谈Java——泛型DAO
首先解释一下为什么要学习泛型DAO。平时在写DAO的时候是一个接口对应一个实现类,实现类里面要写很多的操作数据库的方法。当我们有很多的javaben的时候我们会写很多的接口和实现类,并且里面的代码都是相同的,这样太麻烦,我们就不能写一个类,在类里面传入泛型,让类根据泛型,创建出一个实例对象,这样就出现了泛型DAO。
一、需要提前准备的知识如下
反射关键的类:
Class<T>类 是java.lang包下,Class类的实例表示正在运行的 Java 应用中的类和接口。
Type接口 是java.lang.reflect包下的是Java类型的通用超级接口。这些包括原始类型,参数化类型,数组类型和类型变量
ParameterizedType接口 是java.lang.reflect包下是Type的子接口,表示一个参数化类型,如Collection<String>
Field类 是java.lang.reflect包下,提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实体字段
AccessibleObject类 是java.lang.reflect包下,是Filed、Method和Constructor对象的基类。提供了将反射的对象标记为在使用时取消默认 Java语言访问控制检查的能力
反射关键的方法:
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
//getGenericSuperclass() 返回此Class 所有的实体(类、接口、基本类型或者void)的直接超类的 Type
Class<T> entityClass = (Class<T>) type.getActualTypeArguments()[0];
//getActualTypeArguments() 返回此类型的实际类型参数的数组Type对象
getDeclaredFields() 返回 Field 对象的一个数组,这些对象所表示的类或接口所声明的所有字段。(公共、保护、默认、私有字段,不包括继承的字段)
newInstance() 创建此 Class 对象的新实例
setAccessible(boolean flag) 值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。值为 false 则实施访问检查
二、下面是泛型DAO的源码
User实体类:主要声明一个实体,get、set方法来获取实体的属性
package zhr.bean; public class User {
private int id;
private String username;
private String password; public int getId() {
return id;
} public void setId(int 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;
} @Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
} }
BaseDao接口:用来写泛型DAO的核心接口主要就是一些增删改查的方法
package zhr.dao; public interface BaseDao<T> {
T selectByID(int id); T select(T t); void add(T t); void update(T t); void delete(T t);
}
UserDao接口:主要DAO接口,类似的DAO接口也可以写这样只需要继承BaseDao接口就可以,提高了代码的复用性,也可以自己定义功能方法
package zhr.dao; import java.util.List; import zhr.bean.User; public interface UserDao extends BaseDao<User> {
List<User> findAll();
}
BaseDaoImpl实现类:实现BaseDao接口,构造方法使用了反射获取实体类,这是泛型DAO核心实现类,需要详细写,增删改查,或者更多功能,比如通过id来查询,或者给两个参数查询between and,大于或者小于 核心思想就是反射。
1 package zhr.daoimpl;
2
3 import java.lang.reflect.Field;
4 import java.lang.reflect.ParameterizedType;
5 import java.sql.Connection;
6 import java.sql.PreparedStatement;
7 import java.sql.ResultSet;
8 import java.sql.SQLException;
9
10 import util.ConnectionManager;
11 import zhr.dao.BaseDao;
12
13 public class BaseDaoImpl<T> implements BaseDao<T> {
14
15 private Connection conn;
16 private PreparedStatement ps;
17 private ResultSet rs;
18 private Class<T> EntityClass;// 获取实体类
19
20 @SuppressWarnings("unchecked")
21 public BaseDaoImpl() {
22 /**
23 * 传递User就是 zhr.daoimpl.BaseDaoImpl<zhr.bean.User> 传递Shop就是
24 * zhr.daoimpl.BaseDaoImpl<zhr.bean.Shop>
25 */
26 ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
27 System.out.println(type);
28 /**
29 * 这里如果传递的是User.那么就是zhr.bean.User 如果传递的是Shop. 那么就是zhr.bean.Shop
30 *
31 */
32
33 EntityClass = (Class<T>) type.getActualTypeArguments()[0];
34 System.out.println(EntityClass);
35 }
36
37 @Override
38 public T selectByID(int id) {
39 StringBuffer sqlb = new StringBuffer();
40 // 通过反射获取实体类中的所有变量
41 Field fields[] = EntityClass.getDeclaredFields();
42 sqlb.append("select * from " + EntityClass.getSimpleName() + " where id=?");
43 T obj = null;
44 try {
45 conn = ConnectionManager.getConnection();
46 ps = conn.prepareStatement(sqlb.toString());
47 ps.setInt(1, id);
48 rs = ps.executeQuery();
49 fields = EntityClass.getDeclaredFields();
50 while (rs.next()) {
51 obj = EntityClass.newInstance();
52 for (int i = 0; i < fields.length; i++) {
53 fields[i].setAccessible(true);
54 fields[i].set(obj, rs.getObject(fields[i].getName()));
55 }
56 }
57
58 } catch (SQLException e) {
59 e.printStackTrace();
60 } catch (InstantiationException e) {
61 e.printStackTrace();
62 } catch (IllegalAccessException e) {
63 e.printStackTrace();
64 }
65 return obj;
66 }
67
68 @Override
69 public T select(T t) {
70 StringBuffer sqlb = new StringBuffer();
71 // 通过反射获取实体类中的所有变量
72 Field fields[] = EntityClass.getDeclaredFields();
73 sqlb.append("select * from " + EntityClass.getSimpleName() + " where id=?");
74 T obj = null;
75 try {
76 conn = ConnectionManager.getConnection();
77 ps = conn.prepareStatement(sqlb.toString());
78 fields[0].setAccessible(true);
79 ps.setInt(1, (int) fields[0].get(t));
80 rs = ps.executeQuery();
81 fields = EntityClass.getDeclaredFields();
82 while (rs.next()) {
83 obj = EntityClass.newInstance();
84 for (int i = 0; i < fields.length; i++) {
85 fields[i].setAccessible(true);
86 fields[i].set(obj, rs.getObject(fields[i].getName()));
87 }
88 }
89
90 } catch (SQLException e) {
91 e.printStackTrace();
92 } catch (InstantiationException e) {
93 e.printStackTrace();
94 } catch (IllegalAccessException e) {
95 e.printStackTrace();
96 }
97 return obj;
98 }
99
100 // insert into User(id,username,password) values (?,?,?);
101 @Override
102 public void add(T t) {
103 StringBuffer sql = new StringBuffer();
104 Field fields[] = EntityClass.getDeclaredFields();
105 sql.append("insert into " + EntityClass.getSimpleName());
106 sql.append("(");
107 for (int i = 0; fields != null && i < fields.length; i++) {
108 fields[i].setAccessible(true); // 这句话必须要有,否则会抛出异常.
109 String column = fields[i].getName();
110 sql.append(column).append(",");
111 }
112 sql = sql.deleteCharAt(sql.length() - 1);// 删除最后一个,
113 sql.append(") values (");
114 for (int i = 0; fields != null && i < fields.length; i++) {
115 sql.append("?,");
116 }
117 sql.deleteCharAt(sql.length() - 1);// 删除最后一个,
118 sql.append(")");
119 try {
120 conn = ConnectionManager.getConnection();
121 ps = conn.prepareStatement(sql.toString());
122 Object obj[] = new Object[fields.length];
123 for (int i = 0; obj != null && i < fields.length; i++) {
124 fields[i].setAccessible(true);// AccessibleTest类中的成员变量为private,故必须进行此操
125 obj[i] = fields[i].get(t);
126 }
127
128 for (int i = 0; i < obj.length; i++) {
129 ps.setObject(i + 1, obj[i]);
130 }
131 ps.executeUpdate();
132 System.out.println("添加成功");
133
134 } catch (SQLException e) {
135 e.printStackTrace();
136 } catch (IllegalArgumentException e) {
137 e.printStackTrace();
138 } catch (IllegalAccessException e) {
139 e.printStackTrace();
140 } finally {
141 try {
142 ps.close();
143 } catch (SQLException e) {
144 e.printStackTrace();
145 }
146 try {
147 conn.close();
148 } catch (SQLException e) {
149 e.printStackTrace();
150 }
151 }
152
153 }
154
155 // update User set username=?,password=? where id=?
156 @Override
157 public void update(T t) {
158 StringBuffer sql = new StringBuffer();
159 Field fields[] = EntityClass.getDeclaredFields();
160 sql.append("update " + EntityClass.getSimpleName() + " set ");
161 for (int i = 0; fields != null && i < fields.length; i++) {
162 fields[i].setAccessible(true);
163 String column = fields[i].getName();
164 if (column.equals("id")) {
165 continue;
166 }
167 sql.append(column).append("=").append("?,");
168 }
169 sql.deleteCharAt(sql.length() - 1);
170 sql.append(" where id=?");
171
172 try {
173 conn = ConnectionManager.getConnection();
174 ps = conn.prepareStatement(sql.toString());
175
176 Object Tempobj[] = new Object[fields.length];
177 for (int i = 0; Tempobj != null && i < fields.length; i++) {
178 fields[i].setAccessible(true);
179 Tempobj[i] = fields[i].get(t);
180 }
181 Object obj[] = new Object[fields.length];
182 System.arraycopy(Tempobj, 1, obj, 0, Tempobj.length - 1);
183 obj[obj.length - 1] = Tempobj[0];
184
185 for (int i = 0; i < obj.length; i++) {
186 ps.setObject(i + 1, obj[i]);
187 }
188
189 ps.executeUpdate();
190 System.out.println("更新成功");
191
192 } catch (SQLException e) {
193 e.printStackTrace();
194 } catch (IllegalArgumentException e) {
195 e.printStackTrace();
196 } catch (IllegalAccessException e) {
197 e.printStackTrace();
198 } finally {
199 try {
200 ps.close();
201 } catch (SQLException e) {
202 e.printStackTrace();
203 }
204 try {
205 conn.close();
206 } catch (SQLException e) {
207 e.printStackTrace();
208 }
209 }
210
211 }
212
213 @Override
214 public void delete(T t) {
215 StringBuffer sql = new StringBuffer();
216 Field fields[] = EntityClass.getDeclaredFields();
217
218 sql.append("delete from " + EntityClass.getSimpleName() + " where id=?");
219
220 try {
221 conn = ConnectionManager.getConnection();
222 ps = conn.prepareStatement(sql.toString());
223
224 Object obj[] = new Object[1];
225 fields[0].setAccessible(true);
226 obj[0] = fields[0].get(t);
227
228 for (int i = 0; i < obj.length; i++) {// 设置参数
229 ps.setObject(i + 1, obj[i]);
230 }
231
232 ps.executeUpdate();
233 System.out.println("删除成功");
234
235 } catch (SQLException e) {
236 e.printStackTrace();
237 } catch (IllegalArgumentException e) {
238 e.printStackTrace();
239 } catch (IllegalAccessException e) {
240 e.printStackTrace();
241 } finally {
242 try {
243 ps.close();
244 } catch (SQLException e) {
245 e.printStackTrace();
246 }
247 try {
248 conn.close();
249 } catch (SQLException e) {
250 e.printStackTrace();
251 }
252 }
253
254 }
255
256 }
BaseDaoImpl实现类
UserDaoImpl实现类:这是用户的实现类,继承了BaseDaoImpl并且实现 UserDao
package zhr.daoimpl; import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List; import util.ConnectionManager;
import zhr.bean.User;
import zhr.dao.UserDao; public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao { private Connection conn;
private PreparedStatement ps;
private ResultSet rs;
private Class<User> EntityClass;// 获取实体类
private List<User> list;
private String sql; public UserDaoImpl() {
/**
* 传递User就是 com.example.daoimp.BaseDaoImpl<com.example.bean.User> 传递Shop就是
* com.example.daoimp.BaseDaoImpl<com.example.bean.Shop>
*/
ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
/**
* 这里如果传递的是User.那么就是class com.example.bean.User 如果传递的是Shop. 那么就是class
* com.example.bean.Shop
*/ EntityClass = (Class<User>) type.getActualTypeArguments()[0];
} @Override
public List<User> findAll() {
StringBuffer b = new StringBuffer();
list = new ArrayList<User>();
sql = b.append("select * from " + EntityClass.getSimpleName()).toString();
try {
conn = ConnectionManager.getConnection();
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
User user = new User();
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
list.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}
return list;
} }
ConnectionManager工具类:主要用来获取连接Connection
package util; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class ConnectionManager {
public static Connection getConnection() {
Connection conn = null;
String url = "jdbc:mysql://localhost:3306/test";
String username = "root";
String password = "root";
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(url, username, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
System.out.println("没有找到文件");
} catch (SQLException e) {
e.printStackTrace();
System.out.println("sql异常");
}
return conn;
}
}
测试类:
ackage zhr.test; import java.util.List; import zhr.bean.User;
import zhr.dao.UserDao;
import zhr.daoimpl.UserDaoImpl; public class Test {
public static void main(String[] args) {
List<User> list = null;
UserDaoImpl imp = new UserDaoImpl();
list = imp.findAll();
for (User user : list) {
System.out.println(user.getId() + " " + user.getUsername() + " " + user.getPassword());
}
// 查询
User ua = (User) imp.selectByID(1);// 通过id查询User
System.out.println(ua.getClass().getSimpleName());
System.out.println(ua);
System.out.println(ua.getId() + " " + ua.getUsername() + " " + ua.getPassword()); /*
* 添加操作 User user = new User(); user.setId(11); user.setUsername("zhr");
* user.setPassword("123456"); imp.add(user);
*/ /*
* 更新操作 User user1 = new User(); user1.setId(1); user1.setUsername("hhh");
* user1.setPassword("123"); imp.update(user1);
*/ /*
* 删除操作 User user2 = new User(); user2.setId(11); user2.setUsername("zhr");
* user2.setPassword("123456"); imp.delete(user2);
*/ }
}
时隔一年,再次写博客,希望大家互相支持,相互学习,有不对的地方可以评论留言。记得粉我噢~谢谢大家。
浅谈Java——泛型DAO的更多相关文章
- 浅谈Java泛型之<? extends T>和<? super T>的区别
关于Java泛型,这里我不想总结它是什么,这个百度一下一大堆解释,各种java的书籍中也有明确的定义,只要稍微看一下就能很快清楚.从泛型的英文名字Generic type也能看出,Generic普通. ...
- 浅谈Java泛型中的extends和super关键字(转)
通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: 向上造型一个泛型对象的引用 向下造型一个泛型对象的引用 向上造型一个泛型对象 ...
- 浅谈Java泛型中的extends和super关键字
泛型是在Java 1.5中被加入了,这里不讨论泛型的细节问题,这个在Thinking in Java第四版中讲的非常清楚,这里要讲的是super和extends关键字,以及在使用这两个关键字的时候为什 ...
- 浅谈Java泛型中的? extends E和?super E
https://blog.csdn.net/zymx14/article/details/78073757
- 浅谈java类集框架和数据结构(2)
继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...
- 浅谈Java的反射机制和作用
浅谈Java的反射机制和作用 作者:Java大师 欢迎转载,转载请注明出处 很多刚学Java反射的同学可能对反射技术一头雾水,为什么要学习反射,学习反射有什么作用,不用反射,通过new也能创建用户对象 ...
- 浅谈Java的throw与throws
转载:http://blog.csdn.net/luoweifu/article/details/10721543 我进行了一些加工,不是本人原创但比原博主要更完善~ 浅谈Java异常 以前虽然知道一 ...
- 浅谈Java中的equals和==(转)
浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str ...
- 浅谈Java中的对象和引用
浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是“对象和对象引用”,很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起 ...
随机推荐
- 解析ASP.NET Mvc开发之EF延迟加载 分类: ASP.NET 2014-01-04 01:29 4017人阅读 评论(1) 收藏
目录: 从明源动力到创新工场这一路走来 解析ASP.NET WebForm和Mvc开发的区别 解析ASP.NET 和Mvc开发之查询数据实例 ----------------------------- ...
- asp.net页面传值方法汇总
1. Get(即使用QueryString显式传递) 方式:在url后面跟参数. 特点:简单.方便. 缺点:字符串长度最长为255个字符:数据泄漏在url中. 适用数据 ...
- PyCharm2018专业版激活步骤
激活步骤: 1.更改hosts文件,2 获取注册码, 3 完成注册. 1. 更改host文件 hosts文件的路径 : c:\windows\system32\drivers\etc\hosts 将 ...
- 共识算法:Paxos
两阶段提交 Two-phase Commit(2PC):保证一个事务跨越多个节点时保持 ACID 特性: 两类节点:协调者(Coordinator)和参与者(Participants),协调者只有一个 ...
- WPF获取相对位置、坐标的方法
1.获取鼠标在控件中的坐标: private void item_MouseDown(object sender, MouseButtonEventArgs e) { Point point = e. ...
- 触摸UITextView找到该触摸点的文字
参加了一个比赛有一道题是如标题一样,在UITextView上触摸找到该触摸点对应的文字,比赛也可以查资料,当时做的时候就是抱着玩玩的心态试试也没认真做,就没查就去吃饭去了,昨晚下班回去在思考这个问题发 ...
- mariadb(mysql)从库relaylog损坏无法同步的处理方法
故障说明 晚上备用服务器自动重启,收到报警,备用服务器上的mariadb从库无法去同步主库.启动mariadb后,报如下错误(重点看红色字体) mariadb_1 | -- :: [Note] Pl ...
- wcf win7+iis7 异常消息为: 可能证书“CN=PmsWcfServer”没有能够进行密钥交换的私钥
原因是证书没有用户权限,解决方法: 1.开始-运行-mmc 2.添加[证书]管理单元 3.选择[证书(本地计算机)]-[个人]-[证书],右击PmsWcfServer证书-[所有任务]-[管理密钥] ...
- SpringBoot(三) Core Features: External Configuration(配置文件)
码云: external-configuration 可以使用属性文件,YAML文件,环境变量和命令行参数来外部化配置 一.属性值可以直接注入到bean 系统属性值不可以 // application ...
- Java Swing实战(一)JFrame和JTabbedPane容器
概述: 项目是一个桌面程序,涉及标签和按钮组件.布局管理器组件.面板组件.列表框和下拉框组件等组件,以及Swing事件处理机制. 下面先从最基础的界面开始. /** * @author: lishua ...