使用Spring DAO和Hibernate.Problems的数据访问层

时间:2009-07-10 15:17:46

标签: java hibernate spring java-ee

大家好,这是我第一次使用spring和hibernate的应用程序。所以请跟我一起讨论愚蠢的问题:)。 我在netbeans 6.7中创建了一个简单的java应用程序。 这是我的daos接口  UsersDAO

package Dao;

import Entities.Users;

public interface UsersDAO {
    public Long GetIdByUsernameAndPasswor(String username, String password);
    public Users GetAllByID(Long id);
    public boolean Create(Users user);
    public boolean Delete(Users user);
    public boolean Edit(Users user);
}

和ContactDAO

package Dao;

import Entities.Contacts;
import java.util.List;

public interface ContactsDAO {
    public List GetAll();
    public Contacts GetAllById(Long Id);
    public boolean Create(Contacts contact);
    public boolean Delete(Contacts contact);
    public boolean Edit(Contacts contact);
}

及其实施

package Dao.DaoImpl;

import Dao.UsersDAO;
import Entities.Users;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class UserDAOImpl  extends HibernateDaoSupport implements UsersDAO {
    //    private SessionFactory sessionFactory;
    public UserDAOImpl(){}

    public Long GetIdByUsernameAndPasswor(String username, String password)
    {
        try
        {
             return DataAccessUtils.longResult(getHibernateTemplate().find("select u.user_id from Users u where u.username=? and u.password", new Object[] {username, password}) );
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return Long.parseLong("0");
        }
    }

    public Users GetAllByID(Long id) {
       try
       {
           return (Users) getHibernateTemplate().get(Users.class, id);
       }
       catch(Exception ex)
       {
            ex.printStackTrace();
            return new Users();
       }
    }

    public boolean Create(Users user) {
       try
       {
            getHibernateTemplate().save(user);
            return true;
       }
       catch(Exception ex)
       {
           ex.printStackTrace();
           return false;
       }
    }

    public boolean Delete(Users user) {
       try
       {
           getHibernateTemplate().delete(user);
           return true;
       }
       catch(Exception ex)
       {
           ex.printStackTrace();
           return false;
       }
    }

    public boolean Edit(Users user) {
       try
       {
           getHibernateTemplate().saveOrUpdate(user);
           return true;
       }
       catch(Exception ex)
       {
           ex.printStackTrace();
           return false;
       }
      }
    }

package Dao.DaoImpl;

import Dao.ContactsDAO;
import Entities.Contacts;
import java.util.List;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

public class ContactsDAOImpl extends HibernateDaoSupport implements ContactsDAO{
    public ContactsDAOImpl(){}

    public List GetAll() {
        try
        {
            return getHibernateTemplate().find("from Contacts");
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return null;
        }
    }

    public Contacts GetAllById(Long Id) {
      return (Contacts) getHibernateTemplate().get(Contacts.class, Id);
    }

