⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 详细分析一.txt

📁 开源论坛实现
💻 TXT
📖 第 1 页 / 共 5 页
字号:
postMainNum=1
allUserNum=2
appearTime=963209825828
postNum=1
lastRegUser=sgwood

)下面有其get/set方法,子类可以继承哦!当然,还有一个子类需实现的方法:
 public abstract void load();
  public abstract void saveOnline(long nowonlinenum);//在线数
  public abstract void saveAllUserNum(long allusernum, String lastreguser);//所有用户数和最后注册用户名
  public abstract void savePostNum(long main, long all); //存入主题贴和总数
接着我们看下SysStatServiceImp.java文件好了:它加入了logger和UserConfig对象先,看下面的load方法:

	public void load() {
		Properties prop = new Properties();
		File f = new File(this.getUserConfig().getSafePath() + "sysstat.properties");  //getSafePath()当然会暴露出来!
		if (f.exists()) {
			try {
				FileInputStream fis = new FileInputStream(f);
				prop.load(fis);
/**只需传递这个文件的 InputStream 给 load() 方法,就会将每一个键-值对添加到 Properties 实例中。然后用 list() 列出所有属性或者用 getProperty() 获取单独的属性。 
 list() 方法的输出中键-值对的顺序与它们在输入文件中的顺序不一样。 Properties 类在一个散列表(hashtable,事实上是一个 Hashtable 子类)中储存一组键-值对,所以不能保证顺序。
*/
				this.setOnlineNum(Long.parseLong(prop.getProperty("onlineNum", "0").trim()));//继承过来的!!!
				this.setAppearTime(Long.parseLong(prop.getProperty("appearTime", "0").trim()));
				this.setAllUserNum(Long.parseLong(prop.getProperty("allUserNum", "0").trim()));
				this.setLastRegUser(prop.getProperty("lastRegUser", ""));
				this.setPostMainNum(Long.parseLong(prop.getProperty("postMainNum", "0").trim()));
				this.setPostNum(Long.parseLong(prop.getProperty("postNum", "0").trim()));
				this.setAppearTimeStr(Util.formatDateTime(new Date(this.getAppearTime())));//写时间用
				fis.close();
			} catch (NumberFormatException ex) {
				logger.error(ex);
			} catch (FileNotFoundException ex) {
				logger.error(ex);
			} catch (IOException ex) {
				logger.error(ex);
			}
		} else {
			save(); //文件不存在时!内部private方法哦
		}
	}

	private void save() {
		String path = this.getUserConfig().getSafePath() + "sysstat.properties";
		Properties prop = new Properties();
		prop.setProperty("onlineNum", String.valueOf(this.getOnlineNum()));
		prop.setProperty("appearTime", String.valueOf(this.getAppearTime()));
		prop.setProperty("allUserNum", String.valueOf(this.getAllUserNum()));
		prop.setProperty("lastRegUser", this.getLastRegUser());
		prop.setProperty("postNum", String.valueOf(this.getPostNum()));
		prop.setProperty("postMainNum", String.valueOf(this.getPostMainNum()));
		try {
			FileOutputStream fos = new FileOutputStream(path);//写入新文件中
			prop.store(fos, "sysstat.properties");
			fos.close();
		} catch (FileNotFoundException ex) {
			logger.error(ex);
		} catch (IOException ex) {
			logger.error(ex);
		}
	}

我们看下对抽象类的实现吧:(先load一下资源文件,再set相关的key值,最后用私有的save一下)
	public void saveAllUserNum(long allusernum, String lastreguser) {
		this.load();
		this.setAllUserNum(allusernum);
		this.setLastRegUser(lastreguser);
		this.save();
	}
	public void saveOnline(long nowonlinenum) {
		this.load();
		if (nowonlinenum > this.getOnlineNum()) {  //好象不太对,不然只有多没有少!
			long atime = System.currentTimeMillis();
			this.setOnlineNum(nowonlinenum);
			this.setAppearTime(atime);
			this.setAppearTimeStr(Util.formatDateTime(new Date(atime)));
			this.save();
		}
	}
	public void savePostNum(long main, long all) {
		this.load();
		this.setPostMainNum(main);
		this.setPostNum(all);
		this.save();
	}
