DAO模式

DAO数据访问对象data access object的缩写,用于进行数据操作的封装,在Java程序开发中属于标准开 发架构中的持久层的设计模式。DAO模式是标准JavaEE设计模式之一,用途在于将底层的数据访问操作和高层的业务逻辑分离开。 典型的DAO模式的组成 一个DAO工厂类,一个DAO接口 实现了DAO接口的多种实现类 数据传输对象DTO,有时简称为VO。

运用JAVA反射机制,获取实体类定义的字段和方法实现一个万能的DAO模式,IBaseDao接口和BaseDaoImpl类定义类通用的增删改查方法,只需用具体的实现类去继承通用方法,泛型传入具体的类型即可。

结构:

dao类:

IBaseDao:一个接口(定义通用的增删改查方法),通过接口暴漏当前层中允许调用的方法

public interface IBaseDao<T extends Serializable> {

    public int save(T t);//增

    public int delete(T t);//删

    public int update(T t);//改

    public List<T> query(T t);//按id查询

    public List<T> findByExample(T t);//整表查询

}

BaseDaoImpl:实现IBaseDao接口定义的方法:

public abstract class BaseDaoImpl<T extends Serializable> implements IBaseDao<T> {
      
	private Class<T> clazz;
	
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public BaseDaoImpl() {
		Class<? extends IBaseDao> clz=this.getClass();
		ParameterizedType pt =(ParameterizedType)clz.getGenericSuperclass();
	    clazz = (Class) pt.getActualTypeArguments()[0];
	}