    public boolean Create(Contacts contact) {
        try
        {
            getHibernateTemplate().save(contact);
            return true;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

    public boolean Delete(Contacts contact) {

        try
        {
            getHibernateTemplate().delete(contact);
            return true;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return false;
        }
    }

    public boolean Edit(Contacts contact) {

        try
        {
            getHibernateTemplate().saveOrUpdate(contact);
            return true;
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
            return false;
         }
        }
    }

我的spring配置文件位于Resources.so文件夹下,通常路径为Resouces / contactmanagement.xml

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

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver" />

    <property name="url" value="jdbc:mysql://localhost:3306/ContactsMan" />
    <property name="username" value="root" />
    <property name="password" value="letmein" />
</bean>

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.SessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <property name="mappingResouces">
        <list>
            <value>Resources/users.hbm.xml</value>
            <value>Resources/contacts.hbm.xml</value>
        </list>
    </property>
    <property name="hibernateProperties">
        <props>
            <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
            <prop key="hibernate.show_sql">true</prop>
            <prop key="hibernate.hbm2ddl.auto">create</prop>
        </props>
    </property>
</bean>
<bean id="usersdao" class="Dao.DaoImpl.UserDAOImpl">
    <property name="sessionFactory" ref="sessionFactory">
</bean>
<bean id="contactsdao" class="Dao.DaoImpl.ContactDAOImpl">
    <property name="sessionFactory" ref="sessionFactory"/>
</bean>
</beans>

映射文件位于相同的Resources文件夹users.hbm.xml contacts.hbm.xml

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="Entities.Contacts" table="contacts">
            <id name="contact_id">
                    <generator class="increment"/>
            </id>
            <many-to-one cascade="" class="Users" name="user"/>
            <property name="firstname" />
            <property name="lasstname" />
            <property name="cellphone1" />
            <property name="cellphone2" />
            <property name="telephone" />
            <property name="email" />
        </class>
    </hibernate-mapping>

<?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>
        <class name="Entities.Users" table="users">
            <id name="users_id">
                <generator class="increment"/>
            </id>
            <bag name="contacts" inverse="true" lazy="true">
                <key column="user_id"/>
                <one-to-many class="Contacts"/>
            </bag>

            <property name="username"/>
            <property name="passsword"/>
            <property name="city"/>
            <property name="country"/>

        </class>
    </hibernate-mapping>

这是我的主要课程

package main;
import Dao.UsersDAO;
import Entities.Users;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext
public class contactmanagement {

public static void main(String[] args)
{
    ApplicationContext ctx = new ClassPathXmlApplicationContext("Resources/contactmanagement.xml");
    UsersDAO usersdao = (UsersDAO) ctx.getBean("usersdao");
    Users user = new Users();
    user.setUsername("me");
    user.setPassword("mypass");
    user.setCity("somecity");
    user.setCountry("somecountry");

    usersdao.Create(user);
    System.out.println("created");
 }

当我运行它时,它说了一个摘要“没有名为'usersdao'的bean被定义”  请问我做错了什么?  这是关于DAO实现类的另一个问题。我应该设置属性setSessionFactory吗?或Spring通过getHibernateTemplate()处理每一件事? 请让我通过这个。感谢阅读。我知道它很长;)

8 个答案:

答案 0 :(得分:2)

我可能会建议您使用Spring Annotations吗?我并不是要先把你想到另一件事,但是一旦掌握了它,它就会比使所有的配置和映射文件协同工作更容易。

在这里的第3.11和3.12章中有一些非常详细的信息: Spring Documentation Chapter 3. The IoC container 但它基本上归结为:

  • 使用@Repository(或@Service)注释要定义为bean的DAO类。
  • 如果你需要使用这样的DAO,你可以使用以下方法在类中声明一个字段:@Autowired MyExampleDAO myDao; (这些类本身也应该使用@Service进行注释以使其工作(或者有其他方式,任何人吗?))
  • 配置Spring以查找这些注释,这样就可以随时为您的bean提供实现。

例如,我的整个弹簧配置如下所示:

<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">

    <context:component-scan base-package="org.path.to.your.base.package" />

    <!-- Transaction Manager -->
    <bean id="transactionManager"
        class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    <tx:annotation-driven />

    <!-- Session Factory -->
    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="configLocation" value="hibernate.cfg.xml" />
    </bean>
</beans>

样本DAO看起来像这样:

@Repository
public class UserHibDAO extends GenericHibernateDAO<HopeUser> implements UserDAO {
    public IUser findByName(String name) {
        return (User) createCriteria(Restrictions.naturalId().set("name", name)).uniqueResult();
    }
}

使用这个DAO看起来像这样:

@Service
public class Installer {
    private static final Logger log = Logger.getLogger(Installer.class);

    public static void main(String[] args) throws Exception {
        Installer inst = (Installer) SpringUtil.getContext().getBean("installer");
        inst. storeUsers();
        log.info("Done");
    }

@Autowired
private UserDAO userdao;

@Transactional
public void storeUsers() {
    userdao.makePersistent(new User("Tim"));

    log.info("Users stored");
}
}

请特别注意上一个代码示例中的main方法:这是您必须使用的而不是新的Installer()来使自动装配工作。

希望这个例子无论如何能帮助你,我意识到它不是你问题的直接答案,而是解决手头问题的另一种解决方案。

答案 1 :(得分:1)

首先,您需要在两个DAO中创建sessionFactory的setter,因为您必须在contactmanagement.xml的两个bean(UserDAO和ContectDAO)中注入sessionfactory。

另一种方法是,您可以在DAO中使用HibernateTemplete。

例如:

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate.Hibernate Template">
      <property name="sessionFactory"><ref bean="sessionFactory"/></property> 
</bean>

然后在两个(DAO)中创建hibernateTemplate的setter。 然后你可以使用 hibernateTemplate.save(); hibernateTemplate.saveOrUpdate(); hibernateTemplate.delete(); hibernateTemplate.find();
等.....

答案 2 :(得分:0)

您的格式非常糟糕,所以我还没有真正完成您的整个问题,但我确实注意到您没有在此处关闭property标记:

<bean id="usersdao" class="Dao.DaoImpl.UserDAOImpl">
    <property name="sessionFactory" ref="sessionFactory">
</bean>

应该是:

<bean id="usersdao" class="Dao.DaoImpl.UserDAOImpl">
    <property name="sessionFactory" ref="sessionFactory" />
</bean>

答案 3 :(得分:0)

一些注释,虽然我对你的问题没有答案 -

你没有使用你的界面。您有UsersDAO和UsersDAOImpl,但是Impl与接口没有任何关系,因为您省略了“implements UsersDAO”。但这不应该影响弹簧初始化。 (编辑 - 没关系这个,它在类之上,没有看到它 - 但是,你只是创建一个bean并在春天使用它 - 你真的不需要这里的接口。)

通常当我看到这个错误时,因为我要么a)拼错了bean的名字,所以没有这样的bean(你没有做过)或b)因为bean因某些原因无法实例化。你能发布完整的堆栈跟踪吗?

