泛型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);
- */
- }
- }
时隔一年,再次写博客,希望大家互相支持,相互学习,有不对的地方可以评论留言。记得粉我噢~谢谢大家。
泛型DAO的更多相关文章
- 泛型DAO与泛型Service
泛型Dao与Service 看了几个帖子,泛型Dao与Service的主要目的就是要减少重复代码.具体的说明如下: 1. 定义一个BaseDao接口,此接口包含了一些通用的DAO操作,例如:增加.删除 ...
- 一个好用的hibernate泛型dao
以前从springside2.0上搞下来的很好用的,基本实现dao零编码只要配置xml文件就行了. 先看图: 一共4层,com.demonstration.hibernate.basedao是我加的用 ...
- SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装
SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>& ...
- 《项目架构那点儿事》——Hibernate泛型Dao,让持久层简洁起来
[前言]hibernate作为持久层ORM技术,它对JDBC进行非常轻量级对象封装,使得我们可以随心所欲的使用面向对象的思想来操作数据 库.同时,作为后台开发的支撑,的确扮演了一个举足轻重的角色,那么 ...
- 自己动手写泛型dao
在经过一系列的问题得到解决之后,泛型dao终于写出来了.泛型dao相比于以前写的dao最大的好处就是,大大提高了代码的复用性,以往我们要对数据库中表中的数据进行操作的时候,每张表都需要写一个dao来操 ...
- 浅谈Java——泛型DAO
首先解释一下为什么要学习泛型DAO.平时在写DAO的时候是一个接口对应一个实现类,实现类里面要写很多的操作数据库的方法.当我们有很多的javaben的时候我们会写很多的接口和实现类,并且里面的代码都是 ...
- JPA的泛型DAO设计及使用
使用如Hibernate或者JPA作为持久化的解决方案时,设计一个泛型的DAO抽象父类可以方便各个实体的通用CRUD操作.由于此时大部分实体DAO的CRUD操作基本一样,采用泛型设计解决这个问题,带来 ...
- Hibernate也须要呵护——Hibernate的泛型DAO
众所周之.面向对象的基础是抽象.也能够说,抽象促使编程在不断发展. 对于数据库的訪问,以前写过HqlHelper.EFHelper.编写Spring+Hibernate框架下的应用.也相同离不了编写一 ...
- 泛型DAO模型设计
aaarticlea/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAMCAgMCAgMDAwMEAwMEBQgFBQQEBQoHBwYIDAoMDAsKC
随机推荐
- 深入浅出数据结构C语言版(22)——排序决策树与桶式排序
在(17)中我们对排序算法进行了简单的分析,并得出了两个结论: 1.只进行相邻元素交换的排序算法时间复杂度为O(N2) 2.要想时间复杂度低于O(N2),算法必须进行远距离的元素交换 而今天,我们将对 ...
- Free Goodies UVA - 12260 贪心
Free Goodies Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & %llu [Submit ...
- 简单Elixir游戏服设计-玩法simple_poker
上回介绍了玩法,现在编写了玩法的简单建模. 做到现在感觉目前还没有使用umbrella的必要(也许以后会发现必要吧),model 应用完全可以合并到game_server. 代码还在https://g ...
- 【疑问】用python写登录验证遇到的问题
最近开始断断续续学习python,今天加入博客园,作为新人,和各位老师们讨教了,以后多多照顾!为了大家能看清楚所以就截图了,文末尾附源码,说不定会有那位老师给我指教一番.############### ...
- Mysql [Err] 1293 there can be only one TIMESTAMP column with CURRENT_TIMESTAMP in DEFAULT or ON UPDATE clause
问题: mysql数据 导入数据出错 [Err] 1293 - Incorrect table definition; there can be only one TIMESTAMP column w ...
- 关于AOP装饰函数中的this
在学习关于JavaScript的装饰者设计模式的过程中,发现其实现方式的关键在于this的使用. 想象一个匿名函数(其实预定义的有名函数也可以,都存在引用),其中的this: // 我们先定义一个匿名 ...
- WPF 只允许打开一个实例
我们有时候只希望我们的程序只打开一个实例,也就是我们的软件只有一次被打开. 那么我们可以通过一个办法知道,在这个软件打开前是不是打开过一个,还没关闭.也就是是否存在另一个程序在运行. 下面是一个简单方 ...
- 关于Java和JavaScript对字符串截取处理的总结
在JavaWeb开发中,经常需要对字符串进行处理,包括Java语言和JS语言,总是容易弄混淆,这里简单对比一下两种语言对于字符串截取方法. 一.先看Java public class StringDe ...
- Java 7 JVM和垃圾收集
---恢复内容开始--- 写JAVA程序,一定要了解JVM(JAVA Virtual machine)一些基础知识和垃圾收集.如果对JVM已经很了解了,可以不用继续往下阅读了.本文只针对Java 7, ...
- C 结构体零散知识点
1.结构体无法把自己作为成员,但可以包含指向自己的指针成员 2.定义不完整结构类型(类型,结构,占用空间无法确定,如void指针,声明没有指明数组长度数组)只能使用小标签,即struct struct ...