1

Status:感谢答案,但没有人回答重要标签描述以反映我给出的简单代码。(2013 年 7 月 20 日)

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

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

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


重要的:

即使在这个简单的示例中,我也希望在 Service类中通过 hibernate进行sessionfactory和数据库查询(在大型应用程序中设置边界服务类使用许多 DAO 并一次性提交事务)

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

例如 http://blog.pattouchas.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;
    }
}
4

2 回答 2

7

如果你使用 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>

我希望这可以帮助你。

于 2013-07-19T15:52:21.637 回答
2

我不知道最佳实践,但这段代码对我有用:

我写 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中所有jsp我放在/WEB-INF/pages/...如果你想把它放在其他地方,这取决于你

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

我没有给你完全一样的我的真实代码,但我认为它足以给你一个灵感。

于 2013-07-19T02:32:48.197 回答