一、设计实体类时比较原来学校学到的知识:
原有的设计都是数据库存什么字段,就在实体类里生成相应的字段。由于本人的mybatis也只是仅仅会用的菜鸟水平,并不没有用过manyToOne、oneToOne、oneToMany等,使用的还是之前学到的知识与思路。
Eg:
关联表
对应实体类的字段
红色的为外键,而蓝色的就是为了后期传数据方便添加的外键实体
这样的设计导致每次查询时候想要获得Scored这个实体,项目需要经过的操作有2步,
①、从scored表中查出数据
②、遍历所有的scored对象,对于每个timuId,userId,去相应表中取出相应记录并赋给相应Timu,User实体。并塞到Scored的timu与user对象中。
这样虽然可以获得所有的数据,但必然会造成查询时间增加。
对比最近刚接触的hibernate注解:
数据库设计,依然是填入id
但对应的实体类就直接使用了对应外键的实体
具体代码如下:
@ManyToOne(fetch = FetchType.LAZY, targetEntity = UserHome.class)
@JoinColumn(name = "user_id")
public UserHome getUserHome() {
return userHome;
}
public void setUserHome(UserHome userHome) {
this.userHome = userHome;
}
@ManyToOne指明了这个ScoreAllLogs类对于UserHome类是多对一的关系,目标实体是UserHome.class。注意是要放在get方法上,我最早直接放在了实体申明上,结果就是什么奇迹都没有发生。
@JoinColumn则指明了本表中什么字段用于关联外表
这样Hibernate在我们存储实体的时候,就会自动将实体的Id存入ScoreAllLogs表了。
在取出数据的时候,又会根据id自动将实体关联好并传入ScoreAllLogs实体中。
这样做的好处是避免了代码的冗余,并减少了与数据库交互的次数,直接提升操作的速度。
二、实体类中get的巧用
这是我目前这个阶段没有见过的骚操作,当四哥把这方法教我的时候我都震惊了!
具体过程是这样的:我的项目在与客户沟通之后,原有的考试时间取配置文件的方法他们要求改成每题可以设置不同的时间,然后我就从数据改起啊,想着所有的后台要改以及前端都要换页面,多么浩大的工程!按照原来的思路,这一块基本是等于重做了吧。
这时候四哥给我说了一个思路,
1、对于所有的题目,都一个时间这个需求是不变的,只是时间的来源变了而已(来自配置文件或者本题的时间),不管如何时间都是附属于这个实体类的。那我们的对于时间的操作就可以在实体类中进行,而set方法我们尽少用,处理的话多在get方法上。
2、实体类也是一个java类,也可以写java代码。如果有关实体类属性的逻辑判断,方法等,都可以写在实体类中,减少在service中再次处理实体类,造成代码的冗余。
那么是不是可以做一个开关,分别对应是取配置文件还是取本题时间。那么对于后期如果用户又想用统一考试时间的时候,数据库我就不用再做更改了,前端配合EL表达式来控制时间框的显隐就行。
配置文件如下:
源码:Timu实体类,改写getTime的内部,根据配置文件中的开关来决定时间的来源。
public Integer getTimuTime() {
try {
//时间开关 取配置文件的时间 or 取本题的时间
Integer open = Integer.parseInt(GetProperty.getPropertyByName2("setTime.properties", "simpleTimer.switch"));
if (open == 1 || timuTime == null) {//如果开关打开或者题目时间未填写 取配置文件的时间
String timer = GetProperty.getPropertyByName2("setTime.properties", "simpleTimer.timer");
return Integer.parseInt(timer);
} else {
return timuTime;
}
} catch (Exception e) {
System.out.println("取题目时间出错:"+e.getMessage());
return timuTime;
}
}
效果(此时是使用题目自带的时间):
此时使用统一时间:
更改配置文件中的开关:
再来看这时候题目的时间(使用统一的时间):
清一色的变成了配置文件中设置的时间,这样对于用户的需求变更,只需要改一个数字就可以达成,无需再费时费力的将代码从头改到尾了。
另一个巧妙的用法:
前台EL需要一个标志来判断一个输入框是否展示,则用这种get,加上@Transient的意思是不加入实体中,也就是不生成属性。
/**
*
* @author xuexy
* @Title: isOtherMajor
* @Description: 判断用户的专业是否是其他
* @return 是返回true 不是返回false
* @return Boolean
* @throws
*
*/
@Transient
public Boolean getOtherMajor() {
boolean flag = true;
List list= Constants.MajorList.getList();
List listForBL=list.subList(0,10);//判断是否在给定范围中 0~9 不包括10
for (MajorList li:listForBL) {
if(li.getFriendlyType().equals(this.getMajor())){//如果在在给定范围中 则置否 不是其他项
flag=false;
}
}
return flag;
}
前台可以这样取值:
这样就可以在不添加属性的前提下,增加判断的方法了。
这些思想在我一个菜鸟看来十分好用,于是做了这篇笔记。