泛型DAO

最近正在学习泛型DAO,通过网上查阅资料,汇总并自己整理了一下。提前需要学习的知识java反射、泛型

用到的反射如下:

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语言访问控制检查的能力

有人肯定会问什么是参数化类型?

参数化类型就是一个编译器可以自动定制作用于特定类型上的类,个人理解就是泛型

什么是原始类型?

一个原始类型就是一个没有任何类型参数的泛型类或者泛型接口的名字。

eg:List<E> 是一个泛型接口,List<String>是一个参数化的类型,List就是一个原生类型

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实体类:

 1 package zhr.bean;
 2
 3 public class User {
 4     private int id;
 5     private String username;
 6     private String password;
 7
 8     public int getId() {
 9         return id;
10     }
11
12     public void setId(int id) {
13         this.id = id;
14     }
15
16     public String getUsername() {
17         return username;
18     }
19
20     public void setUsername(String username) {
21         this.username = username;
22     }
23
24     public String getPassword() {
25         return password;
26     }
27
28     public void setPassword(String password) {
29         this.password = password;
30     }
31
32     @Override
33     public String toString() {
34         return "User [id=" + id + ", username=" + username + ", password=" + password + "]";
35     }
36
37 }

BaseDao接口:

 1 package zhr.dao;
 2
 3 public interface BaseDao<T> {
 4     T selectByID(int id);
 5
 6     T select(T t);
 7
 8     void add(T t);
 9
10     void update(T t);
11
12     void delete(T t);
13 }

UserDao接口:

1 package zhr.dao;
2
3 import java.util.List;
4
5 import zhr.bean.User;
6
7 public interface UserDao extends BaseDao<User> {
8     List<User> findAll();
9 }

BaseDaoImpl实现类:

  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 }

UserDaoImpl实现类:

 1 package zhr.daoimpl;
 2
 3 import java.lang.reflect.ParameterizedType;
 4 import java.sql.Connection;
 5 import java.sql.PreparedStatement;
 6 import java.sql.ResultSet;
 7 import java.util.ArrayList;
 8 import java.util.List;
 9
10 import util.ConnectionManager;
11 import zhr.bean.User;
12 import zhr.dao.UserDao;
13
14 public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao {
15
16     private Connection conn;
17     private PreparedStatement ps;
18     private ResultSet rs;
19     private Class<User> EntityClass;// 获取实体类
20     private List<User> list;
21     private String sql;
22
23     public UserDaoImpl() {
24         /**
25          * 传递User就是 com.example.daoimp.BaseDaoImpl<com.example.bean.User> 传递Shop就是
26          * com.example.daoimp.BaseDaoImpl<com.example.bean.Shop>
27          */
28         ParameterizedType type = (ParameterizedType) getClass().getGenericSuperclass();
29         /**
30          * 这里如果传递的是User.那么就是class com.example.bean.User 如果传递的是Shop. 那么就是class
31          * com.example.bean.Shop
32          */
33
34         EntityClass = (Class<User>) type.getActualTypeArguments()[0];
35     }
36
37     @Override
38     public List<User> findAll() {
39         StringBuffer b = new StringBuffer();
40         list = new ArrayList<User>();
41         sql = b.append("select * from " + EntityClass.getSimpleName()).toString();
42         try {
43             conn = ConnectionManager.getConnection();
44             ps = conn.prepareStatement(sql);
45             rs = ps.executeQuery();
46             while (rs.next()) {
47                 User user = new User();
48                 user.setId(rs.getInt("id"));
49                 user.setUsername(rs.getString("username"));
50                 user.setPassword(rs.getString("password"));
51                 list.add(user);
52             }
53         } catch (Exception e) {
54             e.printStackTrace();
55         }
56         return list;
57     }
58
59 }

ConnectionManager工具类:

 1 package util;
 2
 3 import java.sql.Connection;
 4 import java.sql.DriverManager;
 5 import java.sql.SQLException;
 6
 7 public class ConnectionManager {
 8     public static Connection getConnection() {
 9         Connection conn = null;
10         String url = "jdbc:mysql://localhost:3306/test";
11         String username = "root";
12         String password = "root";
13         try {
14             Class.forName("com.mysql.jdbc.Driver");
15             conn = DriverManager.getConnection(url, username, password);
16         } catch (ClassNotFoundException e) {
17             e.printStackTrace();
18             System.out.println("没有找到文件");
19         } catch (SQLException e) {
20             e.printStackTrace();
21             System.out.println("sql异常");
22         }
23         return conn;
24     }
25 }

