代码之家  ›  专栏  ›  技术社区  ›  black sensei

使用spring dao和hibernate的数据访问层。问题

  •  0
  • black sensei  · 技术社区  · 16 年前

    嗨,伙计们,这是我在Spring和Hibernate中的第一个应用程序。所以请忍受我愚蠢的问题:)。 我在netbeans 6.7中创建了一个简单的java应用程序。 这是我的daos接口 用户日期

    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文件夹下,所以通常路径是resources/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>
    

    映射文件位于同一资源文件夹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” 拜托,我做错什么了? 这里还有一个关于daos实现类的问题。我应该设置属性setSessionFactory吗?或者spring通过getHibernateTemplate()处理所有事情? 请让我通过这个。谢谢你的阅读。我知道它很长;)

    8 回复  |  直到 16 年前
        1
  •  2
  •   Tim    16 年前

    我可以建议您改用spring注释吗?我并不想让你先去做另一件事,但是一旦你掌握了诀窍,就比让所有的配置和映射文件一起工作要容易得多。

    在第3.11章和第3.12章中有一些非常详细的信息: Spring Documentation Chapter 3. The IoC container 但归根结底是这样的:

    • 使用@repository(或@service)注释要定义为bean的dao类。
    • 如果需要使用这样的dao,可以使用@autowired myexampledao mydao在类中声明一个字段;(这些类本身也应该用@service注释,这样才能工作(或者有其他方法吗,任何人?)
    • 将spring配置为查找这些注释,它将使之成为这样,只要您需要,就总是有一个bean的实现。

    例如,我的整个spring配置如下:

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

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

    @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()来使自动连接工作。

    希望这个例子对你有所帮助,我意识到它不是对你问题的直接回答,而是对手头问题的另一种解决方案。

        2
  •  1
  •   Jitendra Nalwaya    15 年前

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

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

    例如:

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

    然后在两者中创建hibernatemplate的setter(daos)。 以后你可以用 hibernateTemplate.save(); hibernateTemplate.saveorupdate(); hibernateTemplate.delete(); hibernateTemplate.find();
    等。。。。。

        3
  •  0
  •   Jack Leow    16 年前

    你的格式很糟糕,所以我没有仔细考虑你的整个问题,但是我注意到你没有关闭你的 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>
    
        4
  •  0
  •   Steve B.    16 年前

    虽然我对你的问题没有答案-

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

    通常,当我看到这个错误时,是因为我a)拼错了bean名称,所以没有这样的bean(您还没有这样做),或者b)因为bean由于某种原因不能被实例化。你能发布一个完整的堆栈跟踪吗?

        5
  •  0
  •   Robert Munteanu    16 年前

    尝试使用

    context.getBeansOfType(UserDaoImpl.class);
    

    context.getBeansOfType(UserDao.class);
    

    以确保没有打字错误。

        6
  •  0
  •   willcodejavaforfood    16 年前

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

        7
  •  0
  •   James McMahon    16 年前

    这是一个黑暗的拍摄,但尝试做一个干净的和建立在上网本上。后台自动编译不会更新.war文件中的xml。

        8
  •  0
  •   black sensei    16 年前

    大家好,谢谢你们花时间帮助我解决这个问题。实际上,我已经通过查看堆栈消息解决了这个问题,并在HBM文件中更正了大部分时间的拼写错误和错误引用,在POJO中更正了属性的大小写敏感度。而且,我不必在任何道斯。 现在我在第一个问题中说的很好,虽然大多数crud函数都在工作,但我仍然无法返回users对象而不是list。 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();
      }
    

    它不起作用。我猜它可能没有按顺序返回列,这就是为什么我将查询从“from users u where u.username=?”更改为“from users u where u.username=?”到上面那个。

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

    另一件让我担心的事情是如何保存特定用户的联系人。您可以从我的映射文件中注意到,表联系人通过引用用户id(用户表中的主键)来保持关系。在为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成功地完成一个基本但功能强大的应用程序。我想在那之后,我会用它在某个地方发布一个教程。谢谢你的阅读和帮助