java - View 、DAO、服务和 Controller 的基本 Hibernate 和 Spring MVC 集成

标签 java spring hibernate jakarta-ee spring-mvc

状态: 感谢回答,但没有人回答重要标签描述以反射(reflect)我给出的简单代码。 (13 年 7 月 20 日)

我已经阅读了很多教程,但每件事都混在一起,或者只是作为一个看起来很小或抽象的特定示例。

我真的无法让某些事情在我的脑海中变得合乎逻辑。可能是我用具体的实际代码学习。

问题:任何人都可以展示如何使以下不完整的代码完全工作spring 3.x 和 hibernate 4。 x.


重要:

我想,即使在这个简单的例子中, sessionfactory 和 hibernate 查询数据库 在 Service 类中(在大型应用程序中设置边界 Service 类使用许多 DAO 并一次提交事务)

我忘记了我是在哪里读到它的,也许是在 spring 文档中——但它清楚地说,不要把 @Transactional 放在你的 DAO 上 :P 所以一般来说,您的服务层是您定义事务边界的地方。 服务方法通常是一大块东西,如果全部通过,则提交,否则失败并回滚 这当然可能不是一个顽固的规则,但它是我们构建企业资源规划网络核心的方式。 我忘了我是在哪里读到它的,也许是在 spring 文档中——但它清楚地说,不要把 @Transactional 放在你的 DAO 上

例如 http://blog.patouchas.net/technology/hibernate-dao-java-tutorial/就像没有 Spring 一样?


注释 缺失或不正确。正确的注释应该是什么。

这些类是否有具体的 spring.xml(除了通常的)?如果可行,我只想使用注释。正确的注解,如@component、service、repository、resource、autowired

我通常是这样获取交易的

   Configuration configuration = new Configuration();
   configuration.configure();

   ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
                                        .applySettings(configuration.getProperties())
                                        .buildServiceRegistry();

   SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);
   Session session = sessionFactory.openSession();
   session.beginTransaction();
   session.getTransaction().commit();
   session.close();

春暖花开

@Controller
public class UserController {
    private IUserService userService;

    @RequestMapping("/users")
    public String creatUser(){
        Users user = new Users();
        user.setEmail("myemail@mydomain.com");
        user.setName("myname");
        userService.creatUser(user);
        return "user-creation-result";      
    }
}

public class UserService implements IUserService{
    private IUserDAO userDAO;
    public void creatUser(Users user){
        //what to do here
        //how to call the sessionfactory
        //and call it in a way that each call
        // gives the same instance
         userDAO.creatUser(user);        
    }
}

public class UserDAO implements IUserDAO{
    public void creatUser(Users user){
        // what to do here?
    }
}

不过这不会那么重要。

<?xml version='1.0' encoding='utf-8'?>

<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

    <session-factory>

        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://localhost:5432/postgres</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">abc</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->
        <property name="hbm2ddl.auto">create</property>

        <!-- Names the annotated entity class -->

        <mapping class="taskmanagsetup.Boards" />
        <mapping class="taskmanagsetup.BoardPrivileges" />
        <mapping class="taskmanagsetup.Boxes" />
        <mapping class="taskmanagsetup.BoxPrivileges" />
        <mapping class="taskmanagsetup.Groups" />
        <mapping class="taskmanagsetup.Tasks" />
        <mapping class="taskmanagsetup.TaskPrivileges" />
        <mapping class="taskmanagsetup.Users" />

    </session-factory>

</hibernate-configuration>



@Entity
public class Users {
    @Id
    @GeneratedValue
    private long id;
    @ManyToMany
    private Collection<Groups> groupList = new ArrayList<Groups>();
    private String type; // admin / teamlead / normal
    private String name;
    private String email;
    private String password;
    @Lob
    private String description;
    private boolean isEnabled;

    /**
     * @return the id
     */
    public long getId() {
        return id;
    }

    /**
     * @param id the id to set
     */
    public void setId(long id) {
        this.id = id;
    }

    /**
     * @return the groupdId
     */


    /**
     * @param groupdId the groupdId to set
     */


    /**
     * @return the type
     */
    public String getType() {
        return type;
    }

    /**
     * @param type the type to set
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * @return the name
     */
    public String getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * @return the email
     */
    public String getEmail() {
        return email;
    }

    /**
     * @param email the email to set
     */
    public void setEmail(String email) {
        this.email = email;
    }

    /**
     * @return the password
     */
    public String getPassword() {
        return password;
    }

    /**
     * @param password the password to set
     */
    public void setPassword(String password) {
        this.password = password;
    }

    /**
     * @return the isEnabled
     */
    public boolean isIsEnabled() {
        return isEnabled;
    }

