两个月前,我开始使用Java Spring MVC为iOS应用程序开发api。我将用一个例子来解释我的问题。
假设我想更新一个用户名。我的mySQL用户表有:id, user_id, email, display_name。我的方法是:
- 定义用户:
User.java:
package bean;
public class User {
String displayName;
String email;
String userId;
getters/setters...
}
定义一个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;
}
}
我只是把关键类放在这里。我相信你能理解我在这里做什么。因此,如果有人访问URL:****/user/updateUserName,并提供userId和userName,他就可以更新该记录的用户名。
我用同样的方法完成了整个项目。它正在起作用。然后,我找了一个有经验的程序员来检查我的代码,因为这些都是我根据自己的理解得出的。我想知道他们在工业上做得怎么样。他给了我一些有价值的意见。
- 整个结构是错误的。我的刀不应该有逻辑。我至少应该有dao, service和action层。dao只处理数据库访问,service处理所有逻辑,action处理通信并决定调用哪个service。 在代码中手工编写SQL是非常糟糕的方法。我应该使用Hibernate。我应该使用控制逆和依赖注入。(我不处理这个在这篇文章。)
所以我开始更新我的代码来使用Hibernate。
- 定义用户:
User.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...
}
- 道:
- 服务:
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....
}
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。我也不允许在刀里放逻辑。因此,我必须首先查询表以获取整个用户对象,然后更新user_name。与我过去所做的相比,一个SQL处理更新。现在使用Hibernate,我需要一个查询和一个更新。
我在StackOverflow上找到了一个解决方案,我可以使用HQL一步做到这一点。但是我认为使用Hibernate的目的是让我们从编写SQL中解脱出来。如果我需要编写HQL,为什么不继续使用编写SQL的方法呢?
那么是否有一种方法可以使用Hibernate进行更新,而不需要在此结构中首先查询表?或者这是为了更好的结构而付出的代价?
我很抱歉我用了一个很长的例子来回答这个问题。但我想不出其他方法来清楚地解释整个故事。那么在这个结构中是否有一种方法可以在不查询表的情况下使用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;
}
}