OK!终于可以回到BoardServiceCachImp实现类中了,绕了好大一个弯!由于还有许多东西没用过,只能推测一下其用法了哦~~~还是先看几个,createBoard(Board board)先:
	@SuppressWarnings("unchecked")
	public Board createBoard(Board board) throws BbscsException {
		try {
			Board pboard = this.getBoardDAO().getBoardByID(board.getParentID()); // 取得父级版区
			if (pboard != null) { // 父级版区存在
				List pboards = new ArrayList();
				pboards.addAll(pboard.getParentIDs());//父的祖先
				pboards.add(pboard.getId());//父
/** addAll(Collection c) 
add(int index,Elelemt e) 
注意parentIDs和childIDs均为List是由自定义userType的
public Class returnedClass() {
		return List.class;
	}
决定返回是List类型的!
*/
				board.setParentIDs(pboards); // 设置父级版区列表字段
				board.setLevel(pboard.getLevel() + 1); // 设置级别,在父级别上+1
			}
			board = this.getBoardDAO().saveBoard(board);//这里的其它参数由添加时决定,不需要改变,或由其它因素相关!由DAO完成实质的工作

			if (pboard != null) {
				List pcboards = this.getBoardDAO().findBoardsByParentID(board.getParentID(), 1, -1,
						Constant.FIND_BOARDS_BY_ORDER); 
/** 取得父级半区的所有子版区列表pcboard,1是useStat,-1是hidden,FIND_BOARD_BY_ORDER=0另外有,
	public static final int FIND_BOARDS_BY_MAINPOSTNUM = 1;
	public static final int FIND_BOARDS_BY_POSTNUM = 2;
/*

				List cids = this.getBoardIDs(pcboards);//得到子版ID的List
/**
	public List getBoardIDs(List boards) {
		List<Long> l = new ArrayList<Long>();
		for (int i = 0; i < boards.size(); i++) {
			Board b = (Board) boards.get(i);
			l.add(b.getId());
		}
		return l;
	}

*/
				pboard.setChildIDs(cids); // 设置父级版区的所有子版区列表字段
				this.getBoardDAO().saveBoard(pboard);//更新父信息
				this.getBoardCache().remove(pboard.getId());
/**从Board Cache中清除, 我们看下BoardCache的bean定义:
<bean id="boardCache"
		class="com.laoer.bbscs.service.imp.OsCacheImp"> 仍然是这个,以前讲过!
		<constructor-arg>
			<value>${cache.config}</value> cache.config=oscache.properties
		</constructor-arg>
	</bean>
	public void remove(Object key) {
		logger.debug("Remove from cache [Key:" + key + "]");
		this.admin.flushEntry(key.toString());
	}
从oscache.properties配置处的Cache内容中去掉key=pboard.getID()的对象,让OSCache自动缓存内容吧!
*/
			}

			this.clearBoradListSysListCache(board.getParentID());
/**它其实是一私有方法哦!需要注意的是实质用了SysListOjbCache,它其中的对象标识竟是[][][][][],5555,可能有些对象后三者可不用:
	private void clearBoradListSysListCache(long pid) {
		String[] useStats = { "-1", "0", "1" };
		String[] hiddens = { "-1", "0", "1" };
		String[] orderTypes = { "0", "1", "2" };
		for (int i = 0; i < useStats.length; i++) {
			for (int j = 0; j < hiddens.length; j++) {
				for (int x = 0; x < orderTypes.length; x++) {
					this.getSysListObjCache().remove(
							"[B][" + pid + "][" + useStats[i] + "][" + hiddens[j] + "][" + orderTypes[x] + "]");
				}
			}
		}
	}
*/

			// 为版区增加用户组版区权限
			List gl = this.getUserGroupDAO().findUserGroupsAll(); 
/**取得用户组列表
public List findUserGroupsAll() {
		return this.getHibernateTemplate().find(LOADS_ALL);
	}
private static final String LOADS_ALL = "from UserGroup order by id";
原始数据为6个记录的表(见数据库),id1---6,以GroupName区分之,TypeID表示代表类型,默认是系统类型的,不能删除,用户自己建的就是另外一个类型了。 
*/
			BoardPermission bp;

			for (int i = 0; i < gl.size(); i++) {
				UserGroup ug = (UserGroup) gl.get(i);
				bp = new BoardPermission();
				bp.setBoardID(board.getId().longValue());//冗余字段
				bp.setGroupID(ug.getId().intValue());//冗余字段

				switch (ug.getId().intValue()) {
				case 1:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_1);
/**<property column="Permissions" name="permissions" type="com.laoer.bbscs.ext.hibernate.SplitList"/>
					break;
				case 2:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_2);
					break;
				case 3:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_3);
					break;
				case 4:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_4);
					break;
				case 5:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_5);
					break;
				case 6:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_6);
					break;
				default:
					bp.setPermissions(Constant.BOARD_PERMISSION_GROUP_LIST_1);
				}
				this.getBoardPermissionDAO().saveBoardPermission(bp);
/**而在Constant.java中有段static段:
	for (int i = 0; i < BOARD_PERMISSION_GROUP_1.length; i++) {
			BOARD_PERMISSION_GROUP_LIST_1.add(new Long(BOARD_PERMISSION_GROUP_1[i]));
		}

		for (int i = 0; i < BOARD_PERMISSION_GROUP_2.length; i++) {
			BOARD_PERMISSION_GROUP_LIST_2.add(new Long(BOARD_PERMISSION_GROUP_2[i]));
		}

		for (int i = 0; i < BOARD_PERMISSION_GROUP_3.length; i++) {
			BOARD_PERMISSION_GROUP_LIST_3.add(new Long(BOARD_PERMISSION_GROUP_3[i]));
		}

		for (int i = 0; i < BOARD_PERMISSION_GROUP_4.length; i++) {
			BOARD_PERMISSION_GROUP_LIST_4.add(new Long(BOARD_PERMISSION_GROUP_4[i]));
		}

		for (int i = 0; i < BOARD_PERMISSION_GROUP_5.length; i++) {
			BOARD_PERMISSION_GROUP_LIST_5.add(new Long(BOARD_PERMISSION_GROUP_5[i]));
		}
*/
			}

			return board;

		} catch (Exception e) {
			logger.error(e);
			throw new BbscsException(e);
		}

	}
