简体   繁体   English

通用DAO,春季,休眠

[英]Generic DAO, Spring, Hibernate

I want to understand how can i implement the generic methods like add, edit, delete and search on my database, i have already made the connection (hibernate) and works fine 我想了解如何在数据库上实现添加,编辑,删除和搜索之类的通用方法,我已经建立了连接(休眠)并且工作正常

I do have this method, that works 我有这种方法,有效

Class: GenericDAO 类: GenericDAO

public <T> T save(final T o){
        Session session=HibernateUtil.getSessionFactory().openSession();
        Transaction trans=session.beginTransaction();
        Object object = (T) session.save(o);
        trans.commit();
        return (T) object;
    }

and in Main 和在主要

GenericDAO gen = new GenericDAO();
gen.save(object); 

also i have others methods that i dont know how to use them 我也有其他方法,我不知道如何使用它们

Class: GenericDAO 类: GenericDAO

public void delete(final Object object){
   Session session=HibernateUtil.getSessionFactory().openSession();
   Transaction trans=session.beginTransaction();
   session.delete(object);
   trans.commit();
}

/***/
public <T> T get(final Class<T> type, final int id){
    Session session=HibernateUtil.getSessionFactory().openSession();
    Transaction trans=session.beginTransaction();
    Object object = (T) session.get(type, id);
    trans.commit();
    return (T) object;
}

public <T> List<T> getAll(final Class<T> type) {
    Session session=HibernateUtil.getSessionFactory().openSession();
    Transaction trans=session.beginTransaction();
    final Criteria crit = session.createCriteria(type);
    List<T> list = crit.list();
    trans.commit();
    return list;
}

Thank you 谢谢

I think GenericDAO class is base class. 我认为GenericDAO类是基类。 It's not for using directly. 它不是直接使用。 Did you check this article ? 您检查了这篇文章吗? I checked this article and created a sample project. 我检查了这篇文章,并创建了一个示例项目。

Example

GitHub - generic-dao-hibernate sample GitHub-dao-hibernate-样本

For example, you might want to create an API to retrieve all employees list according to MySQL first step example. 例如,您可能想根据MySQL第一步创建一个API以检索所有员工列表。

Employees table schema is like following: 员工表架构如下所示:

Base SQL 基本SQL

    CREATE TABLE employees (
        emp_no      INT             NOT NULL,  -- UNSIGNED AUTO_INCREMENT??
        birth_date  DATE            NOT NULL,
        first_name  VARCHAR(14)     NOT NULL,
        last_name   VARCHAR(16)     NOT NULL,
        gender      ENUM ('M','F')  NOT NULL,  -- Enumeration of either 'M' or 'F'  
        hire_date   DATE            NOT NULL,
        PRIMARY KEY (emp_no)                   -- Index built automatically on primary-key column
                                               -- INDEX (first_name)
                                               -- INDEX (last_name)
    );

O/R Mapping O / R映射

Hibernate require you to configure mapping object-relation settings. Hibernate要求您配置映射对象关系设置。 After that, you will enjoy converting object-to-sql and sql-to-object. 之后,您将享受将对象转换为sql和sql-to-object的乐趣。

Entity class based on SQL 基于SQL的实体类

  • @Entity, @Table, @Id, @Column, @GeneratedValue are from Hibernate @Entity, @Table, @Id, @Column, @GeneratedValue来自Hibernate
  • @Data, @NoArgsConstructor are from lombok, it reduces getter/setter code @Data, @NoArgsConstructor来自@Data, @NoArgsConstructor ,它减少了getter / setter代码
  • @XmlRootElement, @XmlAccessorType are from jaxb, you might don't need to use it @XmlRootElement, @XmlAccessorType来自jaxb,您可能不需要使用它

     @Entity @Data @NoArgsConstructor @Table(name = "employees") @XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement public class Employees implements Serializable { private static final long serialVersionUID = 1L; @Id @Column(name = "emp_no", unique = true) @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer empNo; @Column(name = "birth_date") private Date birthDate; @Column(name = "first_name") private String firstName; @Column(name = "last_name") private String lastName; @Column(name = "gender") @Enumerated(EnumType.STRING) private Gender gender; @Column(name = "hire_date") private Date hireDate; } 

Resource Class for Frontend 前端资源类

You always need to write DAO(Data Access Object) for accessing the database. 您始终需要编写DAO(数据访问对象)来访问数据库。 GenericDAO is a method to reduce boilerplate sources codes. GenericDAO是一种减少样板源代码的方法。

EmployeesResource class 员工资源类

  • CRUD operations on WEB API WEB API上的CRUD操作
    • #create , #read , #update or #delete #create#read#update#delete

should be equivalent with 应该与

  • SQL 的SQL
    • INSERT , SELECT , UPDATE and DELETE INSERTSELECTUPDATEDELETE

You need to identify a record or records with key. 您需要标识一条记录或带有键的记录。 In this case, id is sample primary key. 在这种情况下, id是样本主键。

    @Path("/employee")
    public class EmployeesResource {

        static Logger log = LoggerFactory.getLogger(EmployeesResource.class);

        @GET
        @Produces(MediaType.APPLICATION_JSON)
        public List<Employees> index(@BeanParam Employees paramBean) {
            EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
            List<Employees> result = dao.read();
            System.out.println("Get all employees: size = " + result.size());
            return result;
        }

        @GET
        @Path("{id}")
        @Produces(MediaType.APPLICATION_JSON)
        public Employees show(@PathParam("id") Integer id) {
            EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
            System.out.println("Get employees -> id = " + id);
            return dao.read(id);
        }

        @POST
        @Consumes(MediaType.APPLICATION_JSON)
        public Integer create(Employees obj) {
            EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
            return dao.create(obj);
        }

        @PUT
        @Path("{id}")
        @Consumes(MediaType.APPLICATION_JSON)
        public void update(Employees obj, @PathParam("id") String id) {
            EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("employeesDao");
            dao.update(obj);
        }

        @DELETE
        @Path("{id}")
        public void destroy(@PathParam("id") Integer id) throws Exception {
            EmployeesDao dao = (EmployeesDao) SpringApplicationContext.getBean("EmployeesDao");
            dao.delete(id);
        }
    }

GenericDao interface & implementation GenericDao接口和实现

Interface ( as is from ibm's post ) 界面 (如ibm的帖子所述)

According to the post, we can declare dao interface. 根据帖子,我们可以声明dao接口。 Then we should implement that interface's methods. 然后,我们应该实现该接口的方法。

    public interface GenericDao<T, PK extends Serializable> {

        /** Persist the newInstance object into database */
        PK create(T newInstance);

        /**
         * Retrieve an object that was previously persisted to the database using
         * the indicated id as primary key
         */
        T read(PK id);
        List<T> read();

        /** Save changes made to a persistent object. */
        void update(T transientObject);

        /** Remove an object from persistent storage in the database */
        void delete(PK id) throws Exception;
        void delete(T persistentObject) throws Exception;
    }

Implementation 实作

    public class GenericDaoHibernateImpl<T, PK extends Serializable> implements GenericDao<T, PK> {

        private Class<T> type;

        @Autowired
        private SessionFactory sessionFactory;

        public SessionFactory getSessionFactory() {
            return sessionFactory;
        }

        public void setSessionFactory(SessionFactory sessionFactory) {
            this.sessionFactory = sessionFactory;
        }

        public GenericDaoHibernateImpl(Class<T> type) {
            this.type = type;
        }

        // Not showing implementations of getSession() and setSessionFactory()
        private Session getSession() {
            Session session = sessionFactory.getCurrentSession();
            return session;
        }

        @Transactional(readOnly = false, rollbackFor = RuntimeException.class)
        public PK create(T o) {
            return (PK) getSession().save(o);
        }

        @Transactional(readOnly = false, rollbackFor = RuntimeException.class)
        public void update(T o) {
            getSession().update(o);
        }

        @Transactional(readOnly = true)
        public T read(PK id) {
            return (T) getSession().get(type, id);
        }

        @SuppressWarnings("unchecked")
        @Transactional(readOnly = true)
        public List<T> read() {
            return (List<T>) getSession().createCriteria(type).list();
        }

        @Transactional(readOnly = false, rollbackFor = RuntimeException.class)
        public void delete(PK id) {
            T o = getSession().load(type, id);
            getSession().delete(o);
        }

        @Transactional(readOnly = false, rollbackFor = RuntimeException.class)
        public void delete(T o) {
            getSession().delete(o);
        }

If you use only simple CRUD operations in the project, you don't need to append any code for SQL operations. 如果在项目中仅使用简单的CRUD操作,则无需为SQL操作附加任何代码。 For example, you can create another simple SQL tables like divisions_table or personnel_table with using extends GenericDao<Division, Integer> or extends GenericDao<Personnel, Integer> . 例如,您可以使用extends GenericDao<Division, Integer>extends GenericDao<Personnel, Integer>创建另一个简单的SQL表,例如divisions_tablepersonnel_table

EDIT 编辑

To instantiate real dao class related with each table, you need to configure applicationContext.xml and beans. 要实例化与每个表相关的真实dao类,您需要配置applicationContext.xml和bean。

example

<bean id="employeesDao" parent="abstractDao">
    <!-- You need to configure the interface for Dao -->
    <property name="proxyInterfaces">
        <value>jp.gr.java_conf.hangedman.dao.EmployeesDao</value>
    </property>
    <property name="target">
        <bean parent="abstractDaoTarget">
            <constructor-arg>
                <value>jp.gr.java_conf.hangedman.models.Employees</value>
            </constructor-arg>
        </bean>
    </property>
</bean>

PS 聚苯乙烯

You need to remember this article was written a decade ago. 您需要记住这篇文章是十年前写的。 And, you should think seriously about which O/R mapper is really good or not. 并且,您应该认真考虑哪个O / R映射器确实好。 I think O/R mapper is slightly declining now. 我认为O / R映射器现在略有下降。 Instead of Hibernate, you can find MyBatis , JOOQ 除了Hibernate,您还可以找到MyBatisJOOQ

This is one way to implement a hibernate centric generic DAO. 这是实现休眠中心通用DAO的一种方法。 It provides basic CRUD operations along with simple search but can be extended to include other generic features. 它提供基本的CRUD操作以及简单的搜索,但可以扩展为包括其他通用功能。

IGenericDAO interface IGenericDAO界面

public interface IGenericDAO<T extends Serializable> {

T findOne(long id);

List<T> findAll();

void create(T entity);

void update(T entity);

void delete(T entity);

void deleteById(long entityId);

public void setClazz(Class<T> clazzToSet);

}

AbstractTemplateDAO 抽象模板

import java.io.Serializable;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

public abstract class AbstractHibernateDAO<T extends Serializable> implements IGenericDAO<T> {

private Class<T> clazz;

@Autowired
SessionFactory sessionFactory;

public final void setClazz(Class<T> clazzToSet) {
    this.clazz = clazzToSet;
}


@Override
public T findOne(long id) {
    return (T) getCurrentSession().get(clazz, id);
}


@Override
public List<T> findAll() {
    return getCurrentSession().createQuery("from " + clazz.getName(),clazz).getResultList();
}


@Override
public void create(T entity) {
    getCurrentSession().persist(entity);
}


@Override
public void update(T entity) {
    getCurrentSession().merge(entity);
}


@Override
public void delete(T entity) {
    getCurrentSession().delete(entity);
}


@Override
public void deleteById(long entityId) {
    T entity = findOne(entityId);
    delete(entity);
}

protected final Session getCurrentSession() {
    return sessionFactory.getCurrentSession();
    }
}

GenericHiberateDAO 通用冬眠DAO

Note: the use of scope prototype here. 注意:这里使用范围原型。 The spring container creates a new instance of the dao on each request. 弹簧容器在每个请求上创建dao的新实例。

@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class GenericHibernateDAO<T extends Serializable> extends AbstractHibernateDAO<T> 
implements IGenericDAO<T> {
   //
}

Service class 服务等级

Shows how to use autowire the generic dao in a service class and pass the model class a parameter. 显示如何在服务类中使用自动连接通用dao以及如何向模型类传递参数。 Also, do note that this implementation uses @Transactional annotation for spring transaction management. 另外,请注意,此实现使用@Transactional注释进行Spring事务管理。

@Service
public class TestService implements ITestService {

private IGenericDAO<TestModel> dao;

@Autowired
public void setDao(IGenericDAO<TestModel> daoToSet) {
    dao = daoToSet;
    dao.setClazz(TestModel.class);

}

@Override
@Transactional
public List<TestModel> findAll() {
    return dao.findAll();
}
}

App Config 应用配置

Shows how to set up spring for automatic transaction management using @EnableTransactionManagement 显示如何使用@EnableTransactionManagement为自动交易管理设置spring

@Configuration
@ComponentScan("com.base-package")
@EnableTransactionManagement
public class AppConfig {

       // add hibernate configuration

      // add beans


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM