实现mybatis一对多的关联
解决一个Person有多张IdCard
重点:
- 在IdCard类中添加 person.id 属性
- 在person类中添加List< IdCard> cardList 属性
- 在PersonMapper.xml中
< resultMap>
…
< collection ofType="…IdCArd">
< /collection>
</ resultMap>
项目结构图:
1)创建数据表
本实例需要两张数据表
person表:
CREATE TABLE `person` (
`id` int(2) NOT NULL,
`name` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
);
idcard表:
CREATE TABLE `idcard` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`code` varchar(18) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
`person_id` int(2) DEFAULT NULL,
PRIMARY KEY (`id`)
);
2)创建持久化类
IdCard:
package onetomany.po;
public class IdCard {
private Integer id;
private String code;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
@Override
public String toString() {
return "IdCard [id=" + id + ", code=" + code + "]";
}
}
Person:
package onetomany.po;
import java.util.List;
public class Person {
private Integer id;
private String name;
private Integer age;
//增加list
private List<IdCard> cardList;
public List<IdCard> getCard() {
return cardList;
}
public void setCard(List<IdCard> cardList) {
this.cardList = cardList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + ", cardList=" + cardList + "]";
}
}
3)创建映射文件
IdCardMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="onetomany.dao.IdCardDao">
<select id="selectCardById" parameterType="Integer" resultType="onetomany.po.IdCard">
select * from idcard where person_id=#{id}
</select>
</mapper>
PersonMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace命名空间,唯一标识。一般指定为自定义的接口文件,下面相当于这个接口的实现类 -->
<mapper namespace="onetomany.dao.PersonDao">
<!-- 第一种:一对一根据id查询个人信息:级联查询(嵌套查询,执行两个SQL语句)-->
<!-- 定义结果集,column表示sql查询列,property表示映射到实体的属性 -->
<resultMap type="onetomany.po.Person" id="cardAndPerson1">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<!-- 关联对象 -->
<!-- 使用select属性指定第二步调用的方法,并通过column指定传递的参数值,这个值是第一步的查询的数据 -->
<collection property="cardList" column="id"
ofType="onetomany.po.IdCard" select="onetomany.dao.IdCardDao.selectCardById"/>
</resultMap>
<!-- 第一步值只查询person表 -->
<select id="selectPersonById1" parameterType="Integer" resultMap="cardAndPerson1">
select * from person where id=#{id}
</select>
<!--
第二种:一对一根据id查询个人信息,级联查询(嵌套结果,执行一个SQL语句)
<resultMap type="onetomany.po.Person" id="cardAndPerson2">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="age" column="age"/>
<collection property="cardList" ofType="onetomany.po.IdCard">
<id property="id" column="id"/>
<result property="code" column="code"/>
</collection>
</resultMap>
resultMap指定使用上面定义的结果集,查询使用关联查询,查询列要和上面的column对应
<select id="selectPersonById2" parameterType="Integer" resultMap="cardAndPerson2">
select person.*,idcard.*
from person, idcard
where person.id=idcard.person_id
and person.id=#{id}
</select>
-->
</mapper>
mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J" />
<!--在使用MyBatis嵌套查询方式进行关联查询时,使用MyBatis的延迟加载可以在一定程度上提高查询效率-->
<!--打开延迟加载的开关-->
<setting name= "lazyLoadingEnabled" value= "true"/>
<!--将积极加载改为按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<!-- 配置mybatis运行环境 -->
<environments default="development">
<environment id="development">
<!-- 使用JDBC的事务管理 -->
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<!-- MySQL数据库驱动 -->
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<!-- 连接数据库的URL -->
<property name="url"
value="jdbc:mysql:///mybatis?serverTimezone=Asia/Shanghai&useSSL=true" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="onetomany/mybatis/IdCardMapper.xml"/>
<mapper resource="onetomany/mybatis/PersonMapper.xml"/>
</mappers>
</configuration>
5)创建数据操作接口
IdCardDao:
package onetomany.dao;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import onetomany.po.IdCard;
@Mapper
public interface IdCardDao {
//根据person的id查询
public List<IdCard> selectCardById(Integer id);
}
PersonDao:
package onetomany.dao;
import org.apache.ibatis.annotations.Mapper;
import onetomany.po.Person;
@Mapper
public interface PersonDao {
public Person selectPersonById1(Integer id);
public Person selectPersonById2(Integer id);
}
6)测试
TestOnetoMany:
package onetomany.controller;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import onetomany.dao.PersonDao;
public class TestOneToMany {
public static void main(String[] args) throws IOException {
String resource="onetomany/mybatis/mybatis-config.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession=sessionFactory.openSession();
PersonDao personDao=sqlSession.getMapper(PersonDao.class);
System.out.println(personDao.selectPersonById1(1));
}
}
结果: