<?xml version="1.0" encoding="GBK"?> <project name="hibernate" basedir="." default=""> <property name="src" value="src"/> <property name="dest" value="classes"/> <path id="classpath"> <fileset dir="../../lib"> <include name="**/*.jar"/> </fileset> <pathelement path="${dest}"/> </path> <target name="compile" description="Compile all source code"> <delete dir="${dest}"/> <mkdir dir="${dest}"/> <copy todir="${dest}"> <fileset dir="${src}"> <exclude name="**/*.java"/> </fileset> </copy> <javac destdir="${dest}" debug="true" includeantruntime="yes" deprecation="false" optimize="false" failonerror="true"> <src path="${src}"/> <classpath refid="classpath"/> <compilerarg value="-Xlint:deprecation"/> </javac> </target> <target name="run" description="Run the main class" depends="compile"> <java classname="lee.ProductManager" fork="yes" failonerror="true"> <classpath refid="classpath"/> </java> </target> </project>
drop database if exists hibernate; create database hibernate; use hibernate; CREATE TABLE category_inf ( category_id bigint(20) NOT NULL auto_increment, name varchar(255) default NULL, eff_start_date datetime default NULL, eff_end_date datetime default NULL, PRIMARY KEY (category_id) ); INSERT INTO category_inf VALUES (1,'it产品', ADDDATE(now() , - 200) , ADDDATE(now() , 20)), (2,'工业产品', ADDDATE(now() , - 180) , ADDDATE(now() , 34)), (3,'输出设备', ADDDATE(now() , - 223) , ADDDATE(now() , 42)); CREATE TABLE product_inf ( product_id bigint(20) NOT NULL auto_increment, product_name varchar(255) default NULL, stock_number int(11) default NULL, eff_start_date datetime default NULL, eff_end_date datetime default NULL, PRIMARY KEY (product_id) ); INSERT INTO product_inf VALUES (1,'显示器',20040404 , ADDDATE(now() , - 90) , ADDDATE(now() , 20)), (2,'键盘',20040219 , ADDDATE(now() , - 78) , ADDDATE(now() , 19)), (3,'机箱',20040915 , ADDDATE(now() , - 56) , ADDDATE(now() , 15)); CREATE TABLE product_category ( category_id bigint(20) NOT NULL, product_id bigint(20) NOT NULL, PRIMARY KEY (product_id,category_id), KEY FKA0303E4E64F7AABC (category_id), KEY FKA0303E4E142E1558 (product_id), FOREIGN KEY (product_id) REFERENCES product_inf(product_id), FOREIGN KEY (category_id) REFERENCES category_inf (category_id) ); INSERT INTO product_category VALUES (1,1), (1,3), (2,1), (2,2), (3,1), (3,2), (3,3);
<?xml version="1.0" encoding="GBK"?> <!-- 指定Hibernate配置文件的DTD信息 --> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <!-- hibernate-configuration是配置文件的根元素 --> <hibernate-configuration> <session-factory> <!-- 指定连接数据库所用的驱动 --> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- 指定连接数据库的url,其中hibernate是本应用连接的数据库名 --> <property name="connection.url">jdbc:mysql://localhost/hibernate</property> <!-- 指定连接数据库的用户名 --> <property name="connection.username">root</property> <!-- 指定连接数据库的密码 --> <property name="connection.password">32147</property> <!-- 指定连接池里最大连接数 --> <property name="hibernate.c3p0.max_size">20</property> <!-- 指定连接池里最小连接数 --> <property name="hibernate.c3p0.min_size">1</property> <!-- 指定连接池里连接的超时时长 --> <property name="hibernate.c3p0.timeout">5000</property> <!-- 指定连接池里最大缓存多少个Statement对象 --> <property name="hibernate.c3p0.max_statements">100</property> <property name="hibernate.c3p0.idle_test_period">3000</property> <property name="hibernate.c3p0.acquire_increment">2</property> <property name="hibernate.c3p0.validate">true</property> <!-- 指定数据库方言 --> <property name="dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <!-- 根据需要自动创建数据库 --> <property name="hbm2ddl.auto">update</property> <!-- 显示Hibernate持久化操作所生成的SQL --> <property name="show_sql">true</property> <!-- 将SQL脚本进行格式化后再输出 --> <property name="hibernate.format_sql">true</property> <!-- 罗列所有持久化类的类名 --> <mapping class="org.crazyit.app.domain.Category"/> <mapping class="org.crazyit.app.domain.Product"/> </session-factory> </hibernate-configuration>
package lee; import org.hibernate.*; import org.hibernate.cfg.*; import org.hibernate.service.*; import org.hibernate.boot.registry.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class HibernateUtil { public static final SessionFactory sessionFactory; static { try { // 使用默认的hibernate.cfg.xml配置文件创建Configuration实例 Configuration cfg = new Configuration() .configure(); // 以Configuration实例来创建SessionFactory实例 ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() .applySettings(cfg.getProperties()).build(); sessionFactory = cfg.buildSessionFactory(serviceRegistry); } catch (Throwable ex) { System.err.println("Initial SessionFactory creation failed." + ex); throw new ExceptionInInitializerError(ex); } } // ThreadLocal可以隔离多个线程的数据共享,因此不再需要对线程同步 public static final ThreadLocal<Session> session = new ThreadLocal<Session>(); public static Session currentSession() throws HibernateException { Session s = session.get(); // 如果该线程还没有Session,则创建一个新的Session if (s == null) { s = sessionFactory.openSession(); // 将获得的Session变量存储在ThreadLocal变量session里 session.set(s); } return s; } public static void closeSession() throws HibernateException { Session s = session.get(); if (s != null) s.close(); session.set(null); } }
package lee; import org.hibernate.Transaction; import org.hibernate.Session; import java.util.*; import java.text.SimpleDateFormat; import org.crazyit.app.domain.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ public class ProductManager { SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); public static void main(String[] args) throws Exception { ProductManager mgr = new ProductManager(); mgr.test(); HibernateUtil.sessionFactory.close(); } private void test() throws Exception { Session session = HibernateUtil.currentSession(); Transaction tx = session.beginTransaction(); // 启动effectiveDate过滤器,并设置参数 session.enableFilter("effectiveDate") .setParameter("asOfDate", new Date()); // 启动category过滤器,并设置参数 session.enableFilter("category") .setParameter("catId", 2); // 查询所有Product实体,不加任何筛选条件,但effectiveDate过滤器会起作用 List list = session.createQuery("from Product as p").list(); // ① for (Object obj : list) { Product p = (Product)obj; System.out.println(p.getName()); // 获取Product对象关联的Category试题,2个过滤器会起作用。 System.out.println("----" + p.getCategories()); // ② } tx.commit(); HibernateUtil.closeSession(); } }
package org.crazyit.app.domain; import javax.persistence.*; import org.hibernate.annotations.FilterDefs; import org.hibernate.annotations.FilterDef; import org.hibernate.annotations.ParamDef; import org.hibernate.annotations.Filter; import org.hibernate.annotations.Filters; import java.util.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ @FilterDefs({ // 定义名为effectiveDate的过滤器,该过滤器支持1个date类型的参数 @FilterDef(name="effectiveDate" , parameters={@ParamDef(name="asOfDate" , type="date")}), // 定义名为category的过滤器,该过滤器支持1个int类型的参数 @FilterDef(name="category" , parameters={@ParamDef(name="catId" , type="int")}) }) @Entity @Table(name="product_inf") // 使用effectiveDate过滤器对Product实体使用数据过滤 @Filter(name="effectiveDate" , condition=":asOfDate BETWEEN eff_start_date AND eff_end_date") public class Product { @Id @Column(name="product_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; // 定义产品名 @Column(name="product_name") private String name; // 定义股票号属性,该属性可标识该产品 @Column(name="stock_number") private int stockNumber; // 定义生效开始的时间 @Column(name="eff_start_date") private Date effectiveStartDate; // 定义失效时间 @Column(name="eff_end_date") private Date effectiveEndDate; // 定义该产品所属的种类 @ManyToMany(targetEntity=Category.class) @JoinTable(name="product_category" , joinColumns=@JoinColumn(name="product_id") , inverseJoinColumns=@JoinColumn(name="category_id")) // 对该关联实体的抓取使用effectiveDate、category进行数据过滤 @Filters({ @Filter(name="effectiveDate" , condition=":asOfDate BETWEEN eff_start_date and eff_end_date"), @Filter(name="category" , condition="category_id = :catId") }) private Set<Category> categories = new HashSet<>(); // 无参数的构造器 public Product() { } // 初始化全部成员变量的构造器 public Product(String name , int stockNumber , Date effectiveStartDate , Date effectiveEndDate) { this.name = name; this.stockNumber = stockNumber; this.effectiveStartDate = effectiveStartDate; this.effectiveEndDate = effectiveEndDate; } // id的setter和getter方法 public void setId(Integer id) { this.id = id; } public Integer getId() { return this.id; } // name的setter和getter方法 public void setName(String name) { this.name = name; } public String getName() { return this.name; } // stockNumber的setter和getter方法 public void setStockNumber(int stockNumber) { this.stockNumber = stockNumber; } public int getStockNumber() { return this.stockNumber; } // effectiveStartDate的setter和getter方法 public void setEffectiveStartDate(Date effectiveStartDate) { this.effectiveStartDate = effectiveStartDate; } public Date getEffectiveStartDate() { return this.effectiveStartDate; } // effectiveEndDate的setter和getter方法 public void setEffectiveEndDate(Date effectiveEndDate) { this.effectiveEndDate = effectiveEndDate; } public Date getEffectiveEndDate() { return this.effectiveEndDate; } // categories的setter和getter方法 public void setCategories(Set<Category> categories) { this.categories = categories; } public Set<Category> getCategories() { return this.categories; } // 根据stockNumber来重写hashCode()方法 public boolean equals(Object obj) { if (this == obj) { return true; } if (obj != null && obj.getClass() == Product.class) { Product target = (Product)obj; return target.getStockNumber() == stockNumber; } return false; } // 根据stockNumber来重写hashCode()方法 public int hashCode() { return stockNumber; } // 为产品添加一个所属的种类 public void addCategory(Category category) { if ( category == null ) { return; } this.categories.add(category); category.getProducts().add(this); } }
package org.crazyit.app.domain; import javax.persistence.*; import org.hibernate.annotations.Filter; import java.util.*; /** * Description: * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> * <br/>Copyright (C), 2001-2016, Yeeku.H.Lee * <br/>This program is protected by copyright laws. * <br/>Program Name: * <br/>Date: * @author Yeeku.H.Lee kongyeeku@163.com * @version 1.0 */ @Entity @Table(name="category_inf") // 对Category实体使用数据过滤 @Filter(name="effectiveDate" , condition=":asOfDate BETWEEN eff_start_date and eff_end_date") public class Category { @Id @Column(name="category_id") @GeneratedValue(strategy=GenerationType.IDENTITY) private Integer id; private String name; @Column(name="eff_start_date") private Date effectiveStartDate; @Column(name="eff_end_date") private Date effectiveEndDate; @ManyToMany(targetEntity=Product.class, mappedBy="categories") private Set<Product> products = new HashSet<>(); // 无参数的构造器 public Category() { } // 初始化全部成员变量的构造器 public Category(String name , Date effectiveStartDate , Date effectiveEndDate) { this.name = name; this.effectiveStartDate = effectiveStartDate; this.effectiveEndDate = effectiveEndDate; } // id的setter和getter方法 public void setId(Integer id) { this.id = id; } public Integer getId() { return this.id; } // name的setter和getter方法 public void setName(String name) { this.name = name; } public String getName() { return this.name; } // effectiveStartDate的setter和getter方法 public void setEffectiveStartDate(Date effectiveStartDate) { this.effectiveStartDate = effectiveStartDate; } public Date getEffectiveStartDate() { return this.effectiveStartDate; } // effectiveEndDate的setter和getter方法 public void setEffectiveEndDate(Date effectiveEndDate) { this.effectiveEndDate = effectiveEndDate; } public Date getEffectiveEndDate() { return this.effectiveEndDate; } // products的setter和getter方法 public void setProducts(Set<Product> products) { this.products = products; } public Set<Product> getProducts() { return this.products; } // 判断两个种类是否相等 public boolean equals(Object obj) { if (this == obj) { return true; } if(obj.getClass() == Category.class) { Category target = (Category)obj; return name.equals(target.getName()) && effectiveStartDate.equals(target.getEffectiveStartDate()) && effectiveEndDate.equals(target.getEffectiveEndDate()); } return false; } // 生成hashCode的方式以名字的hashCode加上 // 生效开始日期hashCode,再加生效结束日期的hashCode public int hashCode() { int result; result = name.hashCode(); result = 29 * result + (effectiveStartDate != null ? effectiveStartDate.hashCode() : 0); result = 29 * result + (effectiveEndDate != null ? effectiveEndDate.hashCode() : 0); return result; } }