简体   繁体   English

视图,DAO,服务和控制器的基本Hibernate和Spring MVC集成

[英]basic hibernate and spring mvc integration of view, dao, service and controller

Status: Thankful to the answers but No one has answered the Important tag description in reflection to my simple code given. Status:感谢您的回答,但是没有人回答我的简单代码,从而对重要标签的描述做出了回答。 (20 Jul 13) (13年7月20日)

I have read many tutorials and yet every thing just mixes up or is only as a specific example that looks tiny or abstract. 我已经阅读了许多教程,但每件事都只是混在一起,或者只是作为看起来很小或很抽象的特定示例。

I really cannot make something get logical in my mind. 我真的无法使某些事情变得合乎逻辑。 May be I learn with specific actual code. 可能是我学习了特定的实际代码。

Question: Can anyone show how to make the following incomplete code work completely with spring 3.x and hibernate 4.x. 问题:谁能说明如何使以下不完整代码在spring 3.x和hibernate 4.x中完全work completely


Important: 重要:

I would like, even in this simple example, make sessionfactory and database quering by hibernate in the Service class (making boundry there as in large applications Service classes use many DAOs and commit transactions in one go ) 我想,即使在这个简单的示例中,也可以通过休眠在Service类中进行sessionfactory和数据库查询(在大型应用程序中像在服务类中那样使边界受限) Service类使用许多DAO并一次性提交事务)

I forget where i read it, perhaps in the spring documentation - but it clearly said, don't put @Transactional on your DAOs :P so generally, your service tier is where you define your transaction boundaries. 我可能会在春季文档中忘了我在哪里读的书-但它清楚地说,不要在@DAO:P上使用@Transactional,因此通常,您的服务层是定义事务边界的地方。 a service method is typically a chunk of things that if all pass, commit otherwise fail and rollback That may not be a diehard rule of course, but its how we architected our enterprise resource planning web core. 服务方法通常是一堆东西,如果全部通过,否则将提交,否则将失败并回滚,这当然不是硬道理,而是我们如何设计企业资源计划Web核心的方法。 I forget where i read it, perhaps in the spring documentation - but it clearly said, don't put @Transactional on your DAOs 我忘记了我在哪里阅读的内容,也许是在春季文档中-但它明确指出,不要在您的DAO上使用@Transactional

eg http://blog.patouchas.net/technology/hibernate-dao-java-tutorial/ like without spring ? 例如http://blog.patouchas.net/technology/hibernate-dao-java-tutorial/喜欢没有弹簧?


The annotations are missing or incorrect. 注释丢失或不正确。 What should be the correct annotations. 什么是正确的注释。

Would there be any spring.xml (other than the usual) for these classes in specific? 具体来说,这些类是否会有spring.xml(不同于通常的)? I would like to prefer only annotations if it works. 我希望仅在能工作的情况下使用注释。 correct annotations like @component , service, repository, resource, autowired 正确的批注,例如@component,服务,存储库,资源,自动装配

This is how I get the transaction generally 这就是我一般如何获得交易的方式

   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();

now spring and hibernate 现在春天冬眠

@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?
    }
}

this wont be so important though. 不过,这不会那么重要。

<?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;
    }
}

If you are using Spring 3.x and Hibernate 4.x, you can consider a three-tier application architecture : 如果您使用的是Spring 3.x和Hibernate 4.x,则可以考虑三层应用程序体系结构

Data tier 资料层

You could have an abstract base class for common DAO methods. 您可以为常见的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

}

In every DAO implementation, you can put particular methods for that DAO. 在每个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

}

Application tier 应用层

What if the user does not exist? 如果该用户不存在怎么办? Put this logic in this tier. 将此逻辑放在这一层中。

@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);
    }

}

Presentation tier 展示层

@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 {
        // 
    }

}

The web.xml , this contains the Application config and the Dispatcher config: 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>

The dispatcher-servlet.xml : 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>

