以前学习java的时候,一开始就学习了hibernate,那时候总觉得ssh非常高大上,所以就急忙看了下相关视频。不过因为实际需要不高,所以后来一直没有使用上hibernate组件。现在一年过去了,也疯狂学习了java一段时间了,做过几个不大的项目,但是总算对java有些了解。现在参加了工作,公司使用的就是ssh,所以这两天又重新开始捣鼓hibernate。这次学习直接使用editplus,直接开发。看了官网的demo,发现英语也没有想象中那么困难。哈哈,把自己的学习记录下来吧。这里主要记录三个方面:
1.如何搭建hibernate
2.几种常用映射关系(one - to -one,one - to - many, many - to - one, many - to - many)
搭建hibernate(直接使用文本编辑器)
第一步:这个过程也不复杂,主要是下载到hibernate相关jar包,然后将必要的jar引入到classpath中,具体什么是classpath,大家可以百度下。如果不导入到classpath中,会出现不能找到类的异常。为什么会出现这种情况呢?大家可以百度下,java 的类加载过程。
第二步:编写hibernate.cfg.xml文件。这个大家不用手写,直接去hibernate文章中copy一个即可。下面给出我的代码
<?xml version='1.0' encoding='utf-8' ?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_demo</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <!--if the value='create, means create table, every time open hibernate, if will drop the old scheme'--> <property name="hbm2ddl.auto">update</property> <mapping resource="User.xml"/> <mapping resource="Address.xml"/> </session-factory> </hibernate-configuration>
第三步:开始制作一个工具类,用来初始化hibernate组件。由于难度不高,直接给出代码,这些在文章中都已经有了,大家可以自己下载document看看。下面是代码:
import java.io.*; import org.hibernate.*; import org.hibernate.cfg.*; /** * that is a hibernate config util * */ public class HibernateConfigurationUtil{ private static HibernateConfigurationUtil singleton = new HibernateConfigurationUtil("hibernate.cfg.xml"); private static SessionFactory factory; /** * singleton pattern * */ private HibernateConfigurationUtil(String configXml){ init(configXml); } public void init(String configXml){ Configuration cfg = new Configuration().configure(new File("hibernate.cfg.xml")); factory = cfg.buildSessionFactory(); // build the session factory } public static SessionFactory getSessionFactory(){ if(factory == null) return null; return factory; } /** * open a new Session * * */ public static Session openSession(){ Session session = factory.openSession(); return session; } }
注意下,这个类使用单例设计模式,因为hibernate组建在启动Configuration时,是非常耗时的,而且这个对象在启动之后不能改变,所以每个工程中,启动一次即可。
第三步:编写BaseHibernateDao,这个类注意是封装了save, delete, update, load这四个方法。
import java.io.*; import org.hibernate.*; import org.hibernate.cfg.*; /** * that is the base hibernate dao, * it define a series of method to access database * if you want to 'delete, update a object, the object must exists in hibernate memery' * * @author luohong * @date 2014-08-07 * */ public class BaseHibernateDao{ public BaseHibernateDao(){ } /** * try to save a object * */ public void save(Object object){ Session session = HibernateConfigurationUtil.openSession(); // open transaction Transaction transaction = session.beginTransaction(); session.save(object); // commint transaction transaction.commit(); } /** * try to update a object * */ public void update(Object object){ Session session = HibernateConfigurationUtil.openSession(); // open transaction Transaction transaction = session.beginTransaction(); session.update(object); // commint transaction transaction.commit(); } /** * try to delete a object * */ public void delete(Object object){ Session session = HibernateConfigurationUtil.openSession(); // open transaction Transaction transaction = session.beginTransaction(); session.delete(object); // commint transaction transaction.commit(); } /** * try to load a object from database by className and id * */ public Object load(Class<?> className, Serializable id){ Session session = HibernateConfigurationUtil.openSession(); // there is no need for transaction return session.load(className, id); } }
注意:在save, update, delete方法中,只用了Transaction,要开启事务,否则数据库找不到相关记录。
第四步:到了这里之后,就非常简单了,只需要针对具体的类,扩展BaseHibernateDao即可。下面给出一个一对多的例子。模拟情景:用户(User)拥有多个住址(Address)首先给出两个类:
import java.util.*; public class User{ private int id; private String password; private String name; private Set<Address> addressSet; public void setAddressSet(Set<Address> addressSet){ this.addressSet = addressSet; } public Set<Address> getAddressSet(){ return addressSet; } public void setName(String name){ this.name = name; } public String getName(){ return name; } public void setId(int id){ this.id = id; } public int getId(){ return id; } public void setPassword(String password){ this.password = password; } public String getPassword(){ return password; } public String toString(){ return "id = " + id + ", name = " + name + ", password = " + password + ", addressSet = " + addressSet; } }
/** * that is the user address * a user have many address, but a adress belong to a user * It is the classical 1 * n relationship * @author luohong * @date 2014-08-07 * */ public class Address { //=====================properties============================= private int id; //private User belongTo; private String code; private String city; private String street; private String homeNumber; //===================setter and getter======================== public void setId(int id){ this.id = id; } public int getId(){ return id; } /* public void setBelongTo(User user){ this.belongTo = belongTo; } public User getBelongTo(){ return belongTo; } */ public void setCode(String code){ this.code = code; } public String getCode(){ return code; } public void setCity(String city){ this.city = city; } public String getCity(){ return city; } public void setHomeNumber(String homeNumber){ this.homeNumber = homeNumber; } public String getHomeNumber(){ return homeNumber; } public String getStreet(){ return street; } public void setStreet(String street){ this.street = street; } //========================toString================================ public String toString(){ return "id = " + id + ", city = " + city + ", street = " + street + ", homeNumber = " + homeNumber + ", code = " + code;// + ", belongTo = " + belongTo; } }
给出相关的User.xml, Address.xml;这个例子使用的是单向一对多。
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="User" table="user"> <id name="id"> <generator class="increment"/> </id> <property name="password"/> <property name="name"/> <!--one to many--> <set name="addressSet" cascade="all"> <!--define the foreight column name--> <key column="user_id"/> <!--define the foreight table name--> <one-to-many class="Address"/> </set> </class> </hibernate-mapping>
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="Address" table="address"> <id name="id"> <generator class="increment"/> </id> <property name="code"/> <property name="city"/> <property name="street"/> <property name="homeNumber"/> </class> </hibernate-mapping>
然后编写一个UserDao,继承BaseHibernateDao,也很简单,哈哈,一看就懂,这就是hibernate的厉害之处。
import java.util.*; import org.hibernate.*; /** * user dao extends BaseHibernateDao * you can add new functions to the custom dao * * * @author luohong * @date 2014-08-07 * */ public class UserDao extends BaseHibernateDao{ /** * delete a user by userId * * */ public void deleteById(String id){ if (id == null) return; // do nothing String hql = "delete User where id=?"; // 1 open session Session session = HibernateConfigurationUtil.openSession(); // 2 create a query Query query = session.createQuery(hql); // 3 set the parameter to query query.setString(1, id); // 4 execute query query.executeUpdate(); } /** * find all user from database * */ public List<User> findAllUsers(){ String hql = "from User"; Session session = HibernateConfigurationUtil.openSession(); Query query = session.createQuery(hql); List userList = query.list(); return (List<User>)userList; } }
剩下的就是测试啦,come on...
import java.io.*; import java.util.*; /** * hibernate orm 框架demo * @author luohong * @date 2014-08-06 * * */ public class HibernateDemo{ public static void main(String[] args) throws Exception{ UserDao userDao = new UserDao(); User user = new User(); user.setName("luohong"); user.setPassword("luohong"); Set<Address> addressSet = new HashSet<Address>(); for(int i=0; i<3; i++){ Address address = new Address(); address.setCode("111"); address.setCity("hongkang"); address.setStreet("universal street"); address.setHomeNumber("a-2846"); //address.setBelongTo(user); addressSet.add(address); } user.setAddressSet(addressSet); userDao.save(user); } }