对我的代码进行批评/建议

时间:2010-12-25 03:35:04

标签: java

在进一步讨论之前,我很高兴知道到目前为止我的程序中是否存在任何重大设计缺陷。在我继续之前还有什么值得改变的吗?

模型

package model;

import java.sql.*;
import java.util.*;

public class MovieDatabase {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public List queryMovies() throws SQLException {
        Connection connection = null;
        java.sql.Statement statement = null;
        ResultSet rs = null;
        List results = new ArrayList();

        try {
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password");           
            statement = connection.createStatement();
            String query = "SELECT * FROM movie";
            rs = statement.executeQuery(query);

            while(rs.next()) {
                MovieBean bean = new MovieBean();
                bean.setMovieId(rs.getInt(1));
                bean.setTitle(rs.getString(2));
                bean.setYear(rs.getInt(3));
                bean.setRating(rs.getInt(4));
                results.add(bean);
            }
        } catch(SQLException e) {

        }
        return results;
    }
}

的Servlet

public class Service extends HttpServlet {

    @SuppressWarnings("rawtypes")
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println("Movies!");
        MovieDatabase movies = new MovieDatabase();

        try {
            List results = movies.queryMovies();
            Iterator it = results.iterator();

            while(it.hasNext()) {
                MovieBean movie = new MovieBean();
                movie = (MovieBean)it.next();
                out.println(movie.getYear());
            }
        }
        catch(SQLException e) {

        }

    }
}

package model;

@SuppressWarnings("serial")
public class MovieBean implements java.io.Serializable {

    protected int movieid;
    protected int rating;
    protected int year;
    protected String title;

    public MovieBean() {

    }

    public void setMovieId(int movieidVal) {
        movieid = movieidVal;
    }

    public void setRating(int ratingVal) {
        rating = ratingVal;
    }

    public void setYear(int yearVal) {
        year = yearVal;
    }

    public void setTitle(String titleVal) {
        title = titleVal;
    }

    public int getMovieId() {
        return movieid;
    }

    public int getRating() {
        return rating;
    }

    public int getYear() {
        return year;
    }

    public String getTitle() {
        return title;
    }

}

4 个答案:

答案 0 :(得分:3)

以下是一些建议:

  • 您的MovieDatabase内嵌了连接创建。您没有这样使用连接池。
  • 您在代码中嵌入了连接参数(例如,驱动程序类,URL等)。最好将它们外化。
  • 您不清理任何JDBC资源。这保证会给你带来悲伤。
  • 你有空的拦截块。这是一个令人发指的错误。记录堆栈跟踪。你无法知道编码是否有任何问题。
  • MovieBean?名字很重要 - 让它成为电影。
  • 您的默认构造函数根本不执行任何操作,它是您提供的唯一构造函数。您对String的String引用将为null。我认为你应该有一个构造函数来正确初始化所有字段。
  • 您的服务不应该扩展Servlet。我认为你应该有一个POJO接口和一个与HTTP无关的实现。没有网络,您不能使用此服务(或测试它)。
  • 另一个空挡块 - 你要求麻烦。你什么时候学会打印堆栈跟踪?
  • 我没有MovieDatabase;我会使用具有CRUD操作的MovieDao界面,如下所示:
package persistence; 

public interface MovieDao
{
    List<Movie> find();
    Movie find(int id);
    List<Movie> find(String title);
    void save(Movie movie);
    void update(Movie movie);
    void delete(Movie movie);
}

答案 1 :(得分:2)

以下大部分是风格,不一定是“正确”的方式,当然也不是唯一的方式。

  1. 我会移动数据库连接 到servlet的#doGet中的try块。我通过了 连接到 MovieDatabase#queryMovies。该 原因是,如果在您需要的同一请求中会发生什么 用另一个查询做另一个查询 类?你的联系在 MovieDatabase和另一个类 无法访问它。如果您遇到两个类都可以更新数据库的情况,那么您将无法回滚整个事务。不好。
  2. 我会在#doGet
  3. 的'成功'路径末尾添加一个提交语句
  4. 我在包含数据库连接的try块之后添加了一个异常块,其中我发出了回滚。因此,如果存在异常,则每次都会执行回滚。
  5. 我将关闭数据库连接 #doGet终于阻止了。这是最重要的。 编辑 - 请参阅下面的伪代码以获取示例
  6. 如果不将连接移动到servlet中,则笔直 离开你应该关闭它 #queryMovies中的连接终于 子句。
  7. 如果这是一个更大的项目,我会使用Hibernate及其工具 生成DAO和模型。过冬 会为你生成一个班级和 返回的方法 MovieBeans的集合给你。 你不需要做任何事情 调用它。自动生成的数据库 访问代码很好。
  8. 我会添加一个JSP并将您正在构建的集合放入请求中。然后你的jsp可以遍历集合并根据需要进行格式化。这会将信息的呈现移出servlet,这是一个操作协调器,而不是MVC模型中的数据格式化程序
  9. 如果您实施了上述建议,则可能会将您的代码行数减少50%或更多。学习Hibernate可能是一个头痛,所以第一次不一定更容易或更快。它减少代码行的原因(在完成相同的工作时)是生成的代码非常正确,编码器不必担心它。

    我一直在servlet中使用以下模式。这是伪代码,而不是真正的java。

       Connection conn = null;
       try {
          conn.getConnection(...);
          // your implementation here
          conn.commit();
       } catch (Exception e) {
          conn.rollback();
       } finally {
          conn.close();
       }
    

    重点是数据库连接总是可以传递给worker,除非出现问题,否则总是会提交工作。如果出现问题,可以保证回滚。在任何一种情况下,数据库连接都会在全部结束时关闭。

答案 2 :(得分:1)

这非常简单明了,没有大问题。我唯一要指出的是你正在做一个SELECT *然后通过列索引引用结果集。在这个阶段这不是问题,但是如果您的架构发生了变化(例如,在中间添加了一个字段),那么您的代码将会中断。我会明确选择列名:

SELECT id, title, year, rating FROM movie

答案 3 :(得分:-1)

有很多错误(许多人已经指出了大部分内容)。好像代码是用90年代写的。我强烈建议您阅读layered architectureseparation of concernsMVCDAO模式。然后你会自己回答这个问题,我会投票给你答案; - )。