    /**
     * @param isEnabled the isEnabled to set
     */
    public void setIsEnabled(boolean isEnabled) {
        this.isEnabled = isEnabled;
    }

    /**
     * @return the groupList
     */
    public Collection<Groups> getGroupList() {
        return groupList;
    }

    /**
     * @param groupList the groupList to set
     */
    public void setGroupList(Collection<Groups> groupList) {
        this.groupList = groupList;
    }

    /**
     * @return the description
     */
    public String getDescription() {
        return description;
    }

    /**
     * @param description the description to set
     */
    public void setDescription(String description) {
        this.description = description;
    }
}

最佳答案

如果您使用的是 Spring 3.x 和 Hibernate 4.x,您可以考虑 three-tier application architecture :

数据层

您可以为常见的 DAO 方法创建一个抽象基类。

public abstract class AbstractDAO<E extends Serializable, 
                                 PK extends Serializable> {

    private final transient Class<E> entityClass;

    public AbstractDAO(final Class<E> entityClass) {
        this.entityClass = entityClass;
    }

    protected abstract EntityManager getEntityManager();

    public final E find(final PK id) {
        return getEntityManager().find(entityClass, id);
    }

    // Another common methods

}

在每个 DAO 实现中,您可以为该 DAO 放置特定的方法。

@Repository
public final class UserDAO extends AbstractDAO<User, Long> {

    @Autowired
    private transient EntityManagerFactory emf;

    public UserDAO() {
        super(User.class);
    }

    @Override
    protected EntityManager getEntityManager() {
        return emf.createEntityManager();
    }

    // particular methods for this DAO

}

应用层

如果用户不存在怎么办?将此逻辑放在这一层中。

@Service
public final class UserService {

    private static final Logger LOG = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private transient UserDAO userDAO;

    public User findUser(final Long id) {
        return userDAO.find(id);
    }

}

表示层

@Controller
@RequestMapping("/user")
public final class UserController {

    private static final Logger LOG = LoggerFactory
                            .getLogger(UserController.class);

    @Autowired
    private transient UserService userService;

    @RequestMapping(value = "/find/{id}", method = RequestMethod.GET)
    public void downloadImage(
            @PathVariable("id") final Long id, 
            final HttpServletResponse response) throws IOException {
        // 
    }

}

web.xml,其中包含应用程序配置和调度程序配置:

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
  <display-name>MyWebApp</display-name>

  <!-- log4j -->
  <context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath:log4j.xml</param-value>
  </context-param>
  <context-param>
    <param-name>webAppRootKey</param-name>
    <param-value>MyWebApp.root</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>

  <!-- Spring -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!-- Welcome -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>

dispatcher-servlet.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans ···>

  <context:component-scan base-package="···.mywebapp" use-default-filters="false">
      <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
  </context:component-scan>

  <mvc:annotation-driven />

</beans>

如果你想避免 persistence.xml 文件,你可以将它放在你的 applicationContext.xml 中:

<?xml version="1.0" encoding="UTF-8"?>
<beans ···>

    <bean id="dataSource" class="···">
        <property name="URL" value="···" />
        <property name="user" value="···" />
        <property name="password" value="···" />
    </bean>

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" p:dataSource-ref="dataSource" p:packagesToScan="···.model">

        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" p:showSql="false" p:databasePlatform="org.hibernate.dialect.SQLServerDialect" />
        </property>

        <property name="jpaProperties">
            <props>
                <prop key="hibernate.format_sql">true</prop>
            </props>
        </property>

    </bean>

    <context:component-scan base-package="···.mywebapp" use-default-filters="false">
        <context:include-filter expression="org.springframework.stereotype.Repository" type="annotation"/>
        <context:include-filter expression="org.springframework.stereotype.Service" type="annotation"/>
    </context:component-scan>

</beans>

希望对您有所帮助。

关于java - View 、DAO、服务和 Controller 的基本 Hibernate 和 Spring MVC 集成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17736568/

相关文章:

java - 如何在不将 List 包装在其他类中的情况下验证 spring Controller 参数中 List 中的每个对象?

java - 在 Spring/Java 中过滤特殊字符

java.lang.IllegalArgumentException : Unable to locate persister(Hibernate 6. 0.0,无 xml)

java - 如何在hibernate继承中使用父id获取数据

java - String.split() 后无法获取子字符串?

java - 将迭代器传递给方法

java - 在appdynamics中监控java应用程序

java - jBPM 和 JPA 事务管理器 : no local transaction to join

java - Hibernate,从OneToMany列表中获取用户

java - 为什么在解析第一个字符串数组中的数据时会抛出异常,但在跳过第一个数组时不会抛出异常?