簡體   English   中英

視圖,DAO,服務和控制器的基本Hibernate和Spring MVC集成

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

Status:感謝您的回答,但是沒有人回答我的簡單代碼,從而對重要標簽的描述做出了回答。 (13年7月20日)

我已經閱讀了許多教程,但每件事都只是混在一起,或者只是作為看起來很小或很抽象的特定示例。

我真的無法使某些事情變得合乎邏輯。 可能是我學習了特定的實際代碼。

問題:誰能說明如何使以下不完整代碼在spring 3.x和hibernate 4.x中完全work completely


重要:

我想,即使在這個簡單的示例中,也可以通過休眠在Service類中進行sessionfactory和數據庫查詢(在大型應用程序中像在服務類中那樣使邊界受限) Service類使用許多DAO並一次性提交事務)

我可能會在春季文檔中忘了我在哪里讀的書-但它清楚地說,不要在@DAO:P上使用@Transactional,因此通常,您的服務層是定義事務邊界的地方。 服務方法通常是一堆東西,如果全部通過,否則將提交,否則將失敗並回滾,這當然不是硬道理,而是我們如何設計企業資源計划Web核心的方法。 我忘記了我在哪里閱讀的內容,也許是在春季文檔中-但它明確指出,不要在您的DAO上使用@Transactional

例如http://blog.patouchas.net/technology/hibernate-dao-java-tutorial/喜歡沒有彈簧?


注釋丟失或不正確。 什么是正確的注釋。

具體來說,這些類是否會有spring.xml(不同於通常的)? 我希望僅在能工作的情況下使用注釋。 正確的批注,例如@component,服務,存儲庫,資源,自動裝配

這就是我一般如何獲得交易的方式

   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,則可以考慮三層應用程序體系結構

資料層

您可以為常見的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>

希望對您有所幫助。

我不知道最佳實踐,但是這段代碼對我有用:

我寫了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;
    }
}

我的模特之一:

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
}

道:

import java.util.List;

public interface ProductDAO {

    public void save(Product product, int mode);

    public List<Product> list();

    public Product get(String id);

}

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

控制器(從控制器我們稱為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);
    }
}

我的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>

並且您還需要配置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>

您還需要在代碼的根目錄中創建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>

我沒有給您與我的真實代碼完全相同的代碼,但我認為它足以給您啟發。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM