项目结构:
创建两个表:学生表和身份证表,一对一的关系:
create table cards(
cid int(5) primary key,
cnum varchar(10)
);
create table students(
sid int(5) primary key,
sname varchar(10),
scid int(5),
constraint scid_fk foreign key(scid) references cards(cid)
);
insert into cards(cid,cnum) values(1,'111');
insert into students(sid,sname,scid) values(1,'哈哈',1);
身份证实体类 Card.java:
package com.mybatis.one2one;
/**
* 身份证实体类
*/
public class Card {
private int id;
private String num;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Override
public String toString() {
return "Card{" +
"id=" + id +
", num='" + num + '\'' +
'}';
}
}
身份证实体类与表的映射配置文件 CardMapper.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="cardNamespace">
<!-- resultMap 标签:映射实体与表的关系 -->
<resultMap id="cardMap" type="com.mybatis.one2one.Card">
<id property="id" column="cid"/>
<result property="num" column="cnum"/>
</resultMap>
</mapper>
学生实体类 Student.java:
package com.mybatis.one2one;
/**
* 学生实体类
*/
public class Student {
private int id;
private String name;
private Card card; // 关联属性(身份证实体类)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Card getCard() {
return card;
}
public void setCard(Card card) {
this.card = card;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", card=" + card +
'}';
}
}
学生实体类与表的映射配置文件 StudentMapper.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="studentNamespace">
<!-- resultMap 标签:映射实体与表的关系 -->
<resultMap id="studentMap" type="com.mybatis.one2one.Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<!--
引入 CardMapper.xml 中的映射信息:
property:表示 Student 实体类中关联 Card 实体类的属性;
resultMap:表示查询到的数据根据 cardMap 中的映射关系封装到实体类中;
-->
<association property="card" resultMap="cardNamespace.cardMap"/>
</resultMap>
<!-- 查询语句 -->
<select id="findById" parameterType="int" resultType="com.mybatis.one2one.Student" resultMap="studentMap">
select s.sid, s.sname, c.cid, c.cnum
from students s inner join cards c
on s.scid = c.cid
where s.sid = #{id}
</select>
</mapper>
数据库配置文件 db.properties:
# mysql 配置
mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://localhost:3306/mybatis
mysql.username=root
mysql.password=root
# oracle 配置
oracle.driver=oracle.jdbc.driver.OracleDriver
oracle.url=jdbc:oracle:thin:@localhost:1521:orcl
oracle.username=scott
oracle.password=tiger
主配置文件 mybatis.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>
<!--
加载 src 路径下的 配置文件(db.properties);
下面通过 ${ 键 } 获取对应的值;
-->
<properties resource="db.properties"/>
<!--
设置类型别名:在映射文件中所有的 com.mybatis.demo.Student 类型都可以使用 student 代替
-->
<typeAliases>
<typeAlias type="com.mybatis.one2one.Student" alias="student"/>
</typeAliases>
<!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_developer">
<!-- 连接环境信息:取一个任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis 使用 jdbc 事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis 使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!--
配置与数据库交互的4个必要属性 ;
${mysql.driver}:表示获取 db.properties 配置文件中 mysql.driver 的值;
-->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
<!-- 连接环境信息:取一个任意唯一的名字 -->
<environment id="oracle_developer">
<!-- mybatis 使用 jdbc 事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis 使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="com/mybatis/one2one/StudentMapper.xml"/>
<mapper resource="com/mybatis/one2one/CardMapper.xml"/>
</mappers>
</configuration>
工具类 MybatisUtils.java:
package com.mybatis.one2one;
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 java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
/**
* 工具类
*/
public class MybatisUtils {
/**
* 禁止外界通过 new 方法创建 工具类对象:构造方法私有化;
*/
private MybatisUtils(){}
/**
* 创建一个线程对象,目的是将 SqlSession 和当前线程绑定到一起,线程结束,SqlSession 销毁;
*/
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
/**
* SqlSession 工厂
*/
private static SqlSessionFactory sqlSessionFactory;
/**
* 类加载的时候 自动加载 src/mybatis.xml 配置文件
*/
static {
try {
// 加载配置文件
Reader reader = Resources.getResourceAsReader("mybatis.xml");
// 根据配置文件构造 SqlSession 工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获取 SqlSession
*/
public static SqlSession getSession() {
// 从当前线程中获取 SqlSession
SqlSession sqlSession = threadLocal.get();
// 如果线程中没有 SqlSession 的话
if (sqlSession == null) {
// 找 SessionFactory 创建一个 SqlSession
sqlSession = sqlSessionFactory.openSession();
// 将当前线程与 SqlSession 绑定到一起
threadLocal.set(sqlSession);
}
// 返回 SqlSession 对象
return sqlSession;
}
/**
* 关闭 SqlSession,并与当前线程分离
*/
public static void closeSqlSession() {
// 从当前线程中获取 SqlSession
SqlSession sqlSession = getSession();
// 如果有的话就关闭
if (sqlSession != null) {
// 关闭
sqlSession.close();
// 分离当前线程与 SqlSession,目的是让 GC 尽早回收
threadLocal.remove();
}
}
/**
* 测试是否连接成功
*/
public static void main(String[] args){
Connection connection = MybatisUtils.getSession().getConnection();
System.out.println(connection);
}
}
测试类 StudentCardDao.java:
package com.mybatis.one2one;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 持久层:测试一对一映射
*/
public class StudentCardDao {
/**
* 根据 id 查询学生信息
*/
public Student findById(int id) throws Exception{
// 获取 SqlSession 对象
SqlSession sqlSession = MybatisUtils.getSession();
try {
return sqlSession.selectOne("studentNamespace.findById", id);
}catch (Exception e){
e.printStackTrace();
throw e;
}finally {
MybatisUtils.closeSqlSession(); // 关闭
}
}
public static void main(String[] args) throws Exception{
StudentCardDao dao = new StudentCardDao();
Student student = dao.findById(1);
System.out.println(student);
}
}
查询结果: