1.将上一个项目的代码简化,新建一个接口 IBaseDao 将重复的部分提取到这个接口里面
package cn.dmc.dao;
import java.io.Serializable;
import java.util.List;
public interface IBaseDao<T> {
void save(T t);
void update(T t);
void delete(Serializable i);
List<T> getAll();
T getOne(Serializable i);
}
2.让两个实际用到的接口继承这个IBaseDao ,这两个接口在代码上面是空的,但是继承了IBaseDao,实际都是有空方法的
3.写IBaseDao的实现类BaseDaoImpl,这里使用泛型来创建,后面new什么类型的对象就实现什么对象的功能
package cn.dmc.dao.impl;
import cn.dmc.dao.IBaseDao;
import cn.dmc.util.ProJPAUtil;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
public class BaseDaoImpl<T> implements IBaseDao<T> {
private Class<T> clz ;
public static EntityManager manager = ProJPAUtil.getEntityManager();
static {
manager.getTransaction().begin();
}
public BaseDaoImpl() {
//这里用到反射的原理动态获取类型
//传进来什么类型这里就获得什么类型的class
ParameterizedType parametclass = (ParameterizedType) this.getClass().getGenericSuperclass();
//获得类型的数组,这里只传进来了一个不确定类型T类型
Type[] actualTypeArguments = parametclass.getActualTypeArguments();
//第一个就是传进来的class
clz = (Class<T>) actualTypeArguments[0];
}
@Override
public void save(T o) {
manager.persist(o);
manager.getTransaction().commit();
manager.close();
}
@Override
public void update(T o) {
manager.merge(o);
manager.getTransaction().commit();
manager.close();
}
@Override
public void delete(Serializable i) {
System.out.println(i);
T t = manager.find(clz, i);
manager.remove(t);
manager.getTransaction().commit();
manager.close();
}
@Override
public List<T> getAll() {
String sql = "select p from "+ clz.getName() +" as p";
Query query = manager.createQuery(sql);
List list = query.getResultList();
return list;
}
@Override
public T getOne(Serializable i) {
T t = manager.find(clz, i);
return t;
}
}
4.两个实际用到的实现类继承BaseDaoImpl类、实现自己对应的接口,同样由于继承和实现,这两个类在代码上面是空的
5.工具类不用变util
package cn.dmc.util;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
public class ProJPAUtil {
public static EntityManagerFactory factory;
static {
factory = Persistence.createEntityManagerFactory("product02");//这里的product需要和命名空间相同
}
public static EntityManager getEntityManager(){
return factory.createEntityManager();
}
}
6.测试类不变
package cn.dmc.test;
import cn.dmc.dao.IProductDao;
import cn.dmc.dao.IProductDirDao;
import cn.dmc.dao.impl.ProductDaoImpl;
import cn.dmc.dao.impl.ProductDirDaoImpl;
import cn.dmc.domain.Product;
import cn.dmc.domain.ProductDir;
import org.junit.Test;
import java.util.List;
public class Test01 {
IProductDirDao dao2 = new ProductDirDaoImpl();
IProductDao dao = new ProductDaoImpl();
@Test
public void create(){
Product p1 = new Product();
p1.setName("good1");
p1.setDirId(1l);
dao.save(p1);
}
@Test
public void delete(){
dao.delete(5l);
}
@Test
public void updata(){
Product p1 = new Product();
p1.setName("g4");
p1.setId(5l);
p1.setDirId(1l);
dao.update(p1);
}
@Test
public void findOne(){
Product one = dao.getOne(1l);
System.out.println(one);
}
@Test
public void findAll(){
List<Product> all = dao.getAll();
System.out.println(all);
}
@Test
public void create2(){
ProductDir p = new ProductDir();
p.setName("k4");
dao2.save(p);
}
@Test
public void delete2(){
dao2.delete(4l);
}
@Test
public void update2(){
ProductDir p = new ProductDir();
p.setName("oo");
p.setId(1l);
dao2.update(p);
}
@Test
public void findOne2(){
ProductDir one = dao2.getOne(1l);
System.out.println(one);
}
@Test
public void findAll2(){
List<ProductDir> all = dao2.getAll();
all.forEach(System.out::println);
}
}
7. 配置文件
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.dmc</groupId>
<artifactId>JPA-shopping</artifactId>
<version>1.0-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.8.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.20</version>
</dependency>
</dependencies>
</project>
persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
<!--持久化单元的命名空间-->
<persistence-unit name="product02" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
<property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
<property name="hibernate.connection.username" value="root" />
<property name="hibernate.connection.password" value="123456" />
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
<!--是否每次创建连接时覆盖原来的表,第一次不存在所以需要覆盖就是新建,后面就不需要了,注释了-->
<property name="hibernate.hbm2ddl.auto" value="update" />
<!--显示出来-->
<property name="hibernate.show_sql" value="true"/>
<!--格式化-->
<property name="hibernate.format_sql" value="true"/>
</properties>
</persistence-unit>
</persistence>