【问题标题】:Java spring mvc using hibernate to do updatejava spring mvc使用hibernate做更新
【发布时间】:2017-03-14 23:35:57
【问题描述】:

两个月前,我开始使用 Java Spring MVC 为 iOS 应用程序开发 API。 我会用一个例子来解释我的问题,以便澄清。

假设我想更新用户名。 MySQL 用户表有列:id、user_id、email、display_name。 我的做法是:

  1. 定义用户:

用户.java:

package bean;
public class User {

  String displayName;
  String email;
  String userId;

  getters/setters... 
}

2.定义一个DAO:

UserDao.java:

package dao;
import bean.StandardResponse;

public interface UserDao {
    public StandardResponse updateUserName(String user_id,String userName);
}

UserDaoImpl.java:

package implement;
import bean.User;
import common.DatabaseConnect;

public UserDaoImpl implements UserDao {
    private DatabaseConnect dbConnect; 

    public UserDaoImpl(DatabaseConnect dbConnect) {
      this.dbConnect = dbConnect;
    }

    public StandardResponse updateUserName(userId,userName) {
      if ((userId == null || userId.isEmpty()) ||(userName == null || userName.isEmpty())) return new StandardResponse("Error","Parameters not set!");
      String sql = null;
      Statement smt = dbConnect.createDataBaseConnectResourse();
      StandardResponse result = new StandardResponse("Error","Fail to update the record!");
      sql = "update User set user_name="+userName+" where user_id='"+userId+"'";
      int updateResult = 0;
      try {
        updateResult = smt.executeUpdate(sql);
      } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
      } finally {
        dbConnect.closeDatabaseConnectResource();
      }
      if (updateResult == 1) {
        result = new StandardResponse("Success","The record has been updated!");
      }

      return result;        
  }
}

3.控制器

import org.springframework.stereotype.Controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import bean.StandardResponse;
import bean.User;
import common.DatabaseConnect;
import common.SpringApplicationContext;
import dao.UserDao;
import implement.UserDAOImpl;

@Controller
@RestController
@RequestMapping("user")
public class UserController {

  DatabaseConnect dbConnect = SpringApplicationContext.getApplicationContext().getBean("databaseConnect", DatabaseConnect.class);
  UserDao uiObject = new UserDaoImpl(dbConnect);

  @RequestMapping(value = "/updateUserName", method = RequestMethod.POST)
  public StandardResponse updateUserName(HttpServletRequest request, HttpServletResponse reponses, Model model) {
    StandardResponse srObject = uiObject.updateUserName(request.getparameter("userId"),request.getParameter("userName"));
    return srObject;
  }
}

我只是把关键的课程放在这里。我相信你能明白我在这里做什么。因此,如果有人访问提供 userId 和 userName 的 URL:****/user/updateUserName,他可以更新该记录的用户名。它是功能性的。

我用同样的方法完成了整个项目。这是工作。然后,我请一位经验丰富的程序员查看我的代码,因为我根据自己的理解弄清楚了所有这些。我想知道他们在工业界的表现如何。他给了我一些有价值的cmets。

  1. 整个结构错误。我的道中不应该有逻辑。我至少应该有 dao、service 和 action 层。 dao 只处理数据库访问,service 处理所有逻辑,action 处理通信并决定调用哪个服务。
  2. 在代码中手写 SQL 是一种非常糟糕的方法。我应该使用 Hibernate。
  3. 我应该使用控制反向和依赖注入。(我在这篇文章中不涉及这个。)

所以我开始更新我的代码以使用 Hibernate。

  1. 定义用户:

用户.java:

package model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="User")
public class User {

  @Id
  @Column(name="id")
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private int id;

  @Column(name = "user_id")
  private String userId;

  @Column(name = "user_name")
  private String displayName;

  @Column(name = "email")
  private String emai;

  all getters/setters...
}
  1. 道:

UserDao.java:

package dao;
import model.User;
import java.util.List;
public interface UserDAO {

  public void updateUser(User p);
  other methods....

}

UserDaoImpl.java

package dao;
import model.User;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.stereotype.Repository;

import model.User;

@Repository
public class PersonDAOImpl implements PersonDAO {

    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sf){
        this.sessionFactory = sf;
    }

    @Override
    public void updatePerson(Person p) {
        Session session = this.sessionFactory.getCurrentSession();
        session.update(p);
    }

    implementations of other methods....

}
  1. 服务:

UserService.java:

package service;

import java.util.List;

import model.User;

public interface UserService {

    public void updateUser(User p);
    other methods....

}

UserServiceImpl.java:

package service;

import java.util.List;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import dao.UserDAO;
import model.User;

@Service
public class UserServiceImpl implements UserService {

    private UserDAO userDAO;

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    @Transactional
    public void updateUser(User p) {
       this.userDAO.updateUser(p);
    }

    implementation of other methods...

}

现在,我只需要编写一个类来处理请求并调用此 updateUser 服务。整个结构看起来比我的好。但是,该请求不会给我整个用户对象。我能得到的只是 user_id 和 user_name。我也不允许将逻辑放在道中。所以我必须先查询表以获取整个用户对象,然后更新用户名。与我以前的做法相比,一个 SQL 处理更新。现在使用 Hibernate,我需要 1 个查询和 1 个更新。

我在 StackOverflow 上找到了一个解决方案,我可以使用 HQL 一步完成。但我认为使用 Hibernate 的目的是让我们从编写 SQL 中解放出来。如果我需要写HQL,为什么不继续使用写SQL的方法。

那么有没有办法在不先在这个结构中查询表的情况下使用 Hibernate 进行更新?或者这是为了更好的结构而做出的权衡?

很抱歉,我为这个问题使用了一个很长的示例。但我想不出其他方法来清楚地解释整个故事。

【问题讨论】:

  • 您需要从哪里获取 user_id 和 user_name ?来自用户界面?
  • 是的。我从 UI 获取 user_id 和 user_name。它来自 iOS 应用或网页。
  • hibernate 主要用于 ORM(对象关系映射)。通常您确实必须编写通用 sql 来执行您想要的操作。
  • 那么使用Hibernate的目的不就是为了避免代码中的SQL语句吗?用java代码写SQL语句不专业?
  • 对于复杂的 SQL 查询,你可以编写原生查询,但想法是通过调用 beanObject.save()、beanObject.update() 等来避免它们。但如果你有条件你需要到 HQL 如下例所示

标签: java mysql hibernate spring-mvc


【解决方案1】:

那么有没有办法在不先在这个结构中查询表的情况下使用 Hibernate 进行更新?或者这是为了更好的结构而做出的权衡? 没有折衷,您可以使用 HQL(Hibernate 查询语言)进行更新,就像在 SQL 中一样。

可以看下面的代码:

UserDAOImpl 类:

    @Repository
    //you are calling this in ur code as PersonDAOImpl..change it to UserDAOImpl
    public class UserDAOImpl implements UserDAO {

        private SessionFactory sessionFactory;

        public void setSessionFactory(SessionFactory sf){
            this.sessionFactory = sf;
        }

        @Override
        public int updateUser(String userId, String userName) {
            Session session = this.sessionFactory.getCurrentSession();
         Query query = session.createQuery("update User set userName =:userName where userId = :userName ");
         query.setString("userName", userName);  
         query.setString(userName, userName);  
         int result = query.executeUpdate();
         return result;
        }
    }

UserServiceImpl 类:

@Service
public class UserServiceImpl implements UserService {

    private UserDAO userDAO;

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    @Transactional
    public void updateUserName(String userId, String userName) {

        if(userId !=null && userName != null) {
                int result = this.userDAO.updateUser(userId, userName);

           if(result==0) //userid not available {
                //if userid is NOT available, what to do? check your requirement and handle properly
           }

           } 
       } else {
            //throw exception
       }
    }
    implementation of other methods...
}

控制器类:

@Controller
@RestController
@RequestMapping("user")
public class UserController {

  @Autowired
  private UserService userService;

  @RequestMapping(value = "/updateUserName", method = RequestMethod.POST)
  public StandardResponse updateUserName(HttpServletRequest request, HttpServletResponse reponses, Model model) {
    StandardResponse srObject = userService.updateUserName(request.getparameter("userId"),request.getParameter("userName"));
    return srObject;
  }
}

【讨论】:

  • 谢谢你,@javaguy。我知道我可以做到这一点。但我的困惑是:我之前可以使用一条 SQL 语句进行更新。现在我正在使用 Hibernate,我必须做一个额外的查询(SELECT),然后更新。一个额外的数据库命中,所以我要权衡性能以获得更好的结构?
  • 谢谢你,@javaguy。我想 HQL 是做到这一点的唯一方法。我想也许 Hibernate 有一种简单的方法可以在没有 HQL 的情况下进行更新。(比如 update(criteria(sth)...)因为我从使用 SQL 语句切换到使用 hibernate 的主要原因是他们告诉我我正在编写糟糕的代码里面有SQL语句......所以我觉得如果我必须使用HQL来做这件事很讽刺。如果SQL查询涉及join,我可以同意这是一个复杂的SQL。但是对于像“更新用户设置用户名”这样的语句='Peter' where user_id=1"...我想我对Hibernate的期望太高了...
  • 非常感谢您的解释。我非常感谢您的回答@javaguy。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-09
  • 1970-01-01
  • 2017-08-16
  • 2012-12-25
  • 2014-07-11
  • 1970-01-01
相关资源
最近更新 更多