我想访问我的申请人数据库,这就是我为它创建DAO类的原因.
我想我有很多代码味道,因为我不断重复一些代码.那么,为了减少代码味道,我能做些什么才能使代码更简单呢?我违反了什么规则?我该如何改进我的代码?谢谢.
我的代码如下:
public class ApplicantDAO {
private static ApplicantDAO me = null;
private ApplicantDAO(){};
public static synchronized ApplicantDAO getInstance() {
if(me == null) {
me = new ApplicantDAO();
}
return me;
}
public Applicant getApplicant(int applicantNumber) throws SQLException {
Applicant applicant = null;
Connection conn = null;
Statement statement= null;
String query = null;
ResultSet rs = null;
try {
conn = ConnectionManager.getConnection();
statement = conn.createStatement();
query = "SELECT * FROM applicant WHERE applicant_no = '" + applicantNumber +"'"; //check applicant_number
rs = statement.executeQuery(query);
while(rs.next()){
applicant = new Applicant();
applicant.setApplicantNumber(rs.getInt("applicant_no"));
applicant.setApplicationDate(rs.getString("applicant_date"));
applicant.setfName(rs.getString("first_name"));
applicant.setlName(rs.getString("last_name"));
applicant.setmName(rs.getString("middle_name"));
applicant.setAge(rs.getInt("age"));
applicant.setGender(rs.getString("gender"));
applicant.setEmail(rs.getString("email_address"));
applicant.setContactNumber(rs.getString("contact_no"));
applicant.setCity(rs.getString("city"));
applicant.setSchool(rs.getString("school"));
applicant.setCourse(rs.getString("course"));
applicant.setYearGraduated(rs.getInt("year_graduated"));
applicant.setYearWorkExp(rs.getInt("year_work_exp"));
applicant.setSourceChannel(rs.getString("source_channel"));
applicant.setStatus_id(rs.getInt("status_id"));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
if (rs != null) try { rs.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (conn!= null) try { conn.close(); } catch (SQLException logOrIgnore) {}
}
return applicant;
}
public ArrayList<Applicant> getApplicants() throws SQLException{
ArrayList<Applicant> applicantList = null;
Applicant applicant = null;
Connection conn = null;
Statement statement= null;
String query = null;
ResultSet rs = null;
try {
conn = ConnectionManager.getConnection();
statement = conn.createStatement();
query = "select * from applicant";
rs = statement.executeQuery(query);
while(rs.next()){
if(applicantList == null){
applicantList = new ArrayList<Applicant>();
}
applicant = new Applicant();
applicant.setApplicantNumber(rs.getInt("applicant_no"));
applicant.setApplicationDate(rs.getString("applicant_date"));
applicant.setfName(rs.getString("first_name"));
applicant.setlName(rs.getString("last_name"));
applicant.setmName(rs.getString("middle_name"));
applicant.setAge(rs.getInt("age"));
applicant.setGender(rs.getString("gender"));
applicant.setEmail(rs.getString("email_address"));
applicant.setContactNumber(rs.getString("contact_no"));
applicant.setCity(rs.getString("city"));
applicant.setSchool(rs.getString("school"));
applicant.setCourse(rs.getString("course"));
applicant.setYearGraduated(rs.getInt("year_graduated"));
applicant.setYearWorkExp(rs.getInt("year_work_exp"));
applicant.setSourceChannel(rs.getString("source_channel"));
applicant.setStatus_id(rs.getInt("status_id"));
applicantList.add(applicant);
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
if (rs != null) try { rs.close(); } catch (SQLException logOrIgnore) {}
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (conn!= null) try { conn.close(); } catch (SQLException logOrIgnore) {}
}
return applicantList;
}
Run Code Online (Sandbox Code Playgroud)
我看到巨大的,明显的问题:
EntityManager.还有,为什么?如果你实际上使用的是Java EE(因为标记的问题)而不是J2EE(这是一个围绕Java 1.4构建的可悲的规范),那么DAO模式是完全没必要的.EntityManager是新的DAO.
看看Java EE 6教程的前几节- 持久性.
我们需要使用J2ee .. :(
好的,所以你仍然需要修复单例实现.没有理由只创建这个对象的一个实例,因为它不存储任何内部状态.有一个简单的解决方案:
private static ApplicantDAO me = null;完全删除将getInstance()实现更改为
public static ApplicantDAO getInstance() {
return new ApplicantDAO();
}
Run Code Online (Sandbox Code Playgroud)其他气味:
你几乎总是想要声明Lists而不是ArrayLists,所以改变声明就像
public ArrayList<Applicant> getApplicants() throws SQLException
// to
public List<Applicant> getApplicants() throws SQLException
// and
ArrayList<Applicant> applicantList = null;
// to
List<Applicant> applicantList = null;
Run Code Online (Sandbox Code Playgroud)为了让您了解更现代的DAO会是什么样子:
@Stateless
public class JPAApplicantDAO implements ApplicantDAO {
@PersistenceContext(unitName = "myPU")
private EntityManager entityManager;
@Override
public Applicant getByID(Long applicantID) {
return entityManager.find(Applicant.class, applicantID);
}
@Override
public void update(Applicant applicant) {
applicant.setLastModifiedDate(new Date());
entityManager.merge(applicant);
}
@Override
public void delete(Applicant applicant) {
Applicant deletedApplicant = applicant;
if (!entityManager.contains(applicant)) {
deletedApplicant = entityManager.merge(applicant);
}
entityManager.remove(deletedApplicant);
}
@Override
public List<Applicant> getBySomethingID(Long somethingID) {
return entityManager.createNamedQuery("Applicant.getBySomethingID", Applicant.class)
.setParameter("somethingID", somethingID)
.getResultList();
}
}
Run Code Online (Sandbox Code Playgroud)
现在有人建议放弃整个DAO概念,并在任何地方直接使用实体管理器.我并不完全同意这一点.
这个DAO示例显示了4种不同的方法.第一种方法是通过实体的主ID进行简单获取.正是这种方法让人们想知道是否仍然需要DAO抽象.但请继续阅读.
第二种方法显示了更新方法.在这种情况下,应用程序可能希望对实体执行额外操作,例如设置上次修改日期.DAO是一个非常自然的地方.是的,它也可以在数据库中完成,但是DAO仍然会很方便,因为您可能必须回读实体才能了解正在设置的日期.
第三种方法是删除方法.由于JPA规范中存在一个特殊问题,您只能删除处于附加状态的实体.这意味着一些额外的逻辑来检查它是否附加(包含在持久化上下文中),如果没有附加它(合并它).
第四种方法显示通过(JPQL)查询的数据检索.查询的名称和参数的名称都不是类型安全的.DAO方便地将其隐藏在类型安全的Java方法之后.是的,您可以将这些名称提取为常量,但仍不会强制执行此特定参数与此特定查询之间的关联.
通常,DAO允许进行一定量的重构.在某些时候,我可能想要用条件查询替换JPQL查询.在所有呼叫站点更改此信息可能会有问题.然后就是这样一种情况:作为一般DAO的实体经理只是强大的.我不想将这些发送到所有客户端站点(如果是远程客户端,这甚至是不可能或非常糟糕的做法).
最后,使用来自客户端代码的实体管理器本身不是事务性的,意味着该客户端必须担心事务.这为代码增加了许多冗长.使用DAO,客户端代码变得更加简单:
@Named
@RequestScoped
public class SomeBean {
@EJB
private ApplicantDAO applicantDAO;
public void someMethod() {
applicantDAO.delete(applicant);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3440 次 |
| 最近记录: |