答案 4 :(得分:0)

尝试使用

context.getBeansOfType(UserDaoImpl.class);

context.getBeansOfType(UserDao.class);

确保没有拼写错误。

答案 5 :(得分:0)

在每次更改配置文件后,还要清理和重建项目,以确保它们实际上已移动到已编译的类并在运行应用程序时使用。

答案 6 :(得分:0)

这是一个黑暗中的镜头,但尝试干净并在Netbeans上构建。自动幕后编译不会更新.War文件中的XML。

答案 7 :(得分:0)

大家好,感谢你们所有的时间帮助我解决问题。我实际上通过查看堆栈消息解决了问题并纠正了hbm文件中大部分时间的拼写错误和错误引用并纠正了区分大小写属性的pojo。而且我也没有在任何daos中创建sessionFactory属性。 现在我在第一个问题中说的很好。虽然大多数crud函数正在工作但我仍然遇到问题,返回Users对象而不是list.of当然基于我使用的getHibernateTemplate.get(Users.class, id)

但是我希望在实现从arraylist到Users类的简单转换之后通过Username返回Users对象这里是不可能的

public Users GetUserByUsername(String username) {
  try
  {
      List userdetails = getHibernateTemplate().find("select u.user_id, u.username, u.password, u.city, u.country from Users u where u.username=?",username);
      Users u = new Users();
      u.setUser_id(Integer.parseInt(userdetails.get(0).toString()));
      u.setUsername(userdetails.get(1).toString());
      u.setPassword(userdetails.get(2).toString());
      u.setCity(userdetails.get(3).toString());
      u.setCountry(userdetails.get(4).toString());
     return u;
  }
  catch(Exception ex)
  {
      ex.printStackTrace();
      return new Users();
  }

它没有工作。我猜想也许它不会返回列,这就是为什么我改变了“来自用户u u.username =?”的查询。到上面那个。

1如何从该查询返回Users对象? 2如何返回用户列表对象?

让我担心的另一件事是如何为特定用户保存联系人。您可以从我的映射文件中注意到,表联系人通过引用user_id(这是Users表中的主键)来保持关系。在为contactdaoimpl编写单元测试时,我遇到了一个问题。众所周知,联系人pojo中有一个类的属性。然后保存id 2的联系人,例如我应该这样做吗?

Users u = new Users();
u.setUser_id(2); //supposing i have a way to get the id of the user
Contacts c = new Contacts();
c.setUser(u);
c.setFirtname("young");// an so on for the rest of the properties
contactdao.save(c);

如果这是正确的,那么在测试类中我将必须使用userdao和contactdao。 3那很好吗? 我觉得测试不仅仅是因为它与用户有依赖关系,但我仍然不知道将它们分离,我甚至不知道我应该这样做。 因此,一旦这三个担忧被清除,我将成功完成一个基本但功能性的应用程序与spring hibernate。我想在那之后我会用它来发布教程某处。谢谢阅读和帮助