从创建中可以知道,它调用了两个cache(sysListObjCache和boardCache,对父级和本级的相关项进行更新(或产生),再保存.还有就是对此分版区(论坛)的用户权限的写入.总的来说,原则上,要数据服务(保存和查找)从DAO层来,要Cache从服务层来,要常用服务也从服务层来(因为它不参与DAO工作)

接下来,我们继续看findBoardAllTree:
	@SuppressWarnings("unchecked")//类型安全问题
	public List findBoardsAllTree(long pid, List topList, int useStat, int hidden, int orderType) {
		List l = this.getBoardDAO().findBoardsByParentID(pid, useStat, hidden, orderType);//这个pid指的是当前论坛,与前面的pid不一样哦

		for (int i = 0; i < l.size(); i++) {
			Board b = (Board) l.get(i);
			topList.add(b);
			this.findBoardsAllTree(b.getId().longValue(), topList, useStat, hidden, orderType);//由于topList是一个引用类型,可递归得到All子论坛及子论坛的子论坛...
		}
		return topList;
	}
而这个服务类的findBoardByParentID(非DAO)它首先是查询SysListObjCache里面有没有,若没有的话再由DAO从数据库中找,且放入到SysListObjCache中,用了add方法,需注意的是其命名有点怪哦!

	public List findBoardsByParentID(long pid, int useStat, int hidden, int orderType) {
		List l = (List) this.getSysListObjCache().get(
				"[B][" + pid + "][" + useStat + "][" + hidden + "][" + orderType + "]");
		if (l == null) {
			// l = this.getBoardDAO().findBoardsByParentID(pid, useStat, hidden,
			// orderType);
			l = this.getBoardDAO().findBoardIdsByParentID(pid, useStat, hidden, orderType);
			this.getSysListObjCache().add("[B][" + pid + "][" + useStat + "][" + hidden + "][" + orderType + "]", l);
		}
		List<Board> bl = new ArrayList<Board>();
		if (l != null && !l.isEmpty()) {
			for (int i = 0; i < l.size(); i++) {
				// Board b = this.getBoardByID(((Long)l.get(i)).longValue());
				Board b = this.getBoardByID((Long) l.get(i));
				if (b != null) {
					bl.add(b);
				}
			}
		}
由于Cache中不一定是Borad对象了,由于add进的是list,便由List<Board>类型的bl重新加载一次为Board的List.findBoardInIDs根据IDs一个取一个,边放入到l中!
	public List findBoardsInIDs(List ids) {
		List<Board> l = new ArrayList<Board>();
		if (ids != null && !ids.isEmpty()) {
			for (int i = 0; i < ids.size(); i++) {
				// Board b = this.getBoardByID(((Long) ids.get(i)).longValue());
				Board b = this.getBoardByID((Long) ids.get(i));
				if (b != null) {
					l.add(b);
				}
			}
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -