关联映射
简单的关联映射
在user_mapper.xml
<select id="getUser" parameterType="int" resultType="User">
select * from user where user_id=#{id}
</select>
<select id="getUserInfo" parameterType="int" resultMap="userInfo">
select * from user_info where user_id=#{userId}
</select>
<resultMap type="UserInfo" id="userInfo">
<association property="user" javaType="User" column="user_id" select="getUser"/>
</resultMap>
UserMapper接口
@MyBatisRepository
public interface UserMapper {
public UserInfo getUserInfo(int userId);
public User getUser(int id);
}
多表关联查询
mapper.xml中
<select id="getUserInfo2" parameterType="int" resultMap="UserInfo2">
select u.*,i.* from user_info i join user u on i.user_id=u.user_id
where i.user_id=#{userId}
</select>
<resultMap type="UserInfo" id="UserInfo2">
<id column="user_info_id" property="userInfoId"/>
<result column="age" property="age" />
<result column="sax" property="sax" />
<association property="user" javaType="User" >
<id column="user_id" property="userId"/>
<result column="email" property="email" />
<result column="password" property="password" />
<result column="nickname" property="nickname" />
</association>
</resultMap>
UserMapper接口中:
@MyBatisRepository
public interface UserMapper {
public UserInfo getUserInfo(int userId);
public UserInfo getUserInfo2(int userId);
public User getUser(int id);
}
在mybatis配置文件中增加下面的配置
<settings>
<!-- 数据库的字段为user_id 映射到类中字段为 userId-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开始自动映射,默认是不映射嵌套的结果集,这样写也会映射嵌套的结果集-->
<setting name="autoMappingBehavior" value="FULL"/>
</settings>
<!--别名配置,可以省略包名 -->
<typeAliases>
<package name="entity"/>
</typeAliases>
mapUnderscoreToCamelCase 这个属性的意思是把java实体类中的属性名和数据库的的表面的一个对应关系,比如:User类中的userId对应到数据库中的user表中的字段为user_id,这个是一个默认的驼峰法映射关系
autoMappingBehavior 这个属性的意思是开启自动映射,默认是不会映射嵌套的结果集,官方说明如下:指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。默认是PARTIAL.
在mapper.xml中可以这样写
<resultMap type="UserInfo" id="UserInfo2">
<association property="user" javaType="User" />
</resultMap>
当不去配置autoMappingBehavior,可以手动写
<resultMap type="UserInfo" id="UserInfo2" autoMapping="true">
<association property="user" javaType="User" autoMapping="true" />
</resultMap>
别名的配置,自动加包名
<typeAliases>
<package name="entity"/>
</typeAliases>
主键映射
UserMapper接口
@MyBatisRepository
public interface UserMapper {
public void saveUser(User user);
public void saveUserInfo(UserInfo info);
}
user_mapper.xml
<insert id="saveUser" parameterType="User" useGeneratedKeys="true" keyProperty="userId">
insert into user (email,password,nickname)values
(#{email},#{password},#{nickname})
</insert>
<insert id="saveUserInfo" parameterType="UserInfo">
insert into user_info(user_info_id,user_id,age,sex) values
(#{userInfoId},#{user.userId},#{age},#{sex})
</insert>
USerMapper的saveUser 这个方法会把生成的userId给传入的User对象中的userId进行赋值,从而业务层的代码能顺利执行
在业务层中的代码如下:
User user = new User();
user.setEmail("223@qq.com");
user.setPassword("123");
user.setNickname("weck");
UserInfo info = new UserInfo();
info.setUser(user);
info.setAge(16);
info.setSex("男");
userMapper.saveUser(user);
userMapper.saveUserInfo(info);
return "ok";
这里的user对象中的userId属性在执行saveUser后就会自动赋值进去,从而UserInfo能顺利插入表中,UserInfo表的user_id字段为插入的user生成的主键
Oracle数据库不能够主键自动递增,使用如下配置
<insert id="saveUser" parameterType="User">
<selectKey keyProperty="userId" order="BEFORE" resultType="int">
select user_seq.nextval from dual
</selectKey>
insert into user (user_id,email,password,nickname)values
(#{userId},#{email},#{password},#{nickname})
</insert>
一对多映射
user_mapper.xml,获取用户包含所有的blog,通过id查询
<select id="getBlogsbyUserId" parameterType="int" resultType="Blog">
select * from blog where user_id=#{userId}
</select>
<select id="getUseWithBlogById" parameterType="int" resultMap="userWithBlog">
select * from user where user_id=#{userId}
</select>
<resultMap type="User" id="userWithBlog">
<collection ofType="Blog" property="blogs"
javaType="java.util.ArrayList" column="user_id"
select="getBlogsbyUserId"/>
</resultMap>
也可以使用多表查询
在业务层
User u = userMapper.getUseWithBlogById(2);
在JavaBean中
public void setBlogs(List<Blog> blogs) {
this.blogs = blogs;
for(Blog b : blogs){
b.setUser(this);
}
}
拿到的每一个Blog对象中的user对象不再为空,这是一种解决方式
鉴别器
根据数据表中的某个字段返回相应的对象
Vehicle 交通工具类
Car和Boat是Vehicle的子类 ,根据vehicleType返回相应的对象
Vehicle类
public class Vehicle {
private int id;
private String vin; // 交通登记号码
private Date year;
private String color;
private String vendor;
private int vehicleType;
...
}
Car类
public class Car extends Vehicle {
private int doorCount;
public Car() {
}
public int getDoorCount() {
return doorCount;
}
public void setDoorCount(int doorCount) {
this.doorCount = doorCount;
}
@Override
public String toString() {
return "Car [doorCount=" + doorCount + "]";
}
}
Boat类
public class Boat extends Vehicle{
private String quant; //船桨
public Boat() {
}
@Override
public String toString() {
return "Boat [quant=" + quant + "]";
}
public String getQuant() {
return quant;
}
public void setQuant(String quant) {
this.quant = quant;
}
}
vehicle_mapper .xml
<mapper namespace="mapper.VehicleMapper">
<select id="selectVehicle" parameterType="int" resultMap="vehicleResult">
select * from vehicle where id =#{id};
</select>
<resultMap type="Vehicle" id="vehicleResult">
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultType="Car"/>
<case value="2" resultType="Boat"/>
</discriminator>
</resultMap>
</mapper>
VehicleMapper
@MyBatisRepository
public interface VehicleMapper {
public Vehicle selectVehicle(int id);
}
业务层
Vehicle v = vehicleMapper.selectVehicle(2);
如果vehicle_type是1就返回一个Car对象,2就返回Boat对象,其他返回父类对象Vehicle