首先配置好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; }
首先我们来抽取一个获取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); }