打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
初探Liferay Enterpriese Portal的数据类型持久化

前言:

最近在忙的一个项目是建立在Liferay Enterprise Portal上的,设计的几张数据表要与已有的Portal数据库中的User_表有级联关系。之前从Liferay的官方网站上了解到LiferayPortal持久化都是通过Hibernate来实现,故对其实现的方法产生了小小的兴趣(因为我的数据表也打算通过HibernateO/R映射来实现,代码中难免要使用Portal的类com.liferay.portal.model.User)。

正文:

其实了解各种实现的方法,最好的莫过于读源码。(只要你有这个耐心)

我开始只想通过userId得到User对象,关于User对象的各种相关的类都在包com.liferay.portal.ejb里,你可以看到User开头的类有一堆,呵呵,其实我们这里只要涉及几个重要的类:

UserHBM.java 这个是User类的一个翻版,里面的信息和User里的信息基本一致(没仔细看),Portal也是通过这个类来映射数据库的User_表的。

UserPool.java 这个是一个与Cache相关的类,可不关心,并不影响理解。

UserManager.java 定义了与User相关的一组接口,对一些重要属性如Group,Role等的添加删除等。

UserManagerImpl.java 实现了UserManager接口,并继承了PrincipalBean.java

UserUtil.java 个人觉得有点象实体bean的变体,里面有create,remove,update等方法,还有一些查找方法。

UserPersistence.java 这个里面是具体数据库的实现方法,UserUtil都是调用这个类的方法。

让我们先看看UserManagerImpl.java中关于得到User的代码,源码第400

public User getUserById(String userId)
  throws PortalException, SystemException {

  userId = userId.trim().toLowerCase();

  User user = UserUtil.findByPrimaryKey(userId);

  if (getUserId().equals(userId) ||
   hasAdministrator(user.getCompanyId())) {

   return user;
  }
  else {
   return (User)user.getProtected();
  }
 }

然后再看UserUtil.java749

protected static com.liferay.portal.model.User findByPrimaryKey(
  java.lang.String userId)
  throws com.liferay.portal.NoSuchUserException,
   com.liferay.portal.SystemException {
  
UserPersistence persistence = (UserPersistence)InstancePool.get(PERSISTENCE);

  return persistence.findByPrimaryKey(userId);
 }

再找UserPersistence.java3026

protected com.liferay.portal.model.User findByPrimaryKey(String userId)
  throws NoSuchUserException, SystemException {
  com.liferay.portal.model.User user = UserPool.get(userId);
  Session session = null;

  try {
   if (user == null) {
    session = openSession();

    UserHBM userHBM = (UserHBM)session.load(UserHBM.class, userId);
    user = UserHBMUtil.model(userHBM);
   }

   return user;
  }
  catch (HibernateException he) {
   if (he instanceof ObjectNotFoundException) {
    throw new NoSuchUserException(userId.toString());
   }
   else {
    throw new SystemException(he);
   }
  }
  finally {
   HibernateUtil.closeSession(session);
  }
 }

看完上面这些代码是不是就明白Portal是怎么通过userId得到User对象的?上面一段代码中红色的那句用过hibernate的人都会很熟悉,通过主键得到对象。

我们再深入一下,看一下BasePersistence.java,这个是UserPersistence.java的父类,上面代码中openSession()在这个类里定义。

public class BasePersistence {

 protected Session openSession() throws HibernateException {
  return HibernateUtil.openSession(getHibernateConfigurationClassName());
 }

 protected Dialect getDialect() {
  return HibernateUtil.getDialect(getHibernateConfigurationClassName());
 }

 protected String getHibernateConfigurationClassName() {
  return HibernateConfiguration.class.getName();
 }

}

再看com.liferay.portal.util.HibernateUtil.java63

public static Session openSession(String className)
  throws HibernateException {

  SessionConfiguration config =
   _getSessionConfigurationInstance(className);

  return config.openSession();
 }


com.liferay.util.dao.hibernate.SessionConfiguration.java是一个抽象类,让我直接看其子类com.liferay.portal.util.HibernateConfiguration.java

public class HibernateConfiguration extends SessionConfiguration {

 public void init() {
  try {
   ClassLoader classLoader = getClass().getClassLoader();

   Configuration cfg = new Configuration();

   String[] configs = StringUtil.split(
    SystemProperties.get("hibernate.configs"));

   for (int i = 0; i < configs.length; i++) {
    try {
     InputStream is =
      classLoader.getResourceAsStream(configs[i]);

     if (is != null) {
      cfg = cfg.addInputStream(is);

      is.close();
     }
    }
    catch (Exception e) {
     e.printStackTrace();
    }
   }

   cfg.setProperties(SystemProperties.getProperties());

   setSessionFactory(cfg.buildSessionFactory());
  }
  catch (Exception e) {
   e.printStackTrace();
  }
 }

}


上面代码中的红色部分是从系统的properties文件中读取一些值,实际上是调用portal-ejb/system.properties文件,从这个文件的第94行就可以发现一些Hibernate用来做O/R mapping的文件。代码中通过InputStream方式把这些mapping files加到Configuration中去。

大家可以去看一下这些mapping files是不是我们所熟悉的****.hbm.xml的格式?

后记:

读了一早上的源码,写了一个小时的blog,无非是想切实的解决一个问题。通过读源码可以了解一些机制,也可以了解一些设计思想,对于每一个学习者都是有益的。从开始不知道用什么方法好,就去找admin portlet里找JSPlist-users.jsp),里面有一些相关的用户管理的方法(User[] users = (User[])CompanyLocalManagerUtil.getUsers(company.getCompanyId()).toArray(new User[0]);),从中找到一个得到所有User的方法,也让我联想的去找一些相关的类,后来我就找到UserManagerUtil.java。这个过程是猜测到证实的过程,当你的猜测得到证实的时候,当你发现那个经过多层包装的你熟悉的接口方法的时候,那种感觉是快乐的,满足的。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Liferay系列文章(四)Portal产品介绍--开放源码Portal产品
搭建开发环境(初学liferay必看)
《如何把Hibernate2.1升级到Hibernate3.0?》-你好Blog
Hibernate入门之对象状态与识别
Spring中的Hibernate Session
第一章:struts2框架与hibernate框架
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服