多表操作之一对一
1、由于MyBatis是半自动ORM,所以这里我们还是需要手动建库
User表:
userInfo表:
2、创建数据库对应实体类:
由于是多表查询,数据库表与表的关系,在代码里就体现的是类与类之间的关系
User实体类:
public class User implements Serializable{
private int userId;
private String userName;
private String userPwd;
private UserInfo info; //用户详细信息
public UserInfo getInfo() {
return info;
}
public void setInfo(UserInfo info) {
this.info = info;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPwd() {
return userPwd;
}
public void setUserPwd(String userPwd) {
this.userPwd = userPwd;
}
@Override
public String toString() {
return "User [userId=" + userId + ", userName=" + userName + ", userPwd=" + userPwd + ", info=" + info + "]";
}
}
UserInfo实体类:
public class UserInfo {
private int infoId;
private String infoAddress; //用户地址
private String infoPhone; // 用户电话
private int infoUserID; //对应用户主表ID
public int getInfoId() {
return infoId;
}
public void setInfoId(int infoId) {
this.infoId = infoId;
}
public String getInfoAddress() {
return infoAddress;
}
public void setInfoAddress(String infoAddress) {
this.infoAddress = infoAddress;
}
public String getInfoPhone() {
return infoPhone;
}
public void setInfoPhone(String infoPhone) {
this.infoPhone = infoPhone;
}
public int getInfoUserID() {
return infoUserID;
}
public void setInfoUserID(int infoUserID) {
this.infoUserID = infoUserID;
}
@Override
public String toString() {
return "UserInfo [infoId=" + infoId + ", infoAddress=" + infoAddress + ", infoPhone=" + infoPhone
+ ", infoUserID=" + infoUserID + "]";
}
}
3、新建工具类,用于获取SqlSession会话
public class DBUtil {
/**
* 每个数据库对应一个SqlSessionFactory
*/
private static SqlSessionFactory sqlSessionFactory;
/**
* 1、静态块初始化,通过字节输入流读取配置文件
*/
static {
InputStream is=null;
try {
is=Resources.getResourceAsStream("sqlMapConfig.xml");
/**
* 2、获得SqlSessionFactory
*/
sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 3、通过SqlSessionFactory获得SqlSession会话
*/
public static SqlSession getsqlsession() {
return sqlSessionFactory.openSession();
}
}
4、创建实体类对应的接口,配置映射文件
UserMapper:
public interface UserMapper {
/**
* 通过用户id查询用户所有信息(一对一查询)
* @param id 用户id
* @return user用户对象
*/
public User findUserAndInfo(int id);
}
配置User映射文件:UserMapper.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.zh.mapper.UserMapper">
<!-- (多表查询,一对一查询) -->
<resultMap type="User" id="UserAndInfo">
<id property="userId" column="user_id" javaType="int"></id>
<result property="userName" column="user_name" javaType="java.lang.String"></result>
<result property="userPwd" column="user_pwd" javaType="java.lang.String"></result>
<!-- 映射多表,select对应从表查询方法 -->
<association property="info" column="user_id" javaType="UserInfo"
select="com.zh.mapper.UserInfoMapper.findInfoById"></association>
</resultMap>
<!-- 通过用户ID查询用户的所有信息(一对一查询) -->
<select id="findUserAndInfo" resultMap="UserAndInfo">
select * from t_user where user_id=#{id}
</select>
</mapper>
接着我们写从表的映射文件,首先写从表的实现接口:
UserInfoMapper:
public interface UserInfoMapper {
/**
* 通过ID查询所有信息
* @param id用户ID
* @return 用户信息对象
*/
public UserInfo findInfoById(int id);
}
从表映射配置:UserInfoMapper.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.zh.mapper.UserInfoMapper">
<!-- 单表查询,一对一查询 -->
<resultMap type="UserInfo" id="userInfoMap">
<id property="infoId" column="info_id" javaType="int"></id>
<result property="infoAddress" column="info_address" javaType="java.lang.String"></result>
<result property="infoPhone" column="info_phone" javaType="java.lang.String"></result>
<result property="infoUserID" column="info_userID" javaType="int"></result>
</resultMap>
<select id="findInfoById" resultMap="userInfoMap">
select * from t_userInfo where info_userID=#{id}
</select>
</mapper>
5、接下来是实现层:
UserService:
public class UserService {
// 调用实现sqlsession会话
SqlSession sqlsession = DBUtil.getsession();
// 接口不能直接new,通过session的getMapper方法实现,参数为接口的class文件
UserMapper mapper = sqlsession.getMapper(UserMapper.class);
// 通过ID查询用户的所有信息(一对一)
public User findUserAndInfo(int id) {
User user = mapper.findUserAndInfo(id);
return user;
}
}
UserInfoService:
public class UserInfoService {
// 调用实现sqlsession会话
SqlSession sqlsession = DBUtil.getsession();
// 实现对应的mapper接口
UserInfoMapper mapper = sqlsession.getMapper(UserInfoMapper.class);
public UserInfo findInfoById(int id) {
return mapper.findInfoById(id);
}
}
6、写到这里,基本上就完工了,接下来就开始测试:
新建测试类:UserAction:
public class UserAction {
//实例化UserService
private static UserService service=new UserService();
public static void main(String[] args) {
//调用service的方法
User user=service.findUserAndInfo(1);
System.out.println(user);
}
}
7、获得结果:
最后,总结下:由于我们需要查两张表的数据,每张表对应一个实体类,而我们需要查每个类里面的属性,所以我们就需要建立单表个的查询,然后通过映射,把两个类相关联,最后就查询出我们需要的数据了。