一个人有一个身份证,一个身份证属于一个人。定义表如下:
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for t_person
-- ----------------------------
DROP TABLE IF EXISTS `t_person`;
CREATE TABLE `t_person` (
`pid` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) NOT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
DROP TABLE IF EXISTS `t_card`;
CREATE TABLE `t_card` (
`cardNum` varchar(20) NOT NULL DEFAULT '',
`pid` int(11) NOT NULL,
PRIMARY KEY (`cardNum`),
KEY `t_card_t_person_pid_fk` (`pid`),
CONSTRAINT `t_card_t_person_pid_fk` FOREIGN KEY (`pid`) REFERENCES `t_person` (`pid`) ON DELETE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
注意t_card表中的pid是t_person的外键,并且建立了级联删除关系。
父级 主键被其它表作为外键 子级表示把其它表的主键作为自己的外键
RESTRICT、NO ACTION、SET NULL 和 CASCADE
RESTRICT、NO ACTION表示子级有数据改变是父级数据不更新
SET NULL 表示父级在更新或者删除时将子记录列的值设为null
ON DELETE CASCADE 表示父记录删除时子记录对应的列数据也删除
ON UPDATE CASCADE 表示父记录更新时子记录对应的列数据也更新。
一对一的关系主要是添加时要获取主表的主键,并作为子表的外键完成级联添加,查询时可以利用resultMap进行配置,让Mybatis自动完成级联查询。具体配置如下:
实体类:
@Data
@Accessors(chain = true)
public class Person {
private Integer pid;
private String username;
private Integer age;
}
@Data
@Accessors(chain = true)
public class Card {
private String cardNum;
private Person person;
}
PersonMapper.java
package com.song.mybatis.one.mapper;
import com.song.mybatis.one.entity.Card;
import com.song.mybatis.one.entity.Person;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface PersonMapper {
int addPerson(Person person);
@Insert("insert into t_card(cardNum,pid) values(#{cardNum},#{pid})")
int addCard(@Param("cardNum")String cardNum, @Param("pid")Integer pid);
List<Card> findAllCard();
Person findPerson(@Param("pid")Integer pid);
@Delete("delete from t_person where pid=#{pid}")
int deletePerson(@Param("pid")Integer pid);
@Delete("delete from t_card where pid=#{pid}")
int deleteCard(@Param("pid")Integer pid);
}
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">
<mapper namespace="com.song.mybatis.one.mapper.PersonMapper">
<resultMap id="cardMap" type="com.song.mybatis.one.entity.Card">
<id property="cardNo" column="cardNo"/>
<association property="person" javaType="com.song.mybatis.one.entity.Person" column="pid" select="findPerson">
<id property="pid" column="pid"/>
</association>
</resultMap>
<insert id="addPerson" useGeneratedKeys="true" keyProperty="pid">
insert into t_person(username, age) VALUES (#{username},#{age})
</insert>
<select id="findAllCard" resultMap="cardMap">
select * from t_card
</select>
<select id="findPerson" resultType="com.song.mybatis.one.entity.Person">
select * from t_person where pid=#{pid}
</select>
</mapper>
测试:
package com.song.test;
import com.song.mybatis.one.entity.Card;
import com.song.mybatis.one.entity.Person;
import com.song.mybatis.one.mapper.PersonMapper;
import com.song.mybatis.one.util.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
public class MyTest {
private SqlSession session;
private PersonMapper personMapper;
private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
@Before
public void before(){
this.session = MyBatisUtil.getSession();
this.personMapper =this.session.getMapper(PersonMapper.class);
}
@After
public void after(){
this.session.close();
}
@Test
public void testAdd(){
Person person=new Person();
person.setAge(22).setUsername("王五");
int m= this.personMapper.addPerson(person);
String cardNo= sdf.format(new Date());
System.out.println(cardNo);
int pid=person.getPid();
System.out.println(pid);
m+=this.personMapper.addCard(cardNo,pid);
if(m>=2){
this.session.commit();
}else{
System.out.println("sorry!");
}
}
@Test
public void testFindAll(){
List<Card> allCard = this.personMapper.findAllCard();
for(Card card: allCard){
System.out.println(card);
}
}
@Test
public void testDelete(){
// int m=this.personMapper.deleteCard(3);
int m=this.personMapper.deletePerson(6);
if(m>=1) {
this.session.commit();
}else{
System.out.println("执行失败!");
}
}
}
我们还可以通过@Results进行基于接口的注解实现,该方式无需xml文件,适合业务不太复杂的情况,方便快速实现,具体如下:
CardMapper.java (主要作用是查询所有身份证,自动关联查询每个身份证的人员的信息)
public interface CardMapper {
@Select("select * from t_card")
@Results({
@Result(column = "cid", property = "cid"),
@Result(column = "cardNum", property = "cardNum"),
@Result(
column = "pid",property ="person",javaType = Person.class,
one = @One(select = "com.zhe.tonysong.mapper.PersonMapper.findPersonById")
)
})
List<Card> selectCardList();
}
PersonMapper.java
public interface PersonMapper {
@Select("select * from t_person where pid=#{pid}")
Person findPersonById(@Param("pid")int pid);
}
测试:
@Test
public void test234(){
CardMapper cardMapper= sqlSession.getMapper(CardMapper.class);
cardMapper.selectCardList().forEach(card->{
System.out.println(card);
});
}
}
输出如下: