中华视窗是诚信为本,市场在变,我们的诚信永远不变...
总结多表查询(注解方式) 前言
在之前的总结多表查询(xml方式)的博客中,已经对多表查询做了一定的介绍,而且总结了基于xml的多表查询,一些通用的技术点可以翻阅上一篇博客。这次我们总结基于注解的多表查询。多对多查询的xml和注解方式我会再写个博客。
数据库表及关系
为了方便查看,这里再次给出user和表
一对多查询
首先和xml方式一样,我们要在User实体类中添加List 的集合成员变量,表示一对多映射关系,主表实体含有从表实体的集合引用。
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
//一对多映射关系,主表实体含有从表实体的集合引用
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", address='" + address + '\'' +
", sex='" + sex + '\'' +
", birthday=" + birthday +
'}';
}
}
由于采用注解方式,所以我们不需要再配置xml,直接在dao接口中进行注解。
可以发现其实注解进行封装映射配置和xml配置非常类似,注解和xml标签可以对应上。
public interface IUserDao {
/**
* 查询所有用户并携带账户信息
*
* @return
*/
//select注解用于查询操作,内容为查询语句
@Select("select * from user")
//用于封装user
@Results(id = "userMap",value = {
//id表示主键
@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
//定义一对多的关系映射,实现对account的封装
// @Many注解用于一对多或多对多查询使用
// select属性指定内容:查询用户的唯一标识
// column属性指定内容:用户根据id查询账户是所需要的参数
// fetchType属性指定内容:指定延时查询FetchType.LAZY或立即查询FetchType.EAGER
@Result(property = "accounts",column = "id",many = @Many(select = "com.cc.dao.IAccountDao.findByUid",fetchType = FetchType.LAZY))
})
List<User> findAll();
/**
* 根据id查询
*
* @param id
* @return
*/
@Select("select * from user where id = #{id}")
User findById(Integer id);
}
这里对注解详细说明一下
@注解,我们需要查询时用到的注解,里面放查询语句。我们可以点开源码看一下,它只有一个value属性,所以我们不需要写属性名。
可以发现我们注解配置查询语句相比于xml配置简单了很多,这是为什么?
我们画张图来解释一下,见图就懂。
@注解,这个注解其实功能相当于xml配置中的标签,我们也可以点开源码看一下。id相当于的id标签,@注解相当于下的标签。
最后@注解,属性和标签很类似,这里说明两个属性。@one和@many,其实也就相当于标签和标签,表示一对一和一对多映射。
点开@one注解和@many注解发现属性都是一样的。
属性指定内容:查询用户的唯一标识
属性指定内容:指定延时查询.LAZY或立即查询.EAGER。还有一个默认.,默认是立即查询。
然后我们就可以测试了,测试代码和结果和总结多表查询(xml方式)博客中的一样,这里就不再给出了。
多对一及一对一查询
和xml配置一样,首先我们在实体类中加入user成员变量表示一对一映射。
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//从表实体应该包含一个主表实体的对象引用
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUid() {
return uid;
}
public void setUid(Integer uid) {
this.uid = uid;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" +
"id=" + id +
", uid=" + uid +
", money=" + money +
'}';
}
}
然后配置在接口中注解,注解解释在上面已经给出。
public interface IAccountDao {
/**
* 查询所有账户,并携带用户信息
* @return
*/
@Select("select * from account")
@Results(id = "accountMap",value = {
@Result(id = true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column = "uid",one = @One(select = "com.cc.dao.IUserDao.findById",fetchType = FetchType.EAGER))
})
List<Account> findAll();
/**
* 根据用户id查询账户
* @param uid
* @return
*/
@Select("select * from account where uid = #{uid}")
List<Account> findByUid(Integer uid);
}
测试当然也是相同,这里也不再给出,大家可以点开头连接。