为了实现一个多表联合查询
我新建一个数据库表nation
在nation表里插入几行数据
select g.*,n.* from goods g,nation n where g.ID=n.goods_id
查到了,这就是多表连查
问题来了,你说这个多表连查应该怎么去封装数据呢?
首先再创建一个实体类,命名为Nation
思考下问题
1.多表连查是一个什么关系?
2.两表之间怎么去体现这样的关系
3.Java中类与类中的关系有2种,要么继承,要么关联
4.什么是关联? 就是在一个类中有另一个类的声明对象
/Mybatis02/src/com/chen/GoodsInfo.java
package com.chen;
public class GoodsInfo {
private int e_id ;
private String e_name;
//Java中类与类之间的关系。注意下面这引进了另一个类
private Nation nation ; //只声明,不赋值
public Nation getNation() {
return nation;
}
public void setNation(Nation nation) {
this.nation = nation;
}
public int getE_id() {
return e_id;
}
public void setE_id(int e_id) {
this.e_id = e_id;
}
public String getE_name() {
return e_name;
}
public void setE_name(String e_name) {
this.e_name = e_name;
}
}
老套路第1步
/Mybatis02/src/com/chen/dao/GoodsDao2.java
public List<GoodsInfo> selectAll3();
老套路第2步
/Mybatis02/config/mappers/GoodsInfoMapper.xml
<!-- type一定要对应实体类
id就是给当前配置的封装格式起一个唯一标识 -->
<select id="selectAll3" resultMap="lalala">
select g.id id,g.name name ,n.goods_id goods_id,n.from from goods g,nation n WHERE g.id = n.goods_id
</select>
<resultMap type="com.chen.GoodsInfo" id="lalala">
<!-- 下面这个id标签表示配置主键的封装格式 -->
<id column="id" property="e_id" />
<result column="name" property="e_name" />
<result column="goods_id" property="nati.goods_id" />
<result column="goods_id" property="nati.from" />
</resultMap>
老套路第3步
/Mybatis02/src/test/Start2.java
public class Start2 {
public static void main(String[] args) throws IOException {
String resource = "mybatis-conf.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//true表示自动提交。否则需要使用commit方法才会提交。默认是false
SqlSession session = sqlSessionFactory.openSession();
//拿到接口的代理对象
GoodsDao2 dao=session.getMapper(GoodsDao2.class);
List<GoodsInfo> list = dao.selectAll3();
System.out.println(list);
//如果上面不设置自动提交表单,那么就需要commit方法
session.commit();
}
}
点击运行
得到了3个对象,说明有3条数据,不信看看用这个SQL语句查下数据库
对没错,但是正常来说控制台应该是直接打印出相应的数据的,但不知道为什么 这里只显示出3个对象的引用地址
正常显示应该是下面这样
我只能改成这样,可以拿到第几个对象的对应属性。但这样好像很不直观
经过我的琢磨,愿来原因是这个
回到实体类GoodsInfo 里重写一个toSring()方法,让其返回相应信息
/Mybatis02/src/com/chen/GoodsInfo.java
package com.chen;
public class GoodsInfo {
private int e_id ;
private String e_name;
public Nation getNation() {
return nati;
}
public void setNation(Nation nati) {
this.nati = nati;
}
public int getE_id() {
return e_id;
}
public void setE_id(int e_id) {
this.e_id = e_id;
}
public String getE_name() {
return e_name;
}
public void setE_name(String e_name) {
this.e_name = e_name;
}
// 注意:新重写的方法 就是下面这个 .既 让其返回当前对象的对应字段
public String toString()
{
return "Goods [e_id=" +e_id + ",e_name=" +e_name + "]";
}
}
System.out.println(list);
System.out.println(list.toString());
发现结果就能正常显示出来了。且,这两个不语句的输出效果是一样的。
小细节
这里也另外也无意中发现。原来直接System.out.println(list); 就是默认list.toSring() 。本来我如果不重写toString() ,它系统默认的是输出当前对象的引用地址 (既是一个16进制的值)。而我现在重写了toString()。既
public String toString()
{
return "Goods [e_id=" +e_id + ",e_name=" +e_name + "]";
}
那么,这就使输出结果产生了变化.。
对了,上面return是自己手打的,感觉很麻烦,且很容易错。这里有个小技巧可以快速toString
右键实体类空白处---source -----generate toString() ---OK
那么就立刻快速生成了,不仅字段显示完整,而且不会错
@Override
public String toString() {
return "GoodsInfo [e_id=" + e_id + ", e_name=" + e_name + ", nati="
+ nati + "]";
}
回到主入口类 点击运行,看下新结果
[GoodsInfo [e_id=1, e_name=大米面膜, nati=com.chen.Nation@475530b9], GoodsInfo [e_id=2, e_name=泰国纳兰足贴, nati=com.chen.Nation@1d057a39], GoodsInfo [e_id=3, e_name=Mellin菊花晶, nati=com.chen.Nation@26be92ad]]
`
因为nati 是在GoodsInfo类中声明的一个对象。而刚nati所属的Nation实体类中 ,还没重写它的方法toString。 所以上面的结果就是输出nati对象的16进制的引用地址,因为这就是原本系统的toString()的默认方法。
那么现在我去Nation实体类里 像刚才一样 快速重写toString()
点击运行
[GoodsInfo [e_id=1, e_name=大米面膜, nati=Nation [goods_id=1, from=1]], GoodsInfo [e_id=2, e_name=泰国纳兰足贴, nati=Nation [goods_id=2, from=2]], GoodsInfo [e_id=3, e_name=Mellin菊花晶, nati=Nation [goods_id=3, from=3]]]