liferay数据类型持久化

来源:互联网 发布:官方淘宝波司登羽绒服 编辑:程序博客网 时间:2024/05/21 16:54

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

我开始只想通过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.java的749行

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.java的3026行

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.java的63行

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里找JSP(list-users.jsp),里面有一些相关的用户管理的方法(User[] users = (User[])CompanyLocalManagerUtil.getUsers(company.getCompanyId()).toArray(new User[0]);),从中找到一个得到所有User的方法,也让我联想的去找一些相关的类,后来我就找到UserManagerUtil.java。这个过程是猜测到证实的过程,当你的猜测得到证实的时候,当你发现那个经过多层包装的你熟悉的接口方法的时候,那种感觉是快乐的,满足的。