	@Override
	//insert into tb_user() values();
	public int save(T obj) {
		StringBuilder sb1 = new StringBuilder("insert into tb_");
		sb1.append(clazz.getSimpleName().toLowerCase()).append("(");
		StringBuilder sb2=new StringBuilder(") values (");
		Field[] fs = clazz.getDeclaredFields();//获取当前类的所有字段
		List<Object> params = new ArrayList<>();
		try {
			for (int i = 0; i < fs.length; i++) {
				Field f = fs[i];
				f.setAccessible(true);
				Object val = f.get(obj);
				if (val!=null) {
					sb1.append(f.getName()).append(",");
					sb2.append("?,");
					params.add(val);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		if (sb1.toString().endsWith(",")) {
			sb1.deleteCharAt(sb1.length()-1);
		}
		if (sb2.toString().endsWith(",")) {
			sb2.deleteCharAt(sb2.length()-1);
		}
		String sql = sb1.toString()+sb2.toString()+")";
		return update(sql, params.toArray());
	}
	
	public int update(String sql,Object...params) {
		int res=0;
		try {
			res = JdbcUtils.executeUpdate(sql, params);
		} catch (Exception e) {
			JdbcUtils.releaseConnention();
		}
		return res;
	}

	@Override
	//delete from tb_user where id=?
	public int delete(T obj) {
		StringBuilder sb1 = new StringBuilder("delete from tb_");
		sb1.append(clazz.getSimpleName().toLowerCase()).append(" where 1=1 ");
		Field [] fs = clazz.getDeclaredFields();
		List<Object> params = new ArrayList<>();
		try {
			for (int i = 0; i < fs.length; i++) {
				Field f = fs[i];
				f.setAccessible(true);
				Object val = f.get(obj);
				if (f!=null && val!=null) {
					sb1.append(" and ").append(f.getName()).append(" =? ");
					params.add(val);
				}
			}
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		
		String sql = sb1.toString();
		return update(sql, params.toArray());
	}

	@Override
	//update tb_user set name=?,password=?  where id=?;
	public int update(T obj) {
		StringBuilder sb1 = new StringBuilder("update tb_");
		sb1.append(clazz.getSimpleName().toLowerCase()).append(" set ");
		StringBuilder sb2 = new StringBuilder(" where ");
		Field [] fs = clazz.getDeclaredFields();
		List<Object> params = new ArrayList<>();
		try {
			for (int i = 1; i < fs.length; i++) {
				Field f = fs[i];
				f.setAccessible(true);
				Object val = f.get(obj);
				if (f!=null && val!=null) {
					sb1.append(f.getName()).append(" =?,");
					params.add(val);
				}
			}
			Field f = fs[0];
			f.setAccessible(true);
			sb2.append(f.getName()).append(" =? ");
			Object val = f.get(obj);
			params.add(val);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		if (sb1.toString().endsWith(",")) {
			sb1.deleteCharAt(sb1.length()-1);
		}
		String sql = sb1.toString()+sb2.toString();
		return update(sql, params.toArray());
	}

	@Override
	public List<T> query(T obj) {
		List<T> res = new ArrayList<>();
		try {
			StringBuilder sb = new StringBuilder("select * from tb_");
			sb.append(clazz.getSimpleName().toLowerCase()).append(" where 1=1 ");
			Field[] fs = clazz.getDeclaredFields();
			List<Object> params = new ArrayList<>();
			for (int i = 0; i < fs.length; i++) {
				Field f = fs[i];
				f.setAccessible(true);
				Object val = f.get(obj);
				if (val!=null) {
					sb.append(" and ").append(f.getName()).append(" =? ");
					params.add(val);
				}
			}
			ResultSet rs = JdbcUtils.executeQuery(sb.toString(),params.toArray());
			while (rs.next()) {
				ResultSetMetaData rsemd = rs.getMetaData();
				T t = clazz.newInstance();
				for (int i = 1; i <=rsemd.getColumnCount(); i++) {
					String fieldName = rsemd.getColumnLabel(i);
					Field f = clazz.getDeclaredField(fieldName);
					f.setAccessible(true);
					f.set(t, rs.getObject(i));
				}
				res.add(t);
			}
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnention();
		}
		return res;
	}

	@Override
	public List<T> findByExample(T obj){
		List<T> res = new ArrayList<>();
		List<Object> params = new ArrayList<>();
		StringBuilder sql = new StringBuilder("select * from tb_user;");
		try{
			ResultSet rs = JdbcUtils.executeQuery(sql.toString(),params.toArray());
			while (rs.next()) {
				ResultSetMetaData rsemd = rs.getMetaData();
				T t = clazz.newInstance();
				for (int i = 1; i <=rsemd.getColumnCount(); i++) {
					String fieldName = rsemd.getColumnLabel(i);
					Field f = clazz.getDeclaredField(fieldName);
					f.setAccessible(true);
					f.set(t, rs.getObject(i));
				}
				res.add(t);
			}
			rs.close();
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JdbcUtils.releaseConnention();
		}
		return res;
	}
}

IUserDao和UserDaoImpl:

public interface IUserDao extends IBaseDao<User> {
   //如果需要增加方法,可以在这里声明

}
public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao {
如果有特殊方法,则在这里实现,实际上通用的增删改查方法已经从BaseDao中继承

}

实体类entity:

user:根据对应的表结构定义实体类类名称和表名称对应,属性名称和字段名称对应 类中的属性不要使用简单类型,判断的需要 setObject

public class User implements Serializable {
    private Integer id;
    private String username;
    private String password;

    public User() {

    }

    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer 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 + '\'' +
                '}';
    }
}

工厂类Factory:

Factory:

public class User implements Serializable {
    private Long id;
    private String username;
    private String password;

    public User() {

    }

    public User(Long id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long 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 + '\'' +
                '}';
    }
}

工具类Util类:

public class JdbcUtils {
    private JdbcUtils() {

    }

    private static DataSource ds;
    private static final ThreadLocal<Connection> ts = new ThreadLocal<>();
    static {
        try {
            InputStream is = JdbcUtils.class.getClassLoader().getResourceAsStream("src/jdbc.properties");
            Properties ps = new Properties();
            ps.load(is);
            ds = DruidDataSourceFactory.createDataSource(ps);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取链接
    public static Connection getConnection() {
        Connection res = ts.get();
        if (res == null) {
            try {
                res = ds.getConnection();
                ts.set(res);
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
        }
        return res;
    }

    //释放连接
    public static void releaseConnention() {
        Connection conn = ts.get();
        if (conn != null) {
            try {
                conn.close();
                ts.remove();
            } catch (Exception e) {
                throw new RuntimeException(e.getMessage());
            }
        }
    }
    //执行增删改的方法
    public static int executeUpdate(String sql, Object... params) {
        try {
            System.out.println(sql);
            return createPreparedStatement(sql, params).executeUpdate();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
    //执行查询的方法
    public static ResultSet executeQuery(String sql, Object... params) {
        try {
            return createPreparedStatement(sql, params).executeQuery();
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
    //为sql语句赋值,并返回PreparedStatement对象
    public static PreparedStatement createPreparedStatement(String sql, Object... params) {
        try {
            Connection conn = getConnection();
            PreparedStatement ps = conn.prepareStatement(sql);
            if (params != null && params.length > 0)
                for (int i = 0; i < params.length; i++)
                    ps.setObject(i + 1, params[i]);
            System.out.println(ps);
            return ps;
        } catch (Exception e) {
            throw new RuntimeException(e.getMessage());
        }
    }
}

测试方法:

具体的数据表tb_user

​
mysql> desc tb_user;
+----------+-------------+------+-----+---------+----------------+
| Field    | Type        | Null | Key | Default | Extra          |
+----------+-------------+------+-----+---------+----------------+
| id       | int(11)     | NO   | PRI | NULL    | auto_increment |
| username | varchar(32) | NO   |     | NULL    |                |
| password | varchar(32) | NO   |     | NULL    |                |
+----------+-------------+------+-----+---------+----------------+
3 rows in set (0.02 sec)

mysql> select * from tb_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张三     | ZS123456 |
|  2 | 李四     | LS123456 |
|  3 | 王五     | WW123456 |
+----+----------+----------+
3 rows in set (0.00 sec)

​

1.测试增加数据的方法:save(T obj)

IUserDao dao =DaoFactory.getUserDao();
        User user1=new User(4L,"赵六","ZL123456");
        int num=dao.save(user1);
        if (num >0) {
            System.out.println("插入成功!");
        }else {
            System.out.println("插入失败!");
        }

mysql> select * from tb_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张三     | ZS123456 |
|  2 | 李四     | LS123456 |
|  3 | 王五     | WW123456 |
|  4 | 赵六     | ZL123456 |
+----+----------+----------+
4 rows in set (0.00 sec)

mysql>

 2.测试删除方法delet(T obj)

IUserDao dao =DaoFactory.getUserDao();
        User user1=new User();
        user1.setId(4L);
        int num=dao.delete(user1);
        if (num >0) {
            System.out.println("删除成功!");
        }else {
            System.out.println("删除失败!");
        }

 

mysql> select * from tb_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张三     | ZS123456 |
|  2 | 李四     | LS123456 |
|  3 | 王五     | WW123456 |
+----+----------+----------+
3 rows in set (0.00 sec)

3.测试修改方法delet(T obj)

IUserDao dao =DaoFactory.getUserDao();
        User user1=new User();
        user1.setId(1L);
        user1.setUsername("张小三");
        int num=dao.update(user1);
        if (num >0) {
            System.out.println("修改成功!");
        }else {
            System.out.println("修改失败!");
        }

 

mysql> select * from tb_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张小三   | ZS123456 |
|  2 | 李四     | LS123456 |
|  3 | 王五     | WW123456 |
+----+----------+----------+
3 rows in set (0.00 sec)

4.测试查询方法:

1.测试整表查询

mysql> select * from tb_user;
+----+----------+----------+
| id | username | password |
+----+----------+----------+
|  1 | 张小三   | ZS123456 |
|  2 | 李四     | LS123456 |
|  3 | 王五     | WW123456 |
+----+----------+----------+
3 rows in set (0.00 sec)

 2.测试按id查询:

 IUserDao dao =DaoFactory.getUserDao();
        User user1=new User();
        user1.setId(1);
        List<User> list = dao.query(user1);
        for (User temp:list) {
            System.out.println(temp);
        }
       

 

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
java设计模式DAO模式   DAO设计模式    DAO的理解   1、DAO其实是利用组合工厂模式来解决问题的,并没有带来新的功能,所以学的 其实就是个思路。   2、DAO理论上是没有层数限制的。   3、DAO的各层理论上是没有先后的。    DAO模式的本质   一层屏蔽一种变化 " " " "1 "<strong> DAO基础 " " " " " " " "2 "DAO模式是标准的J2EE设计模式之一.开发人员使用这个模式把底层的数据访问操作和上层的商务逻辑分开.一个典型的" " "'DAO实现有下列几个组件: " " " " "3 " " " "1 " " ". 一个DAO工厂类; " "4 " " " " " " "2 " "5 ". 一个DAO接口; " " " " " " " "6 "3 " " ". 一个实现DAO接口的具体类; " " " " " " " " "4 " " ". 数据传递对象(有些时候叫做值对象).</strong> "   下面举例(多层dao接口的实现)   具体实现:   1.dao接口: " " " "1 "package " " "cn.hncu.pattern.dao.dao; " " " " "2 " " " "public " " "interface " "3 "DepDAO { " " " " " " " "4 " " " "public " " "void " "5 "create(String userId, String name); " " " " " " " " "} "   2.dao工厂 " " " "1 "package " " "cn.hncu.pattern.dao.factory; " " " " "2 " " " "import " " "cn.hncu.pattern.dao.dao.DepDAO; " "3 " " " " " " "import " "4 "cn.hncu.pattern.dao.impl.a.factory.F2AFactory; " " " " " " " "5 "import " " "cn.hncu.pattern.dao.impl.b.factory.F2BFactory; " " " " "6 " " " "public " " "class " "7 "F1Factory { " " " " " " " "8 " " " "private " " "F1Factory(){ " "9 " " " " " " " " "10 "} " " " " " " " "11 " " " "public " " "static " "12 "DepDAO getDepDAO(){ " " " " " " " "13 " " " "int " " "type1= " "14 "1 " " "; " " "//第一层工厂的选择类型,按理应该从用户的配置信息中读取,我们这里模拟了 " "15 " " " " " " " " "16 " " " "if " " "(type1== " "17 "1 " " "){ " " " " "18 " " " " " " "return " "19 "F2AFactory.getDepDAO(); " " " " " " " " " " " "} " " "else " " "if " " "(type1== " " "2 " " "){ " " " " " " " " " " " "return " " "F2BFactory.getDepDAO(); " " " " " " " " " " " "} " " " " " " " " " " " "return " " "null " " "; " " " " " " " " " " " "} " " " " " " " " "} "   3.dao实现接口   第二层dao " " " "1 "package " " "cn.hncu.pattern.dao.impl.a.factory; " " " " "2 " " " "import " " "cn.hncu.pattern.dao.dao.DepDAO; " "3 " " " " " " "import " "4 "cn.hncu.pattern.dao.impl.a.rdb.factory.F3A_RDB_Factory; " " " " " " " "5 "import " " "cn.hncu.pattern.dao.impl.b.factory.F2BFactory; " " " " "6 " " " "public " " "class " "7 "F2AFacto

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值