目前单位在给一家公司做一套业务系统,主要涉及工作流(用JPDL框架做的)。我所在的小组做的是物流,属于业务系统中的一个子模块,用的框架是Spring、SpringMVC、Hibernate,使用Eclipse开发,并且配置是基于注解的,表是由Hibernate根据实体类自动建的。
在Controller中的方法往往都有一个参数ModelMap model,它的功能不可小觑啊,方法要进行重定向跳转使,model中存放的值依然可从下一个方法的request中拿到。
【如何使用Hibernate自动建表的】
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 数据库配置转移到context.properties --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/logistics </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"> 123456 </property> <property name="connection.useUnicode">true</property> <property name="connection.characterEncoding">utf8</property> <property name="dialect"> org.hibernate.dialect.MySQLDialect </property> <property name="show_sql">true</property> <property name="hbm2ddl.auto">create</property> <!-- 需要建表的实体类--> <mapping class="cn.gacinfo.business.domain.project.Client"/> <mapping class="cn.gacinfo.business.domain.project.Grade"/> </session-factory> </hibernate-configuration>
public class SchemaExportWrapper { @Autowired private SessionFactory sessionFactory; public SchemaExportWrapper() { } /** * @param args * 第一个参数为hibernate config文件路径 第二个参数为sql输出文件路径 * @throws IOException */ public static void main(String[] args) { try{ createDBTable(); }catch(Exception ex){ ex.printStackTrace(); } //createJbpmSchema(); } public static void createDBTable() { Logger logger = LoggerFactory.getLogger(SchemaExportWrapper.class); logger.info("****************"); AnnotationConfiguration acfg = new AnnotationConfiguration(); // Configuration cfg = acfg // .configure("hibernate/hibernate-tools.cfg.xml.ora"); Configuration cfg = acfg.configure("hibernate/hibernate-tools.cfg.xml"); SchemaExport schemaExport = new SchemaExport(cfg); // // schemaExport.setOutputFile("misc/database/createDB.sql"); // // schemaExport.execute(true, true, true, false); schemaExport.drop(true, true); schemaExport.create(true, true); } }
【page标签的使用】已总结,改变start元素的值,并提交form[0]
【中文乱码问题】已总结,后来在做按中文名称进行搜索时,发现需要post提交,正是这个原因,即普通的浏览方法是get提交而搜索是post提交,使我将搜索方法与浏览方法进行了分离
【权限部分的业务及代码】
权限,就是对web资源的访问权,表现为对超链接的访问权,有三个主要属性:权限名称、功能点、URL。在我们的项目中,它的作用有两处,①预置一套完整菜单,在用户登陆时,通过对用户权限的判断,进行选择性的呈现②用户登陆后,在每次访问网站资源时,判断他是否具有访问该资源的权限,如无,则拒绝访问。这第二点暂时还没有实现,需要写一个过滤器,根据用户的请求分析出请求的功能点(拦截到用户欲访问的链接,查询出该链接对应的功能点),然后判断当前登陆用户是否有该功能点对应的权限。
在我们的项目中,存在两类用户,一类是长期的稳定的,主持着所有项目活动的开展,而另一类是临时的偶尔的,只参与一个或几个项目,针对这两类用户,将权限也分两类:职务权限、角色权限。当一个用户拥有某项职务时,他就拥有了改职务权限,适用于所有的项目;当一个用户在某个项目下拥有某项角色时,他的角色权限只适用于该项目,如果他还在其他项目下拥有角色时,那他就还在其他项目下拥有相应的角色权限。
// 综合判断此用户在某项目中是否具有访问功能点的权限 public boolean hasAuthorityForUser(String userId, String projectId, String fcode) { boolean result = false; Users user = userService.getUserById(userId); // 先判断此用户职务权限中是否包含此功能点 if (user.getPosition() != null) { Set<Authority> authoritys = user.getPosition().getAuthority(); if (!authoritys.isEmpty()) { Iterator<Authority> iterators = authoritys.iterator(); while (iterators.hasNext()) { Authority auth = iterators.next(); if (fcode.equals(auth.getFtcode())) { return true; } } } } // 先判断此用户项目权限中是否包含此功能点 Project project = new Project(); project.setId(projectId); List<ProjectAuthority> projectAuthority = projectAuthorityService .getProjectAuthority(user, project, null); if (projectAuthority.size() > 0) { for (int i = 0; i < projectAuthority.size(); i++) { ProjectAuthority pauthority = projectAuthority.get(i); Set<Authority> ProjectAuthority = pauthority.getRole() .getAuthority(); for (Iterator<Authority> iterator = ProjectAuthority.iterator(); iterator .hasNext();) { Authority auth = iterator.next(); if (fcode.equals(auth.getFtcode())) { return true; } } } } return result; }
【绝对路径、相对路径】
假如当前的项目是demo,那么
前台默认的路径是:http://localhost:8080/demo/
后台默认的路径是从webRoot开始的,但如果配置了视图解析器,那情况就不同了
【在SpringMVC中使用Ajax的例子】
在SpringMVC框架中使用Ajax,后台写法: @RequestMapping("/bbs/savebanzhu") public @ResponseBody Message saveBanzhu(String blockid,String useremail){ Message mes = new Message(); User user = userService.findByEmail(useremail); if(user != null){ boolean result = bas.saveBanzhu(blockid, user.getId()); if(result){ mes.setType(Const.SUCCESS); }else{ mes.setType(Const.ERROR); mes.setMessage("操作失败"); } }else{ mes.setType(Const.ERROR); mes.setMessage("您输入的用户Email有误"); } return mes; } 前台写法: //添加版主 $(".addblockuser").click(function(){ $("#useremail").val(""); $("#useremail").focus(); }); $("#add").click(function(){ var useremail = $("#useremail").val(); if(useremail==""){ alert("sorry,用户邮件地址不能为空~"); $("#useremail").focus(); }else if(!check_email()){ alert("sorry,用户邮件格式不正确~"); $("#useremail").focus(); }else{ $.post("${basePath}/ks-admin/bbs/savebanzhu",{"useremail":useremail,"blockid":blockid},function(json){ $(json).each(function(){ if(this.type == "success"){ alert("操作成功!"); window.location.href = "${basePath}/ks-admin/bbs"; }else{ alert(this.message); $("#useremail").focus(); } }); }); } });
喜欢自顶向下的方式去开发,把一个稍微模糊的问题推到了DAO的角落里,变得容易实现。
感觉有创意的工作是,下拉框选择按批次、按编号等,对应的值如1、2作为参数传给后台以确定查询方式;当查询结果页面与查询前页面共用一张页面时,用一个变量queryTag来告诉后台:前台想走的是“浏览”路线(取0)还是“搜索”路线(取1)。同时,后台走完其中一条路线后,会把queryTag发给前台以标记前台页面的状态(前台在翻页浏览时,保持该状态,在查询全部和进行搜索时,会改变该queryTag的值)。
哈,还有很多东西要学,加油吧