【问题标题】:Spring JDBCTemplate: is it okay to call a DAO method inside RowMapper?Spring JDBCTemplate:可以在 RowMapper 内部调用 DAO 方法吗?
【发布时间】:2014-05-17 06:13:41
【问题描述】:

假设我们在一个对象中有一个对象。假设我们有引用 owner_id 的数据库表 car 和 owner 表。

我们的领域对象 car 引用了 Person:

public class Car {
    public class Person person;
}

假设我们有一个用于 Car 的 DAO 和一个用于 Person 的 DAO,是否可以在 CarDao 中自动装配 PersonDao,并从 CarDao 的 RowMapper 中查询 Person 并将其添加到 car 对象中?我对此进行了测试并且它有效,但我想更多地询问它是否被认为是不好的形式或做法以及为什么。

【问题讨论】:

    标签: java spring dao


    【解决方案1】:

    我肯定会将其归类为不良形式,因为数据库调用应该是单数的。

    您可以尝试分别调用 DAO 并从两个调用中组合您的 Car 实例

    List<Car> cars = carDao.getCars();
    List<Person> people = personDao.getPeople();
    for (int i=0; i<cars.size(); i++){
        cars.get(i).setPerson(people.get(i));
    } 
    

    或创建一个连接查询来生成您需要的所有结果,并在 RowMapper 中创建适当的对象:

    jdbcTemplate.query("SELECT c.name, c.serialNumber, p.name FROM Car c INNER JOIN Person p ON c.id = p.carId", .., .., new RowMapper<Car> {
        public Car mapRow(ResultSet rs, int rowNum) throws SQLException {
            String carName = rs.getString(1);
            String carSerialNumber = rs.getInt(2);
            String personName = rs.getString(3);
            Car car = new Car();
            car.setName(carName);
            car.setSerialNumber(serialNumber);
            Person person = new Person();
            person.setName(personName);
            car.setPerson(person);
            return car;
        }
    });
    

    注意:我按原样编写代码并没有对其进行测试,但这是我使用 JDBC 的方式。

    【讨论】:

      【解决方案2】:

      IMO 这不是一个好习惯。如果你想从数据库中提取一对多关系,你可以使用ResultSetExtractor

      public class MasterDetailResultSetExtractor implements ResultSetExtractor {
      
        @Override
        public Object extractData(ResultSet rs) throws SQLException {
          Master m = new Master();
          m.setFirstName(rs.getString(1));
          m.setLastName(rs.getString(2));
      
          //put the master in a map
      
          Detail d = new Detail();
          d.setSomeProp(rs.getString(3));
      
          //check if the master is in the map
              //if yes - add the detail to the master
              //if no - add the master first
          return m;
        }
      
      } 
      

      ResultSet 是表 JOIN 的结果。

      【讨论】:

      • 哪种方法更好……你的或加布里埃尔的。使用Resultsetmapper,我们提取了大量冗余数据,但只访问了一次数据库。
      • RowMapper 只为您提供结果集的一行。如果一个人拥有 2 辆或更多辆汽车,则使用 Gabriel 的方法,即使数据相同,您最终也会为他/她拥有的每辆汽车创建一个 Person 对象。 + 使用 ResultSetExtractor,您只能使用一次调用数据库(与另一个答案中的 sql 相同)我投票赞成我的方法 :)
      猜你喜欢
      • 2012-02-17
      • 2018-03-06
      • 1970-01-01
      • 2022-12-15
      • 2013-05-31
      • 2016-09-07
      • 1970-01-01
      • 2016-11-28
      • 2012-05-23
      相关资源
      最近更新 更多