And if you want to avoid the persistence.xml file, you can have it in your applicationContext.xml : 而且,如果要避免使用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>

I hope this can help you. 希望对您有所帮助。

i dont know the best practice but this code worked for me : 我不知道最佳实践,但是这段代码对我有用:

i write HibernateUtil to connect to DB : 我写了HibernateUtil连接到数据库:

import org.hibernate.SessionFactory;
import org.hibernate.cfg.AnnotationConfiguration;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;
    static {
        try {
            sessionFactory = new AnnotationConfiguration().configure()
                    .buildSessionFactory();
            System.out.println("session Factory = "+sessionFactory.toString()+" current session="+sessionFactory.getCurrentSession()+
                    " collection="+sessionFactory.getAllCollectionMetadata()+" collection="+sessionFactory.getStatistics());
        } catch (Throwable ex) {
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

one of my model : 我的模特之一:

import javax.persistence.Column;
import javax.persistence.Entity;

import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;

@Entity
public class Product {

    @ManyToOne
    @JoinColumn(name = "providerid")
    private Provider provider;
    @Id
    private String productCode;
    private int nominal;
    private double buyPrice;
    private double sellPrice;
    @ManyToOne
    @JoinColumn(name = "supplierid")
    private Supplier supplier;

    public Product(){
    }

    public Product(String id){
        setProductCode(id);

    }

    //setter and getter
}

DAO : 道:

import java.util.List;

public interface ProductDAO {

    public void save(Product product, int mode);

    public List<Product> list();

    public Product get(String id);

}

DAO Implementation : DAO实施:

import java.util.List;
import org.hibernate.SessionFactory;
import org.springframework.orm.hibernate3.HibernateTemplate;
import com.util.HibernateUtil;
import com.util.SessionHelper;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.Transaction;

public class ProductDAOImpl implements ProductDAO {

    private HibernateTemplate hibernateTemplate;
    private TableIDDAO tableIDDao;

    public void setTableIDDao(TableIDDAO tableIDDao) {
        this.tableIDDao = tableIDDao;
    }

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.hibernateTemplate = new HibernateTemplate(sessionFactory);
    }

    @Override
    public void save(Product product, int mode) {
        SessionFactory sf = HibernateUtil.getSessionFactory();
        Session session = sf.getCurrentSession();
        Transaction tr = session.beginTransaction();
        session.saveOrUpdate(product);      
        tr.commit();
    }

    @Override
    @SuppressWarnings("unchecked")
    public List<Product> list() {
        return hibernateTemplate.find(" from Product ");
    }

    @Override
    public Product get(String id) {
        List<Product> list = hibernateTemplate.find(" from Product where productCode='" + id + "'");
        Product c = null;
        if (!list.isEmpty()) {
            c = list.get(0);
        }
        return c;
    }
}

Controller (from controller we call dao - i write this long time ago so still use modelandview, its better if you use annotation cause modelandview is obsolete) : 控制器(从控制器我们称为dao-我很久以前就写过,所以仍然使用modelandview,如果使用注释则更好,因为modelandview已过时):

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;
import com.util.SessionHelper;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;

public class ProductController extends MultiActionController {

    private ProductDAO productDAO;

    public void setProductDAO(ProductDAO productDAO) {
        this.productDAO = productDAO;
    }

    public ProductController() {
        System.out.println("Masuk ke Contrutctor Product Controller");
    }

    public ModelAndView add(HttpServletRequest request,
            HttpServletResponse response, Product product) throws Exception {
        productDAO.save(product,mode);
        return new ModelAndView("redirect:list.htm");
    }

    public ModelAndView list(HttpServletRequest request,
            HttpServletResponse response,Page p) throws Exception {
        ModelMap modelMap = new ModelMap();
        modelMap.addAttribute("productList", page.paging(productDAO.list()));
        modelMap.addAttribute("product", new Product());
        return new ModelAndView("product", modelMap);
    }
}

My JSP : 我的JSP:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
         pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%>

<html>
    <body>
        <div class="content"> 
            <c:if test="${fn:length(productList) > 0}">
                <table cellpadding="5">
                    <tr class="even">
                        <th>Product Code</th>
                        <th>nominal</th>
                        <th>buy price</th>
                        <th>Sell Price</th>
                        <th>Provider</th>
                        <th>Supplier</th>
                    </tr>
                    <c:forEach items="${productList}" var="product" varStatus="status">
                            <td>${product.productCode}</td>
                            <td>${product.nominal}</td>
                            <td>${product.buyPrice}</td>
                            <td>${product.sellPrice}</td>
                            <td>${product.provider.namaProvider}</td>
                            <td>${product.supplier.name}</td>
                        </tr>
                    </c:forEach>
                </table>
            </c:if>
                    <p>Data Form</p>
            <form:form action="add.htm" commandName="product">
                <table>
                    <tr>
                        <td>Product Code :</td>
                        <td><form:input path="productCode" /></td>
                    </tr>
                    <tr>
                        <td>Nominal :</td>
                        <td><form:input path="nominal" /></td>
                    </tr>
                    <tr>
                        <td>Buy Price :</td>
                        <td><form:input path="buyPrice" /></td>
                    </tr>
                    <tr>
                        <td>Sell Price :</td>
                        <td><form:input path="sellPrice" /></td>
                    </tr>
                    <tr>
                        <td>Provider :</td>
                        <td><form:select path="provider.providerID"  modelAttribute="contact" >
                                <form:options items="${providerList}" itemValue="providerID" itemLabel="namaProvider" />
                            </form:select>
                        </td>
                    </tr>
                    <tr>
                        <td>Provider :</td>
                        <td><form:select path="supplier.supplierID"   >
                                <form:options items="${supplierList}" itemValue="supplierID" itemLabel="name" />
                            </form:select>
                        </td>
                    </tr>
                    <tr>
                        <td colspan="2"><input type="submit" value="Register"></td>
                    </tr>
                </table>
            </form:form>
        </div>
    </body>
</html>

and you also need to configure your spring configuration and include it in your web.xml all jsp i put in /WEB-INF/pages/... its up to you if you want put it somewhere else 并且您还需要配置spring配置并将其包含在web.xml中,我将其放在/ WEB-INF / pages /中的所有jsp ...如果您希望将其放置在其他位置,则取决于您

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/pages/" p:suffix=".jsp" />

    <bean id="myDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
        <property name="driverClassName" value="org.springframework.jdbc.datasource.DriverManagerDataSource"/>
        <property name="url" value="jdbc:mysql://localhost:3306/yourdatabase"/>
        <property name="username" value="root"/>
        <property name="password" value="yourmysqlpassword"/>
    </bean>

    <bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="myDataSource" />
        <property name="annotatedClasses">
            <list>
                <value>com.bean.Product</value>
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
            </props>
        </property>
    </bean>

    <bean id="myProductDAO" class="com.dao.ProductDAOImpl">
        <property name="sessionFactory" ref="mySessionFactory"/>
    </bean>

    <bean name="/product/*.htm" class="com.controller.ProductController" >
        <property name="productDAO" ref="myProductDAO" />
    </bean>

</beans>

also you need create hibernate.cf.xml in your root of your code : 您还需要在代码的根目录中创建hibernate.cf.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
  <session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/yourdatabase</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">yourmysqlpassword</property>
    <property name="hibernate.connection.driver_class"> org.hsqldb.jdbcDriver</property>
    <property name="current_session_context_class">thread</property>
    <property name="connection.pool_size">3</property>
    <property name="show_sql">true</property>
    <mapping class="com.bean.Product" />    
  </session-factory>
</hibernate-configuration>

i dont give you exactly the same to my real code, but i think its enough to give you an inspiration. 我没有给您与我的真实代码完全相同的代码,但我认为它足以给您启发。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM