抽象的なDaoを作成しようとしました。私はSpring + Hibernateを使用します。 ここに私のコードです。構成で
メインクラス:DAOとSpring Autowired
package ru.makaek.growbox.api;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
@ComponentScan(value = "ru.makaek.growbox")
@EnableAutoConfiguration(exclude = HibernateJpaAutoConfiguration.class)
@EnableTransactionManagement
@SpringBootApplication
public class Application {
@Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("datasource.driver"));
dataSource.setUrl(env.getRequiredProperty("datasource.url"));
dataSource.setUsername(env.getRequiredProperty("datasource.username"));
dataSource.setPassword(env.getRequiredProperty("datasource.password"));
return dataSource;
}
@Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(getDataSource());
sessionFactory.setPackagesToScan(new String[]{"ru.makaek.growbox"});
return sessionFactory;
}
@Bean
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
}
休憩コントローラ
package ru.makaek.growbox.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.makaek.growbox.api.model.data.entities.Device;
import ru.makaek.growbox.api.service.IStructureService;
@RestController
public class DeviceController extends AbstractController {
@Autowired
IStructureService structureService;
@RequestMapping(value = "/devices", method = RequestMethod.POST)
public Answer addDevice(@RequestBody Device device) {
structureService.addDevice(device);
return ok("Device has been added");
}
@RequestMapping(value = "/devices", method = RequestMethod.GET)
public Answer getDevices() {
return ok(structureService.getDevices());
}
@RequestMapping(value = "/devices/{deviceId}", method = RequestMethod.GET)
public Answer getDevice(@PathVariable Long deviceId) {
return ok(structureService.getDevice(deviceId));
}
}
サービス層。インターフェース
package ru.makaek.growbox.api.service;
import ru.makaek.growbox.api.model.data.entities.Device;
import java.util.List;
public interface IStructureService {
void addDevice(Device device);
List<Device> getDevices();
Device getDevice(Long deviceId);
}
サービス層。実装
package ru.makaek.growbox.api.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.makaek.growbox.api.model.data.dao.base.IDao;
import ru.makaek.growbox.api.model.data.entities.Device;
import java.util.List;
@Service
@Transactional
public class StructureService implements IStructureService {
IDao<Device> deviceDao;
@Autowired
public void setDao(IDao<Device> dao) {
deviceDao = dao;
dao.setClazz(Device.class);
}
@Override
public void addDevice(Device device) {
deviceDao.create(device);
}
@Override
public List<Device> getDevices() {
return deviceDao.findAll();
}
@Override
public Device getDevice(Long deviceId) {
return deviceDao.findOne(deviceId);
}
}
エンティティ
package ru.makaek.growbox.api.model.data.entities;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity(name = "devices")
@Data public class Device extends BaseEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
DAO。インタフェース
package ru.makaek.growbox.api.model.data.dao.base;
import ru.makaek.growbox.api.model.data.entities.BaseEntity;
import java.util.List;
public interface IDao<T extends BaseEntity> {
T findOne(final long id);
void setClazz(Class<T> clazz);
List<T> findAll();
void create(final T entity);
T update(final T entity);
void delete(final T entity);
void deleteById(final long entityId);
}
抽象DAO
package ru.makaek.growbox.api.model.data.dao.base;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import ru.makaek.growbox.api.model.data.entities.BaseEntity;
import ru.makaek.growbox.api.util.GBException;
import java.util.List;
public abstract class AbstractDao<T extends BaseEntity> implements IDao<T> {
private Class<T> clazz;
@Autowired
private SessionFactory sessionFactory;
public final void setClazz(Class<T> clazz) {
this.clazz = clazz;
}
public T findOne(long id) {
try {
return (T) getCurrentSession().get(clazz, id);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public List<T> findAll() {
try {
return getCurrentSession().createQuery("from " + clazz.getName()).list();
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void create(T entity) {
try {
getCurrentSession().persist(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public T update(T entity) {
try {
return (T) getCurrentSession().merge(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void delete(T entity) {
try {
getCurrentSession().delete(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void deleteById(long entityId) {
try {
T entity = findOne(entityId);
delete(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
protected final Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
DAO。実装
package ru.makaek.growbox.api.model.data.dao;
import org.springframework.stereotype.Repository;
import ru.makaek.growbox.api.model.data.dao.base.AbstractDao;
import ru.makaek.growbox.api.model.data.entities.Device;
@Repository
public class DeviceDao extends AbstractDao<Device> {
}
私は1つの問題があります。私はhttp://host:port/devices APIメソッドをGET呼び出すとき、私はAbstractDao.findAll()方法でclazz変数にヌルを持っています。私がコードをデバッグしているときに、興味深いものが1つ見つかりました。サービスレイヤメソッドdeviceDao.getClazz()が返されましたclazz(not null)。しかし方法でAbstractDao.findAll()私はnullにのclazz変数を持っています。どうして?助けてください。
私の英語と処方では大変申し訳ございません。私はこのサイトで新しいです、春と英語
を見てみましょう。私は、ソリューションがHibernateではなくSpringデータを使用することを正しく理解していますか? –
HibernateはJPA実装であり、Spring Data JPAはJPAデータアクセス抽象化です。 Spring Dataは、GenericDaoカスタム実装のソリューションを提供します。また、メソッド名の規則を使用して、JPAクエリーを生成することもできます。 Springデータでは、Hibernate、Eclipse Linkまたは他のJPAプロバイダを使用できます。 – toucheqt
ありがとうございます。 JPAに関する良い本や記事を私にアドバイスできますか? –