mybatis小结4

mybatis小结4

多表查询创建两张表,添加相关属性

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

表与表之间建立关联靠字段

在java中,它是一个面向对象的语言,表明关系时,肯定是对象和对象,不能再是属性。

案例:

class Room{
//要和person产生关联 此处写为:
private List<Person> persons;
}
class Person{
//要和Room产生关系
private Room room;
//不能写成 private Integer roomId;
}

上面room和person的实例

room

package com.kang.model;

import java.util.List;

public class Room {
	//房间的编号
private Integer id;
 //房间的名称
private String name;
//房间关联的人,由于一个房间可以关联多个人,此处需要是一个集合
private List<Person> persons;
public Room() {
	
	
}

public Room(Integer id, String name, List<Person> persons) {
	super();
	this.id = id;
	this.name = name;
	this.persons = persons;
}

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 List<Person> getPersons() {
	return persons;
}
public void setPersons(List<Person> persons) {
	this.persons = persons;
}

@Override
public String toString() {
	return "Room [id=" + id + ", name=" + name + ", persons=" + persons + "]";
}


}

person

package com.kang.model;

public class Person {
	//人员编号
private Integer id;
//人员姓名
private String name;
//关联的房间,由于一个人只关联一个房间,所以此处给Room对象即可
private Room room;
public Person() {
	super();

}
public Person(Integer id, String name, Room room) {
	super();
	this.id = id;
	this.name = name;
	this.room = room;
}
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 Room getRoom() {
	return room;
}
public void setRoom(Room room) {
	this.room = room;
}
@Override
public String toString() {
	return "Person [id=" + id + ", name=" + name + ", room=" + room + "]";
}

}

映射文件

<?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.kang.dao.RPDao">
<!--我们查person时,需要关联查询room,此处就要通过resultMap建立结果映射 
-->
<resultMap type="person" id="personMap">
<!-- person自己的属性映射 -->
<id column="personId" property="id"/>
<result column="personName" property="name"/>

<!-- 自己关联对象的映射 
  如果关联的对象是一方,需要使用association标签
  property:对应的成员变量名
-->
<association property="room" javaType="com.kang.model.Room">
<!-- 配置room的字段和属性名的对应关系 -->
<id column="roomId" property="id"/>
<result column="roomName" property="name"/>
</association>
</resultMap> 


<!-- mybatis中多表联查时,通过resultMap进行结果映射时,
如果不同表中的字段名有一样的,通过别名区分 -->
<select id="queryById" resultMap="personMap">
select 
 person.id as  personId,
 person.name as personName,
 room.id as roomId,
 room.name as roomName
 from person
  left join room 
  on person.roomId=room.id
where person.id=#{id}
</select>


<!-- 建立room的结果映射 -->
<resultMap type="room" id="RoomMap">
 <id column="id" property="id"/>
 <result column="name" property="name"/>
 
 <!-- 关联的对象的映射 由于一个room可以关联多个person
 此处需要使用collection标签
 property:对应的成员变量名
 ofType:指定集合中的元素类型
  -->
  <collection property="persons" ofType="person">
   <id column="personId" property="id"/>
   <result column="personName" property="name"/>
  </collection>
  
</resultMap>
<select id="queryRoomById" resultMap="RoomMap">
select
  room.*,
  person.id as personId,
  person.name as personName
  from
   room
   left join
    person
    on room.id=person.roomId
    where
    room.id=#{id}
</select>

<!-- 
useGeneratedKeys:是否需要获取自增主键生成的值,true就是需要
keyProperty:指定将获取到的主键值存到那个属性中

要使用到该功能,方法的参数必须是实体类对象。因为拿到的主键值只能存放到
方法参数的对象的成员变量中!!

例如:当前例子中,方法的参数是room对象,一会就会把主键值存放到room.id中
 获取自增主键值的方案只能用于insert和update
 -->
 
 <!-- 
 #:会先用?占位,然后将获取到的值,赋值给?位置
 $:会直接将值填充到对应位置,但如果是字符串类型,它不会帮我们添加单引号
 或双引号,需要手动添加
  
  使用场景:#一般用在具体的字段值上
          $:一般用在表名、库名、字段名
  -->
<insert id="addRoom" useGeneratedKeys="true" keyProperty="id">
<!-- insert into room (name) values (#{name}) -->
insert into room (name) values (${name})
</insert>


  </mapper>

在这里插入图片描述

测试

package com.kang.test;

import static org.junit.jupiter.api.Assertions.*;




import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import com.kang.dao.RPDao;
import com.kang.dao.StudentDao;
import com.kang.model.Person;
import com.kang.model.Student;


public class MyTest2{

		//由于我们使用的是Session对象,所以SessionFactory值需要一个,
		//让sessionFactory对象只创建一个
		private static SqlSessionFactory sqlsessionFactory;
		private SqlSession  sqlSession;
		
		@BeforeAll
		public static void createFactory() throws IOException {
			InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
			sqlsessionFactory = new SqlSessionFactoryBuilder().build(in);
		}
		@BeforeEach
		public void createSession() {
			sqlSession = sqlsessionFactory.openSession();
		}
	
	@AfterEach
	public void releaseSession() {
		sqlSession.commit();
		sqlSession.close();
	}
	@AfterAll
	public static void releaseFactory() {
		sqlsessionFactory=null;
	}
	
	@Test
	public void queryById() {
		RPDao dao = sqlSession.getMapper(RPDao.class);
		Person person = dao.queryById(1);
		System.out.println(person);
	}
	
}

mybatis的注解:用来替代映射文件,将映射文件的配置内容,通过注解的方式,直接加到接口的方法上。

官方不推荐使用注解:原因是这种方式,会将sql语句和java语句混在一起,不方便维护。

package com.kang.dao;

import org.apache.ibatis.annotations.Insert;

import com.kang.model.Room;

//mybatis的注解式开发
public interface RoomDao {
   
	/*
	 * @Insert:修饰方法的注解,作用就等同于
	 * 映射文件中的insert标签
	 * value:该属性就是当前方法绑定的sql语句
	 * 当sql语句比较长,一行写不下时,也可以写成数组的形式
	 */
	//@Insert(value ="insert into room(name) values (#{name})" )
	
	@Insert(value= {
			"insert into room",
			"(name) values (#{name})"
		
	})
	public int add(Room room);
	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值