首先配置好persistence.xml
我们再来简单创建两个类,完成多对一
/** *多方 * 产品类 * * */ //交给jpa管理,在mysql中创建对应的表@Entity@Table(name="t_product")public class Product { //设置主键,自增 @Id @GeneratedValue private Long id; private String name; //设置附键 @ManyToOne(fetch = FetchType.LAZY)//懒加载延迟加载,提高性能 @JoinColumn(name = "dir_id") private ProductDir dir;}
/** *一方 * 产品类型类 * */@Entity@Table(name="t_productDir")public class ProductDir { @Id @GeneratedValue private Long id; private String name; }
接下来我们来完成多对一的CRUD
首先我们来抽取一个获取EntityManager实体管理对象的工具类
/** * * 抽取创建EntityManager的工具类 */public class Jpautil { private static EntityManagerFactory factory; //放入静态代码块中实现单例 static{ try { //获取工厂类 factory = Persistence.createEntityManagerFactory("cn.itsource.jpa"); } catch (Exception e) { e.printStackTrace(); } } //返回EntityManager的方法 public static EntityManager getEntityManager(){ return factory.createEntityManager(); }}
接下来我们来完成Dao层代码的编写,由于CRUD的方法类似,我们来抽取代码,做一个代码的简化,注意这里放置的是共有的方法
public interface IBaseDao{ //保存 void save(T t); //修改 void update(T t); //删除 void delete(Serializable id); //查询一条数据 T queryOne(Serializable id); //查询所有数据 List queryAll();}
我们让两个类的接口都去继承它
public interface IProductDao extends IBaseDao{ //这里现在写了其实没有实现任何功能,当时当我们后续这个类有自己独有的方法的时候,就可以在这里添加自己的方法}public interface IProductDirDao extends IBaseDao {}
再写一个共有的实现类去实现IBaseDao公共接口
public class BaseDaoImplimplements IBaseDao { //在查询中要使用到的实体类 private Class entityClass; //通过构造方法子类可以传入他的实体类 public BaseDaoImpl(Class entityClass) { this.entityClass = entityClass; } //保存方法 @Override public void save(T t) { EntityManager entityManager = null; try { entityManager = Jpautil.getEntityManager(); //开启事务 entityManager.getTransaction().begin(); //保存 entityManager.persist(t); //提交事务 entityManager.getTransaction().commit(); } catch (Exception e) { //回滚事务 entityManager.getTransaction().rollback(); e.printStackTrace(); } finally { //关闭 entityManager.close(); } } //修改方法 @Override public void update(T t) { EntityManager entityManager = null; try { entityManager = Jpautil.getEntityManager(); //开启事务 entityManager.getTransaction().begin(); //修改 entityManager.merge(t); //提交事务 entityManager.getTransaction().commit(); } catch (Exception e) { //回滚事务 entityManager.getTransaction().rollback(); e.printStackTrace(); } finally { //关闭 entityManager.close(); } } //删除方法 @Override public void delete(Serializable id) { EntityManager entityManager = null; try { entityManager = Jpautil.getEntityManager(); //开启事务 entityManager.getTransaction().begin(); //先查询 T t = (T)entityManager.find(entityClass, id); if (t != null){ //再删除 entityManager.remove(t); } //提交事务 entityManager.getTransaction().commit(); } catch (Exception e) { //回滚事务 entityManager.getTransaction().rollback(); e.printStackTrace(); } finally { //关闭 entityManager.close(); } } //查询一个数据 @Override public T queryOne(Serializable id) { EntityManager entityManager = null; try { entityManager = Jpautil.getEntityManager(); //查询方法 return (T)entityManager.find(entityClass, id); } catch (Exception e) { e.printStackTrace(); } finally { //关闭 entityManager.close(); } return null; } @Override public List queryAll() { EntityManager entityManager = null; try { entityManager = Jpautil.getEntityManager(); //查询所有方法 return entityManager.createQuery("from "+entityClass.getName()).getResultList(); } catch (Exception e) { e.printStackTrace(); } finally { //关闭 entityManager.close(); } return null; }}
写两个子类分别去实现他们自己的接口,同时去继承共用的实现类BaseDaoImpl,那么就能完成覆写自己接口的方法
public class ProductDaoImpl extends BaseDaoImplimplements IProductDao { //创建一个构造方法,将自己的实体类传给父类 public ProductDaoImpl() { super(Product.class); }}public class ProductDirDaoImpl extends BaseDaoImpl implements IProductDirDao { public ProductDirDaoImpl() { super(ProductDir.class); }}
到这里我们简单的多对一CRUD就完成了,同时提取简练了代码,这里我只是简单示范了两个类实现多对一,在面对更多类时,我们只需要去实现公共接口,同时继承公共实现类即可 附上简单的抽取代码思路: 简单的测试一下
private IProductDirDao productDirDao = new ProductDirDaoImpl(); private IProductDao productDao = new ProductDaoImpl(); @Test public void saveTest() { //产品类型 ProductDir productDir = new ProductDir(); productDir.setName("白色系列"); //产品1 Product product1 = new Product(); product1.setName("罗技530"); product1.setDir(productDir); //产品2 Product product2 = new Product(); product2.setName("罗技820"); product2.setDir(productDir); //注意这里要先保存一方,再保存多方 productDirDao.save(productDir); productDao.save(product1); productDao.save(product2); }