这两天在纠3层开发模式主要纠结于dao与biz的分工 biz到底该不该出现SQL语句 如果biz不出现SQL语句 那么dao里的接口就不具有通用性 也就是说我biz需要一种增删改查 那么dao包里就要相应的写出一个方法。
其实dao包里就写两个通用方法就可以了 查写一个方法 参数为SQL语句和Objet[] 通过循环拼接好语句以后 调用PreparedStatement的setObject方法 return 一个ResultSet就可以了
增删改写一个方法 还是以SQL语句和Objet[]为参数 通过循环拼接好用PreparedStatement的executeUpdate() return 一个int出去就可以了 之后再biz里调用这两个通用方法 传入SQL语句和参数就可以完成所有的增删改任务了
但是 问题就在于dao与biz分工的作用就体现不出来了 如果数据库更换了 那么不但要更改dao包 还要去biz修改SQL语句 这样就特别不好维护了
这两种一个是便于维护 符合分工规则。一个是节省代码 通用性强 但是彼此的缺点也很明显。
所以我又想了第三种方法 那就是在dao包的实现类里面加入字段 在biz层调用通用方法 并且调用通用方法的固定SQL语句,然后再传入需要的参数 比如说 ID啊 姓名 年龄这些的 这样的话又可以节省代码 提高通用性 又可以便于维护
说不太好体现各自的优劣 下面三段代码演示 假设开始用户要求 根据ID 从数据库里查一列数据 之后又添加N种查询方式
情况一:
public interface SelectUserById {
public User seletcUser(int id);//根据id查询一个User
}
public class SelectUserByIdImpl implements SelectUserById{
public User SelectUser(int id){
String sql="select user from uerttable where id=?";
//之后建立连接对象 数据集等过程就省略了
}
}
这样在BIZ调用这个方法 然后传入ID就可完成功能 这样SQL语句就完全独立出来了 BIZ完全没有数据库的内容 但是 之后添加N中方法 那么在dao包里就需要增加多种接口来完成功能 我感觉又费时间 又不好写
情况二:
public interface Select{
public ResultSet select(Strng sql,Object[] param);
}
public class SelectImpl implements Select{
public ResultSet select(Strng sql,Object[] param){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null; try {
conn = getConn(); // 得到数据库连接
pstmt = conn.prepareStatement(preparedSql);
// 得到PreparedStatement对象
if (param != null) {
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i + 1, param[i]); // 为预编译sql设置参数
}
}
rs = pstmt.executeQuery(); // 执行SQL语句
} catch (ClassNotFoundException e) {
e.printStackTrace(); // 处理ClassNotFoundException异常
} catch (SQLException e) {
e.printStackTrace(); // 处理SQLException异常
}
return rs; }
}
其实上面这个方法是写在父类里面的 所有需要用到增删改查的daoImpl对象都继承这个类直接调用这个方法 然后转换对象就可以了之后再biz里不管需要怎么查询数据 只要调用通用方法 然后传入SQL语句和参数 就可以得到自己想要的结果 缺点刚才已经说了 现在演示方法3
情况三:
public interface Select{
String sql SelectUserById="select user from uerttable where id=?";
//Sql语句
public ResultSet select(Strng sql,Object[] param);
}
public class SelectImpl implements Select{
//方法和情况三一样
}
之后 在biz调用 selectImpl(Select.SelectUserByid,Object[] param)这个方法就不考虑SQL语句了只考虑参数就行了 语句是在BIZ完成 这样就把上面的优势全部吸收了 劣势全避免了 假如底层dao换了 biz虽然会有报错的情况 但是参照以前的 写好SQL语句就可以了感觉这个就像方法重载一样 不过不是通过参数类型和数量重载的 而是通过参数名重载的问题就是这个param的个数是不是和SQL语句的?个数一样 我希望java能扩展一个功能 能像方法一样打点就能出来 后面的参数也能按照SQL的问号来提示由于自己是初学者 而且第一次写这样的文章 不知道写的是不是能让大家看懂 如果感兴趣,者有疑问或者建议的话可以直接联系我 QQ:980123603
其实dao包里就写两个通用方法就可以了 查写一个方法 参数为SQL语句和Objet[] 通过循环拼接好语句以后 调用PreparedStatement的setObject方法 return 一个ResultSet就可以了
增删改写一个方法 还是以SQL语句和Objet[]为参数 通过循环拼接好用PreparedStatement的executeUpdate() return 一个int出去就可以了 之后再biz里调用这两个通用方法 传入SQL语句和参数就可以完成所有的增删改任务了
但是 问题就在于dao与biz分工的作用就体现不出来了 如果数据库更换了 那么不但要更改dao包 还要去biz修改SQL语句 这样就特别不好维护了
这两种一个是便于维护 符合分工规则。一个是节省代码 通用性强 但是彼此的缺点也很明显。
所以我又想了第三种方法 那就是在dao包的实现类里面加入字段 在biz层调用通用方法 并且调用通用方法的固定SQL语句,然后再传入需要的参数 比如说 ID啊 姓名 年龄这些的 这样的话又可以节省代码 提高通用性 又可以便于维护
说不太好体现各自的优劣 下面三段代码演示 假设开始用户要求 根据ID 从数据库里查一列数据 之后又添加N种查询方式
情况一:
public interface SelectUserById {
public User seletcUser(int id);//根据id查询一个User
}
public class SelectUserByIdImpl implements SelectUserById{
public User SelectUser(int id){
String sql="select user from uerttable where id=?";
//之后建立连接对象 数据集等过程就省略了
}
}
这样在BIZ调用这个方法 然后传入ID就可完成功能 这样SQL语句就完全独立出来了 BIZ完全没有数据库的内容 但是 之后添加N中方法 那么在dao包里就需要增加多种接口来完成功能 我感觉又费时间 又不好写
情况二:
public interface Select{
public ResultSet select(Strng sql,Object[] param);
}
public class SelectImpl implements Select{
public ResultSet select(Strng sql,Object[] param){
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null; try {
conn = getConn(); // 得到数据库连接
pstmt = conn.prepareStatement(preparedSql);
// 得到PreparedStatement对象
if (param != null) {
for (int i = 0; i < param.length; i++) {
pstmt.setObject(i + 1, param[i]); // 为预编译sql设置参数
}
}
rs = pstmt.executeQuery(); // 执行SQL语句
} catch (ClassNotFoundException e) {
e.printStackTrace(); // 处理ClassNotFoundException异常
} catch (SQLException e) {
e.printStackTrace(); // 处理SQLException异常
}
return rs; }
}
其实上面这个方法是写在父类里面的 所有需要用到增删改查的daoImpl对象都继承这个类直接调用这个方法 然后转换对象就可以了之后再biz里不管需要怎么查询数据 只要调用通用方法 然后传入SQL语句和参数 就可以得到自己想要的结果 缺点刚才已经说了 现在演示方法3
情况三:
public interface Select{
String sql SelectUserById="select user from uerttable where id=?";
//Sql语句
public ResultSet select(Strng sql,Object[] param);
}
public class SelectImpl implements Select{
//方法和情况三一样
}
之后 在biz调用 selectImpl(Select.SelectUserByid,Object[] param)这个方法就不考虑SQL语句了只考虑参数就行了 语句是在BIZ完成 这样就把上面的优势全部吸收了 劣势全避免了 假如底层dao换了 biz虽然会有报错的情况 但是参照以前的 写好SQL语句就可以了感觉这个就像方法重载一样 不过不是通过参数类型和数量重载的 而是通过参数名重载的问题就是这个param的个数是不是和SQL语句的?个数一样 我希望java能扩展一个功能 能像方法一样打点就能出来 后面的参数也能按照SQL的问号来提示由于自己是初学者 而且第一次写这样的文章 不知道写的是不是能让大家看懂 如果感兴趣,者有疑问或者建议的话可以直接联系我 QQ:980123603