测试类:

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);
         */

    }
}

时隔一年,再次写博客,希望大家互相支持,相互学习,有不对的地方可以评论留言。记得粉我噢~谢谢大家。

时间: 2024-08-29 22:23:43

泛型DAO的相关文章

基于SpringJdbc的泛型Dao

> 使用的Spring是3.1版本,不是3.0版本.两者还是有区别的,其中一点就是:SimpleJdbcTemplate在3.1版本被标记为过时了,而SimpleJdbcTemplate的一些方法,被JdbcTemplate吸收了.所以,个人推荐使用3.1版本. 需要的JAR文件: org.springframework.aop-3.1.0.RELEASE.jar org.springframework.asm-3.1.0.RELEASE.jar org.springframework.bean

hibernate3泛型Dao

已经有1年没有使用hibernate了,公司已经基本转到mybatis,一直很怀念当年hibernate通用泛型Dao的方式,只需要写好sql设置好返回的object,现在感觉mybatis这方面我还是太弱小. 先定义个接口 package com.fangj.core.platform.common; import java.util.*; import java.io.Serializable; import org.hibernate.criterion.Criterion; import

SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装

SpringJdbc持久层封装,Spring jdbcTemplate封装,springJdbc泛型Dao,Spring baseDao封装 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年7月6日 http://www.cnblogs.com/fanshuy

Android 使用ORMLite打造万能泛型Dao简化数据持久化层

前面的一篇文章Android ORM系列之ActiveAndroid 介绍了ActiveAndroid的使用方法,但是ActiveAndroid有一个很明显的缺点,就是所有的实体类必须继承Model类才能进行CRUD,这是典型的php中的ActiveRecord方式的数据库操作.这时候我们会想一下,在Java Web中,hibernate或者mybatis就很好,其实在android中也有这么一个框架,但是这个框架是java的,只不过它支持Android而已,它就是ORMLite.这篇文章不会过

Hibernate也需要呵护——Hibernate的泛型DAO

众所周之,面向对象的基础是抽象.也可以说,抽象促使编程在不断发展.对于数据库的访问,曾经写过HqlHelper,EFHelper.编写Spring+Hibernate框架下的应用,也同样离不了编写一个通用的泛型GenericHibernateDao.查阅了网上不少的GenericHibernateDao实现,归纳整理为如下实现,供后续编码参考. 一. DAO泛型的接口 GenericDao package ICT.framework.orm.hibernate; import java.io.S

JPA的泛型DAO设计及使用

使用如Hibernate或者JPA作为持久化的解决方案时,设计一个泛型的DAO抽象父类可以方便各个实体的通用CRUD操作.由于此时大部分实体DAO的CRUD操作基本一样,采用泛型设计解决这个问题,带来了简洁代码的好处. 问题的关键在于我们需要在代码中获取抽象DAO父类(BaseEntityDAOImpl<T>)中的泛型信息. 由于Java的泛型是基于泛型擦除实现的,因此无法直接获取如果直接获取,在Java中,如果子类继承一个泛型的父类,会保存父类中泛型的信息,因此可以采用如下方法获取泛型信息.

反射泛型,Dao设计模型 (编码时需要用到)

Dao package com.xiaofan.reflect; import java.io.Serializable; public interface Dao<T> { /** * 添加实体(Entity--Domain)数据到数据库中 * @param t */ void save(T t); /** * 修改数据库中的实体 * @param t */ void update(T t); /** * 根据主键删除记录 * @param pk */ void delete(Seriali

Hibernate 泛型Dao实现

package com.esailcar.finance.common.persistence; import java.io.Serializable; import java.lang.reflect.ParameterizedType; import java.lang.reflect.Type; import java.sql.SQLException; import java.util.List; import org.hibernate.Session; import org.hib

使用getGenericSuperclass()和getActualTypeArguments()将DAO做成泛型

一.getGenericSuperclass()和getActualTypeArguments()基本用法: import java.lang.reflect.ParameterizedType; public class TT extends TT2<Integer> { public static void main(String[] args) { System.out.println(((ParameterizedType) new TT().getClass() .getGeneri