一、Mybatis一对一映射
本例讲述使用mybatis开发过程中常见的一对一映射查询案例。只抽取关键代码和mapper文件中的关键sql和配置,详细的工程搭建和Mybatis详细的流程代码可参见《Mybatis入门和简单Demo》和《Mybatis的CRUD案例》
案例:根据一个学生id查询对应的唯一的身份证信息
步骤1.建表脚本,创建身份证表cards和students,students字段cid(身份证id)作为cards字段id的外键
create table cards( id int(5) primary key, num varchar(20) ); create table students( id int(5) primary key, name varchar(10), cid int(5), constraint cid_fk foreign key(cid) references cards(id) );
insert into cards(id,num) values(2,'12345');
insert into students(id,name,cid) values(1,'cat',2);
步骤2.构建身份证,学生信息实体类
package com.jyk.mybatis.oneByone; public class Card { private int cid; //身份证id private String cnum; //身份证号码 public int getCid() { return cid; } public void setCid(int cid) { this.cid = cid; } public String getCnum() { return cnum; } public void setCnum(String cnum) { this.cnum = cnum; } }
package com.jyk.mybatis.oneByone; public class Student { private int id; //学生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; } }
步骤3.编写mapper文件,在CardMapper.xml中编写身份证信息和表字段的映射关系,在StudentMapper.xml中编写学生实体和表字段的映射关系,并编写好根据id查询身份证信息的SQL,并将mapper文件和对应实体类的别名加入mybatis.xml(mybatis.xml的描述见Mybatis系列第一篇博客)
在Student实体中有一属性为Card对象,意为一个学生对应的完整身份证信息,此时在配置映射关系时,可使用<association property="card" resultMap="cardNamespace.cardMap"/>标签来引入,property为属性名,resultMap关联到对应实体类的mapper配置,用名称空间.id来表示。
<?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"> <!-- 名称空间namespace必须唯一 --> <mapper namespace="studentNamespace"> <!-- resultMap标签:映射实体与表 type属性:实体全路径名 id属性:为实体与表的映射取一个唯一的编号 --> <resultMap type="student" id="studentMap"> <!-- id标签:映射主键属性 result标签:映射非主键属性 property属性:实体属性名 column属性:表的字段名 --> <id property="id" column="id"/> <result property="name" column="name"/> <association property="card" resultMap="cardNamespace.cardMap"/> </resultMap> <!-- 根据学生id找到对应学生信息和身份证信息 --> <select id="findById" parameterType="int" resultMap="studentMap"> select s.id,s.name,c.id as cid,c.num as cnum from students s inner join cards c on s.cid = c.id and s.id = #{id} </select> </mapper>
<?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"> <!-- 名称空间namespace必须唯一 --> <mapper namespace="cardNamespace"> <!-- resultMap标签:映射实体与表 type属性:实体全路径名 id属性:为实体与表的映射取一个唯一的编号 --> <resultMap type="card" id="cardMap"> <!-- id标签:映射主键属性 result标签:映射非主键属性 property属性:实体属性名 column属性:表的字段名 --> <id property="cid" column="cid"/> <result property="cnum" column="cnum"/> </resultMap> </mapper>
<?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> <!-- 加载类路径下的属性文件 --> <properties resource="db.properties"> </properties> <!-- 设置类型别名 --> <typeAliases> <typeAlias type="com.jyk.mybatis.oneByone.Card" alias="card"/> <typeAlias type="com.jyk.mybatis.oneByone.Student" alias="student"/> </typeAliases> <!-- 设置一个默认的连接环境信息 --> <environments default="mysql_env"> <!-- 连接环境信息,取一个唯一的编号 --> <environment id="mysql_env"> <!-- mybatis使用的jdbc事务管理方式 --> <transactionManager type="jdbc"> </transactionManager> <!-- mybatis使用连接池方式来获取链接 --> <dataSource type="pooled"> <!-- 配置与数据库交互的四个属性 --> <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> </environments> <mappers> <mapper resource="com/jyk/mybatis/oneByone/StudentMapper.xml"/> <mapper resource="com/jyk/mybatis/oneByone/CardMapper.xml"/> </mappers> </configuration>
步骤4.编写Java代码实现该一对一查询
package com.jyk.mybatis.oneByone; import org.apache.ibatis.session.SqlSession; import com.jyk.mybatis.util.MyBatisUtil; public class StudentDao { /* * 根据ID查找 */ public Student findById(int id) { SqlSession sqlSession = null; try{ sqlSession = MyBatisUtil.getSqlSession(); Student stu = sqlSession.selectOne("studentNamespace.findById", id); return stu; }catch(Exception e){ e.printStackTrace(); throw e; }finally{ MyBatisUtil.closeSqlSession(); } } public static void main(String[] args) { StudentDao sd = new StudentDao(); Student stu = sd.findById(1); System.out.println("id=="+stu.getId()); System.out.println("name=="+stu.getName()); System.out.println("cid=="+stu.getCard().getCnum()); } }