MyBatis一对一映射初识教程
mybatis是一个支持普通sql查询,存储过程和高级映射的优秀持久层框架。mybatis消除了几乎所有的jdbc代码和参数的手工设置以及对结果集的检索封装。mybatis可以使用简单的xml或注解用于配置和原始映射,将接口和java的pojo(plain old java objects,普通的java对象)映射成数据库中的记录。
一对一映射
在生活中,一对一的例子还是有的,比如啦,学生和身份证哦,或者在我国,实行的是一夫一妻制度哦。那么我们以学生和身份证每个学生只有一张身份证,而每张身份证的主人当然只有一个啦。
数据库脚本:
-- 删除数据库 drop database if exists mybaits; -- 创建数据库 create database if not exists mybatis default character set utf8; -- 选择数据库 use mybatis; -- 删除数据表 drop table if exists student ; drop table if exists card; -- 创建数据表 create table card( cid int(255), num varchar(18), constraint pk_cid primary key (cid) ); create table student( sid int(255), sname varchar(32), scid int(255), constraint pk_sid primary key (sid), constraint fk_scid foreign key (scid) references card(cid) ); -- 增加测试数据 insert into card (cid,num) values(1,'123456789012345678'); insert into student (sid,sname,scid) values(1,'哈哈',1);
新建一个one2one.card.java类
package one2one; import java.io.serializable; /** * 身份证 * @author administrator * */ @suppresswarnings("serial") public class card implements serializable{ private integer cid; private string num; public integer getcid() { return cid; } public void setcid(integer cid) { this.cid = cid; } public string getnum() { return num; } public void setnum(string num) { this.num = num; } }
新建one2one.student.java类
package one2one; import java.io.serializable; /** * 学生 * @author administrator * */ @suppresswarnings("serial") public class student implements serializable{ private integer sid; private string sname; private card card; public integer getsid() { return sid; } public void setsid(integer sid) { this.sid = sid; } public string getsname() { return sname; } public void setsname(string sname) { this.sname = sname; } public card getcard() { return card; } public void setcard(card card) { this.card = card; } }
在one2one包下新建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 type="one2one.card" id="cardmap"> <id column="cid" property="cid"/> <result column="num" property="num"/> </resultmap> </mapper>
同理,在one2one包下新建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 type="one2one.student" id="studentmap"> <id column="sid" property="sid"/> <result column="sname" property="sname"/> <!-- 关联字段不要写 --> </resultmap> <select id="findbyid" parametertype="integer" resultmap="studentmap"> select s.sid,s.sname,c.cid,c.num from student s,card c where s.scid = c.cid and s.sid = #{sid} </select> </mapper>
在src下新建一个mybatis.cfg.xml文件,并包含studentmapper.xml和cardmapper.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> <!-- 设置一个默认的环境信息 --> <environments default="mysql_developer"> <!-- 连接mysql环境信息 --> <environment id="mysql_developer"> <!-- mybatis使用jdbc事务管理器 --> <transactionmanager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接对象 --> <datasource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="com.mysql.jdbc.driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="mysqladmin"/> </datasource> </environment> <!-- 连接oracle环境信息 --> <environment id="oracle_developer"> <!-- mybatis使用jdbc事务管理器 --> <transactionmanager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接对象 --> <datasource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="oracle.jdbc.driver.oracledriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="scott"/> <property name="password" value="tiger"/> </datasource> </environment> </environments> <!-- 加载映射文件 --> <mappers> <mapper resource="one2one/cardmapper.xml"/> <mapper resource="one2one/studentmapper.xml"/> </mappers> </configuration>
在util包下新建一个工具类mybatisutil.java类
package util; import java.io.ioexception; import java.io.reader; import java.sql.connection; import org.apache.ibatis.io.resources; import org.apache.ibatis.session.sqlsession; import org.apache.ibatis.session.sqlsessionfactory; import org.apache.ibatis.session.sqlsessionfactorybuilder; public class mybatisutil { private static threadlocal<sqlsession> threadlocal = new threadlocal<sqlsession>(); public static sqlsessionfactory sqlsessionfactory ; //私有化构造方法 private mybatisutil(){} //加载位于src/mybatis.cfg.xml static{ try { reader reader = resources.getresourceasreader("mybatis.cfg.xml"); sqlsessionfactory=new sqlsessionfactorybuilder().build(reader); } catch (ioexception e) { e.printstacktrace(); } } /** * 获取sqlsession * @return */ public static sqlsession getsqlsession(){ //从当前线程中获取sqlsession对象 sqlsession sqlsession = threadlocal.get(); if(sqlsession == null){ if(sqlsessionfactory != null){ sqlsession = sqlsessionfactory.opensession(); //讲sqlsession与当前线程绑定在一起 threadlocal.set(sqlsession); } } return sqlsession; } /** * 关闭sqlsession 并与当前线程分开 */ public static void closesqlsession(){ //从当前线程中获取sqlsession对象 sqlsession sqlsession = threadlocal.get(); //如果sqlsession对象非空 if(sqlsession != null){ //关闭sqlsession对象 sqlsession.close(); //分离当前线程与sqlsession的关系 threadlocal.remove(); } } //测试 public static void main(string[] args) { sqlsession sqlsession = mybatisutil.getsqlsession(); connection conn= sqlsession.getconnection(); system.out.println(conn != null ?"连接成功":"连接失败"); } }
新建持久层类stuentcarddao.java类
package one2one; import org.apache.ibatis.session.sqlsession; import org.junit.test; import util.mybatisutil; /** * 持久层 * @author administrator * */ public class studentcarddao { /** * 查询1号学生的信息与身份证信息 * @param id * @return * @throws exception */ public student findbyid(integer id) throws exception{ sqlsession sqlsession = null; try { sqlsession = mybatisutil.getsqlsession(); return sqlsession.selectone("studentnamespace.findbyid", id); } catch (exception e) { e.printstacktrace(); throw e; }finally{ mybatisutil.closesqlsession(); } } //测试 查询1号学生的信息与身份证信息 @test public void testfindbyid() throws exception{ studentcarddao dao = new studentcarddao(); student student = dao.findbyid(1); system.out.println(student.getsid()+":"+student.getsname() } }
这时我们只能查询1号学生的姓名,但是我们不能去查询它的身份号号,因为此时的card属性的值为null,从studentmapper.xml中可以看出
<select id="findbyid" parametertype="integer" resultmap="studentmap">
mybatis在解析这一句的时候只能将查询的数据封装到sid,sname中,所以怎么办?
在studentmapper.xml中的
<resultmap type="one2one.card" id="cardmap"> <id column="cid" property="cid"/> <result column="num" property="num"/> </resultmap>
增加
<!-- 引入cardmapper.xml文件中的映射信息 property表示student的关联属性 --> <association property="card" resultmap="cardnamespace.cardmap"/>
那么此时的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 type="one2one.student" id="studentmap"> <id column="sid" property="sid"/> <result column="sname" property="sname"/> <!-- 引入cardmapper.xml文件中的映射信息 property表示student的关联属性 --> <association property="card" resultmap="cardnamespace.cardmap"/> </resultmap> <select id="findbyid" parametertype="integer" resultmap="studentmap"> select s.sid,s.sname,c.cid,c.num from student s,card c where s.scid = c.cid and s.sid = #{sid} </select> </mapper>
现在可以测试学生的身份证号码了
将持久层类stuentcarddao.java类的测试方法改为
//测试 查询1号学生的信息与身份证信息 @test public void testfindbyid() throws exception{ studentcarddao dao = new studentcarddao(); student student = dao.findbyid(1); system.out.println(student.getsid()+":"+student.getsname()+":"+student.getcard().getnum()); }
同理
在studentdao.java类中增加 查询“哈哈”学生的信息与身份证信息的方法
/** * 查询“哈哈”学生的信息与身份证信息 * @param name * @return * @throws exception */ public student findbyname(string name) throws exception{ sqlsession sqlsession = null; try { sqlsession = mybatisutil.getsqlsession(); return sqlsession.selectone("studentnamespace.findbyname", name); } catch (exception e) { e.printstacktrace(); throw e; }finally{ mybatisutil.closesqlsession(); } }
并增加测试方法哦
//测试 查询“哈哈”学生的信息与身份证信息 @test public void testfindbyname() throws exception{ studentcarddao dao = new studentcarddao(); student student = dao.findbyname("哈哈"); system.out.println(student.getsid()+":"+student.getsname()+":"+student.getcard().getnum()); }
当然如果你现在就测试,你会死的很惨,因为你没有在studentmapper.xml文件中配置<select>哦,所以在studentmapper.xml文件中增加<select>配置信息
<select id="findbyname" parametertype="string" resultmap="studentmap"> select s.sid,s.sname,c.cid,c.num from student s,card c where s.scid = c.cid and s.sname = #{sname} </select>
这样就可以测试成功了。大功告成。
完整代码如下:
mysql数据库脚本
-- 删除数据库 drop database if exists mybaits; -- 创建数据库 create database if not exists mybatis default character set utf8; -- 选择数据库 use mybatis; -- 删除数据表 drop table if exists student ; drop table if exists card; -- 创建数据表 create table card( cid int(255), num varchar(18), constraint pk_cid primary key (cid) ); create table student( sid int(255), sname varchar(32), scid int(255), constraint pk_sid primary key (sid), constraint fk_scid foreign key (scid) references card(cid) ); -- 增加测试数据 insert into card (cid,num) values(1,'123456789012345678'); insert into student (sid,sname,scid) values(1,'哈哈',1);
工具类mybatis.java类
package util; import java.io.ioexception; import java.io.reader; import java.sql.connection; import org.apache.ibatis.io.resources; import org.apache.ibatis.session.sqlsession; import org.apache.ibatis.session.sqlsessionfactory; import org.apache.ibatis.session.sqlsessionfactorybuilder; public class mybatisutil { private static threadlocal<sqlsession> threadlocal = new threadlocal<sqlsession>(); public static sqlsessionfactory sqlsessionfactory ; //私有化构造方法 private mybatisutil(){} //加载位于src/mybatis.cfg.xml static{ try { reader reader = resources.getresourceasreader("mybatis.cfg.xml"); sqlsessionfactory=new sqlsessionfactorybuilder().build(reader); } catch (ioexception e) { e.printstacktrace(); } } /** * 获取sqlsession * @return */ public static sqlsession getsqlsession(){ //从当前线程中获取sqlsession对象 sqlsession sqlsession = threadlocal.get(); if(sqlsession == null){ if(sqlsessionfactory != null){ sqlsession = sqlsessionfactory.opensession(); //讲sqlsession与当前线程绑定在一起 threadlocal.set(sqlsession); } } return sqlsession; } /** * 关闭sqlsession 并与当前线程分开 */ public static void closesqlsession(){ //从当前线程中获取sqlsession对象 sqlsession sqlsession = threadlocal.get(); //如果sqlsession对象非空 if(sqlsession != null){ //关闭sqlsession对象 sqlsession.close(); //分离当前线程与sqlsession的关系 threadlocal.remove(); } } //测试 public static void main(string[] args) { sqlsession sqlsession = mybatisutil.getsqlsession(); connection conn= sqlsession.getconnection(); system.out.println(conn != null ?"连接成功":"连接失败"); } }
mybatis.cfg.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> <!-- 设置一个默认的环境信息 --> <environments default="mysql_developer"> <!-- 连接mysql环境信息 --> <environment id="mysql_developer"> <!-- mybatis使用jdbc事务管理器 --> <transactionmanager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接对象 --> <datasource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="com.mysql.jdbc.driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="mysqladmin"/> </datasource> </environment> <!-- 连接oracle环境信息 --> <environment id="oracle_developer"> <!-- mybatis使用jdbc事务管理器 --> <transactionmanager type="jdbc"/> <!-- mybatis使用连接池方式来获取连接对象 --> <datasource type="pooled"> <!-- 配置与数据库交互的4个必要属性 --> <property name="driver" value="oracle.jdbc.driver.oracledriver"/> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/> <property name="username" value="scott"/> <property name="password" value="tiger"/> </datasource> </environment> </environments> <!-- 加载映射文件 --> <mappers> <mapper resource="one2one/cardmapper.xml"/> <mapper resource="one2one/studentmapper.xml"/> </mappers> </configuration>
card.java和student.java
package one2one; import java.io.serializable; /** * 身份证 * @author administrator * */ @suppresswarnings("serial") public class card implements serializable{ private integer cid; private string num; public integer getcid() { return cid; } public void setcid(integer cid) { this.cid = cid; } public string getnum() { return num; } public void setnum(string num) { this.num = num; } } package one2one; import java.io.serializable; /** * 学生 * @author administrator * */ @suppresswarnings("serial") public class student implements serializable{ private integer sid; private string sname; private card card; public integer getsid() { return sid; } public void setsid(integer sid) { this.sid = sid; } public string getsname() { return sname; } public void setsname(string sname) { this.sname = sname; } public card getcard() { return card; } public void setcard(card card) { this.card = card; } }
card.java的映射文件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 type="one2one.card" id="cardmap"> <id column="cid" property="cid"/> <result column="num" property="num"/> </resultmap> </mapper>
student.java类对应的映射文件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 type="one2one.student" id="studentmap"> <id column="sid" property="sid"/> <result column="sname" property="sname"/> <!-- 引入cardmapper.xml文件中的映射信息 property表示student的关联属性 --> <association property="card" resultmap="cardnamespace.cardmap"/> </resultmap> <select id="findbyid" parametertype="integer" resultmap="studentmap"> select s.sid,s.sname,c.cid,c.num from student s,card c where s.scid = c.cid and s.sid = #{sid} </select> <select id="findbyname" parametertype="string" resultmap="studentmap"> select s.sid,s.sname,c.cid,c.num from student s,card c where s.scid = c.cid and s.sname = #{sname} </select> </mapper>
持久层类studentcarddao.java类
package one2one; import org.apache.ibatis.session.sqlsession; import org.junit.test; import util.mybatisutil; /** * 持久层 * @author administrator * */ public class studentcarddao { /** * 查询1号学生的信息与身份证信息 * @param id * @return * @throws exception */ public student findbyid(integer id) throws exception{ sqlsession sqlsession = null; try { sqlsession = mybatisutil.getsqlsession(); return sqlsession.selectone("studentnamespace.findbyid", id); } catch (exception e) { e.printstacktrace(); throw e; }finally{ mybatisutil.closesqlsession(); } } /** * 查询“哈哈”学生的信息与身份证信息 * @param name * @return * @throws exception */ public student findbyname(string name) throws exception{ sqlsession sqlsession = null; try { sqlsession = mybatisutil.getsqlsession(); return sqlsession.selectone("studentnamespace.findbyname", name); } catch (exception e) { e.printstacktrace(); throw e; }finally{ mybatisutil.closesqlsession(); } } //测试 查询1号学生的信息与身份证信息 @test public void testfindbyid() throws exception{ studentcarddao dao = new studentcarddao(); student student = dao.findbyid(1); system.out.println(student.getsid()+":"+student.getsname()+":"+student.getcard().getnum()); } //测试 查询“哈哈”学生的信息与身份证信息 @test public void testfindbyname() throws exception{ studentcarddao dao = new studentcarddao(); student student = dao.findbyname("哈哈"); system.out.println(student.getsid()+":"+student.getsname()+":"+student.getcard().getnum()); } }
以上所述是小编给大家介绍的mybatis一对一映射初识教程,希望对大家有所帮助