联查属性有些为空

使用外连接保留无法匹配的元组。

sql:

1)LEFT JOIN或LEFT OUTER JOIN
左向外联接的结果集包括 LEFT OUTER子句中指定的左表的所有行,而不仅仅是联接列所匹配的行。如果左表的某行在右表中没有匹配行,则在相关联的结果集行中右表的所有选择列表列均为空值。 示例:

SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
LEFT JOIN Orders
ON Persons.Id_P=Orders.Id_P
ORDER BY Persons.LastName

2)RIGHT JOIN 或 RIGHT OUTER JOIN
右向外联接是左向外联接的反向联接。将返回右表的所有行。如果右表的某行在左表中没有匹配行,则将为左表返回空值。
3)FULL JOIN 或 FULL OUTER JOIN
完整外部联接返回左表和右表中的所有行。当某行在另一个表中没有匹配行时,则另一个表的选择列表列包含空值。如果表之间有匹配行,则整个结果集行包含基表的数据值。

Hibernate中:

在hql里使用外连接必须先保证已经为表建立好外键关系。
例如每个鸟类活动(BirdActivitySituation)中记录一种鸟类(BaseBirdInfo),二者通过birdId进行关联。则在BirdActivitySituation.java中添加如下语句:

@OneToOne(targetEntity=BaseBirdInfo.class,cascade=CascadeType.ALL)
@Fetch(FetchMode.JOIN)
@JoinColumn(name="birdId",insertable=false,updatable=false) 
private Set<BaseBirdInfo> baseBirdInfo=new LinkedHashSet<BaseBirdInfo>();

JPA中@JoinTable和@JoinColumn注解的使用:https://blog.csdn.net/yu870646595/article/details/51064634

注:此处因为原来已经有birdId属性,新增的关联birdId会出现重复,因此需要insertable=false,updatable=false

代码:
BirdActivitySituation.java

import java.util.Date;
import java.util.LinkedHashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

@Entity
@Table(name = "bird_activity_situation")

public class BirdActivitySituation implements java.io.Serializable{

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
     private Integer activityId;
	 private Integer airportId;
	 private Integer regionId;
	 private Integer birdId;//对应鸟类信息表birdId
	 private Integer familyId;
	 private String activityNum;
	 private String activityName;
     private Date  activityTime;
     private String activitySite;
     private String description;
     private String windSpeed;
     private String windDirection;
     private String temperature;
     private String humidity;
     private String airVisibility;
     private String weather;
     private Date inTime;
     private Date outTime;
     private String birdCount;
     private String flyDirection;
     private String flyDirection1;
     private String flyDirection2;
     private String flySpeed;
     private String flyStartPosition;
     private String flyEndPosition;
     private String frequency;
     private String behavior;
     private Integer flyHeight;
     private String recorder;
     private Date recordTime;
     
     //以下关联鸟类信息表birdId
     @OneToOne(targetEntity=BaseBirdInfo.class,cascade=CascadeType.ALL)
     @Fetch(FetchMode.JOIN)
     @JoinColumn(name="birdId",insertable=false,updatable=false) 
     private Set<BaseBirdInfo> baseBirdInfo=new LinkedHashSet<BaseBirdInfo>();//关联属性

	public Set<BaseBirdInfo> getBirdActivityPoint() {
		return baseBirdInfo;
	}

	public void setBirdActivityPoint(Set<BaseBirdInfo> birdActivityPoint) {
		this.baseBirdInfo = birdActivityPoint;
	}
//.........set和get方法等等.............

BaseBirdInfo .java

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "base_bird_info")
public class BaseBirdInfo implements java.io.Serializable{
	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
    private Integer birdId;
	private Integer catalogId;  //所在目、科*/
	private String birdNum;
	private String birdName;
	private String pinyin;//拼音
	private String eName;//英文名
	private String lName;//拉丁名
	private String migratory;//留居状况
	private String activityAreas;//活动地带
	private String conservation;//保护等级  分几等?
	private String ecofeature;//生态特征
	private String bodyLength;//体长
	private String wingLength;//翅长
	private String weight;//重量
	private String integralColor;//总体颜色
	private String headColor;//头部颜色
	private String feathering;//有无羽饰
	private Integer birdSequence;//排序
	private Integer pictureAttachId;//图鉴
	private Integer photoAttachId ;//照片

BirdActivityPointDaoImpl.java(记录鸟类出现坐标)

public List getPointCodeAndCorrespondBird(BasQueryForm qForm) {
		Integer airportId = Integer.valueOf(qForm.getAirport());
		String sql = "select a.activityId,p.pointId,b.birdId,substring(cast(p.code as string),1,2) as x,"
				+ "substring(cast(p.code as string),3,2) as y,b.birdName "
				+ "from BirdActivitySituation a left join a.baseBirdInfo b,BirdActivityPoint p where p.activityId = a.activityId ";
		if(airportId != null)
			sql += " and a.airportId="+airportId;
		if(qForm.getStartDate() != null) {
			 sql += " and a.activityTime >='" + DateTimeTool.parseDateTime(qForm.getStartDate(), "yyyy-MM-dd") + " 00:00:00'";
		}
		if(qForm.getEndDate() != null) {
			 sql += " and a.activityTime <='" + DateTimeTool.parseDateTime(qForm.getEndDate(), "yyyy-MM-dd") + " 23:59:59'";
		}
		sql += " order by code";
		List<Object[]> list = this.queryForList(sql);
		List formList = new ArrayList<>();
		if(list.size()>0) {
			for(Object[] obj:list) {
				BirdActivityPointForm form = new BirdActivityPointForm();
				form.setActivityId(Integer.parseInt(obj[0].toString()));
				form.setPointId(Integer.parseInt(obj[1].toString()));
				if(obj[2]!=null && !obj[2].toString().equals(""))
					form.setBirdId(Integer.parseInt(obj[2].toString()));
				form.setX(Integer.parseInt(obj[3].toString()));
				form.setY(Integer.parseInt(obj[4].toString()));
				if(obj[5]!=null && !obj[5].toString().equals(""))
					form.setBirdName(obj[5].toString());
				formList.add(form);
			}
		}
		return formList;
	}

猜你喜欢

转载自blog.csdn.net/weixin_43322208/article/details/83999485