Java 我怎样才能很好地混合冬眠和摇摆

Java 我怎样才能很好地混合冬眠和摇摆,java,hibernate,swing,service-layer,Java,Hibernate,Swing,Service Layer,关于与Hibernate的交互,我有一些问题: 我使用openSession还是getCurrentSession(不使用jta,而是线程) 如何将会话操作与Swing GUI混合使用?在JavaBean类中是否有如下代码 public void actionPerformed(ActionEvent event) { // session code } 我是否可以向包含HQL查询的实体添加方法,或者这是一种不好的做法?例如: // This method is in an ent

关于与Hibernate的交互,我有一些问题:

  • 我使用openSession还是getCurrentSession(不使用jta,而是线程)
  • 如何将会话操作与Swing GUI混合使用?在JavaBean类中是否有如下代码

    public void actionPerformed(ActionEvent event) {
        // session code
    }
    
  • 我是否可以向包含HQL查询的实体添加方法,或者这是一种不好的做法?例如:

     // This method is in an entity MyOtherEntity.java class
     public int getDuration(){
        Session session = HibernateUtil.getSessionFactory().getCurrentSession();
        session.beginTransaction();
        int sum = (Integer) session.createQuery("select sum(e.duration) as duration from MyEntity as e where e.myOtherEntity.id=:id group by e.name").
            .setLong("id", getId());
            .uniqueResult();
        return sum;
     }
    
  • 我怎样才能以一种更好、更优雅的方式做到这一点

    更新 一种广泛使用的做法是创建一个服务/dao类来实现实体类的CRUD操作。但为什么这样好呢? 为什么我必须为每个实体编写一个类来管理它?真正的优势在哪里

    更新2 服务类是DAO模式吗?这是什么意思?
    是一种DAO模式,这就是所谓的“服务层”吗?

    如果你想依赖普通的Hibernate API,你可以使用服务层,因为

    • 它是用例驱动的
    • 划定交易边界
    因此,您可以创建一个AccountService,例如

    public static path.to.HibernateUtil.getSessionFactory;
    
    public class AccountService {
    
        public void withdraw(Integer accountNumber, BigDecimal amount) throws Exception {
            /**
              * Here you set up Transaction boundaries
              */
            getSessionFactory().getCurrentSession().beginTransaction();
    
            // Some actions goes here
    
            getSessionFactory().getCurrentSession().getTransaction().commit();
        }
    
    }
    
    在服务层内执行某些操作时,通常需要一个存储库。您可以将repository视为数据提供者和存储器。您可以看到我如何实现我的存储库

    如果您想要一个可维护且可读的HQL查询,我建议您将HQL查询外部化为一个多行且外部化的xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <query name="GIFT_CARDS_WITH_BUYER">
            <![CDATA[
                from 
                    GiftCard c
                left join fetch 
                    c.buyer
                where
                    c.recipientNotificationRequested = 1
           ]]>
        </query>
        <query name="GIFT_CARDS_WITHOUT_NO_RELATIONSHIP">
            <![CDATA[
                from 
                    GiftCard
            ]]>
        </query>
    </hibernate-mapping>
    
    在实体中使用持久性操作不是一个好主意。如果需要在实体内执行与持久性相关的问题,我认为最好将存储库作为参数传递给实体

    public class Account {
    
       public void doSomething(AccountRepository repository) {
           // code goes here
       }
    
    }
    
    也许你想看看线程

    我建议您看看《使用Hibernate实现Java持久化》一书,第9章(使用对象)附件:仔细阅读

    更新

    为什么有一个好的服务层

    首先

    • 它是用例驱动的(它画出你的应用程序应该做什么)
    其次

    • 它划定了交易边界
    假设这里是您的服务层

    public class MyService {
    
        public void doSomething() {
            getSessionFactory().beginTransaction();
    
            // A POJO doing some operation
    
            // Other POJO doing other operation
    
            // Another POJO doing another operation
    
            getSessionFactory().getTransaction().commit();
        }
    
    }
    

    注意,您只定义了一个事务边界,而不是在每个POJO中定义每个事务边界。此外,无论Swing GUI中的业务规则是否需要在其他组件中使用,都会发生什么。你会使用Ctrl-c+Ctrl-v吗

    嗨!谢谢你,你的answare给了我她的问题。。为什么有一个好的服务层?我更新了我的帖子。好吧,我想现在我已经明白了。。我希望:)再次感谢@请参阅,以获得我使用服务(用例驱动和事务边界)和存储库(检索实体)的良好见解。请记住,对于您拥有的每个实体,您不需要每个存储库。如果需要,您只需编写一个存储库。因为我的问题是如何以良好的方式混合hibernate和swing。哈哈哈。。。哈哈,问这个问题很好:D@blow
    public class MyService {
    
        public void doSomething() {
            getSessionFactory().beginTransaction();
    
            // A POJO doing some operation
    
            // Other POJO doing other operation
    
            // Another POJO doing another operation
    
            getSessionFactory().getTransaction().commit();
        }
    
    }