java中基于Jpa的单向多对一的CRUD功能实现以及代码的抽取简化

首先配置好persistence.xml
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL">
        <properties>
            <!-- 必须配置4个连接数据库属性 -->
            <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="******" />

            <!-- 必须配置1个方言属性 -->
            <!-- 实现跨数据库关键类 :查询MySQLDialect的getLimitString方法 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />

            <!-- 可选配置 -->
            <!-- 是否自动生成表 自动创建表-->
            <property name="hibernate.hbm2ddl.auto" value="create" />
            <!-- 是否显示sql -->
            <property name="hibernate.show_sql" value="true" />
            <!-- 格式化sql -->
            <!--<property name="hibernate.format_sql" value="true" />-->
        </properties>
    </persistence-unit>
我们再来简单创建两个类,完成多对一
/**
 *多方
 * 产品类
 *
 *
 */
//交给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<T> {
    //保存
    void save(T t);
   //修改
    void update(T t);
   //删除
    void delete(Serializable id);
   //查询一条数据
    T queryOne(Serializable id);
   //查询所有数据
    List<T> queryAll();

}
 我们让两个类的接口都去继承它
public interface IProductDao extends IBaseDao<Product> {
   //这里现在写了其实没有实现任何功能,当时当我们后续这个类有自己独有的方法的时候,就可以在这里添加自己的方法
}


public  interface IProductDirDao extends IBaseDao<ProductDir> {

}
再写一个共有的实现类去实现IBaseDao公共接口
public class BaseDaoImpl<T> implements IBaseDao<T> {

    //在查询中要使用到的实体类
    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<T> 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 BaseDaoImpl<Product> implements IProductDao {
   //创建一个构造方法,将自己的实体类传给父类
    public ProductDaoImpl() {
        super(Product.class);
    }
}


public class ProductDirDaoImpl extends BaseDaoImpl<ProductDir> 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);
    }
 
 
 
扫描二维码关注公众号,回复: 5436737 查看本文章
 

猜你喜欢

转载自www.cnblogs.com/bty-per/p/10482337.html