实习第一个阶段,来这边有小半个月了,前面一周在熟悉这边开发平台,最近在学习一些基础技术,周末开始接受培训,这个公司用的是自己的框架,但是底层使用的还是springMVC,jpa,hibernate这一套,只是对这些进行了封装,两天熟悉了下jpa今天开始整合一个demo
1、首先导入相关的依赖包spring、hibernate、jpa
2、接下来是基本的配置,数据源、jpa实体管理工厂(hibernate的一些设置)、注解扫描、spring事务管理、事务的注解启动、jpatemplate
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.1.xsd">
<!-- annotation scan -->
<context:component-scan base-package="com.wyk.sh4"/>
<!-- Data sourse -->
<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/test" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<!-- This will ensure that Hibernate or JPA exceptions are automatically
translated into Spring's generic DataAccessException hierarchy for those
classes annotated with Repository. For example, see ***DAOImpl. -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor" />
<!-- JPA Entity Manager Factory -->
<!-- toscan待扫描的实体类包,不再需要persistence.xml -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
p:packagesToScan="com.wyk.sh4.domain" p:dataSource-ref="dataSource"
p:jpaVendorAdapter-ref="hibernateVendor" p:jpaPropertyMap-ref="jpaPropertyMap"/>
<util:map id="jpaPropertyMap">
<entry key="hibernate.hbm2ddl.auto" value="update"/>
<entry key="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
<!-- To enable Hibernate's second level cache and query cache settings -->
<entry key="hibernate.max_fetch_depth" value="4" />
</util:map>
<bean id="hibernateVendor"
class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"
p:database="MYSQL" p:showSql="true" p:generateDdl="true"
p:databasePlatform="org.hibernate.dialect.MySQLDialect"/>
<!-- User declarative transaction management -->
<tx:annotation-driven transaction-manager="transactionManager"/>
<!-- Transaction Config -->
<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager"
p:entityManagerFactory-ref="entityManagerFactory">
<property name="jpaDialect">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
</property>
</bean>
<!-- jpaTemplate manager entityManagerFactory -->
<bean id="jpaTemplate"
class="org.springframework.orm.jpa.JpaTemplate"
p:entityManagerFactory-ref="entityManagerFactory"/>
</beans>
3、完成配置之后进行测试
Domain对象
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String username;
private String pwd;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
DAO层
BaseDAO
public abstract class BaseDAO<T> implements IBaseDAO<T> {
@Resource(name="jpaTemplate")
private JpaTemplate jpaTemplate;
//居图数据类型处理
private Class<T> clazz = null;
public BaseDAO(){
//--获得具体类的具体类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
clazz = (Class<T>) pt.getActualTypeArguments()[0];
}
@Override
public void add(T entity) {
jpaTemplate.persist(entity);
}
@Override
public void update(T entity) {
jpaTemplate.merge(entity);
}
@Override
public void delete(Long[] ids) {
for(Long id : ids){
jpaTemplate.remove(getById(id));
}
}
@Override
public T getById(Long id) {
return jpaTemplate.find(clazz, id);
}
@Override
public List<T> getByIds(final List ids) {
return (List<T>) jpaTemplate.execute(new JpaCallback<T>() {
@Override
public T doInJpa(EntityManager em) throws PersistenceException {
return (T) em.createQuery("FROM " + clazz.getSimpleName() + " WHERE id IN(:ids)")
.setParameter("ids", ids)
.getResultList();
}
});
}
}
StudentDAO
/**
* 实体DAO,完成实体对应的特殊操作
* @author yk-Woo
*
*/
@Repository
public class StudentDAO extends BaseDAO<Student> implements IStudentDAO{
}
Service层
/**
* 业务层,处理业务逻辑
* @author yk-Woo
*
*/
@Service
@Transactional
public class StudentService implements IStudentService {
@Resource
private IStudentDAO StudentDAO;
@Override
public void add(Student entity) {
this.StudentDAO.add(entity);
}
@Override
public void update(Student entity) {
this.StudentDAO.update(entity);
}
@Override
public void delete(Long[] ids) {
this.StudentDAO.delete(ids);
}
@Override
public Student getById(Long id) {
return this.StudentDAO.getById(id);
}
@Override
public List<Student> getByIds(List ids) {
return this.StudentDAO.getByIds(ids);
}
}
这里要注意:
1、hibernate中使用批量查询使用“IN {:ids}”这里使用的是 "IN (:ids)"符号不一样,在这里使用“{}”会导致语法报错;
2、这里ids用到的参数是List,hibernate中用改的是LONG[];
3、由于配置了事务管理,在执行“增加”、“修改”等操作时需要使用@Transaction注解开启事务;
4、通常做法是在service层中加@Transaction每次调用dao的操作时根据具体注解情况spring会帮我们开启事务与关闭,这里如果直接使用DAO层的话(测试过程中),在basedao的实现中需要加入@Transaction启用注解,具体实现类中的具体方法也需要加;
5、这里我们使用的是jpaTemplate进行操作实体,不需要关注createEntityManage以及close