MyBatis一對一映射初識(shí)教程
MyBatis是一個(gè)支持普通SQL查詢,存儲(chǔ)過程和高級映射的優(yōu)秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及對結(jié)果集的檢索封裝。MyBatis可以使用簡單的XML或注解用于配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數(shù)據(jù)庫中的記錄。
一對一映射
在生活中,一對一的例子還是有的,比如啦,學(xué)生和身份證哦,或者在我國,實(shí)行的是一夫一妻制度哦。那么我們以學(xué)生和身份證每個(gè)學(xué)生只有一張身份證,而每張身份證的主人當(dāng)然只有一個(gè)啦。
數(shù)據(jù)庫腳本:
-- 刪除數(shù)據(jù)庫 drop database if exists mybaits; -- 創(chuàng)建數(shù)據(jù)庫 create database if not exists mybatis default character set utf8; -- 選擇數(shù)據(jù)庫 use mybatis; -- 刪除數(shù)據(jù)表 drop table if exists student ; drop table if exists card; -- 創(chuàng)建數(shù)據(jù)表 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) ); -- 增加測試數(shù)據(jù) insert into card (cid,num) values(1,'123456789012345678'); insert into student (sid,sname,scid) values(1,'哈哈',1);
新建一個(gè)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; /** * 學(xué)生 * @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"/> <!-- 關(guān)聯(lián)字段不要寫 --> </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下新建一個(gè)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> <!-- 設(shè)置一個(gè)默認(rèn)的環(huán)境信息 --> <environments default="mysql_developer"> <!-- 連接MySQL環(huán)境信息 --> <environment id="mysql_developer"> <!-- MyBatis使用jdbc事務(wù)管理器 --> <transactionManager type="jdbc"/> <!-- MyBatis使用連接池方式來獲取連接對象 --> <dataSource type="pooled"> <!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 --> <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環(huán)境信息 --> <environment id="oracle_developer"> <!-- MyBatis使用jdbc事務(wù)管理器 --> <transactionManager type="jdbc"/> <!-- MyBatis使用連接池方式來獲取連接對象 --> <dataSource type="pooled"> <!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 --> <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包下新建一個(gè)工具類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 ; //私有化構(gòu)造方法 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(){ //從當(dāng)前線程中獲取SqlSession對象 SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ if(sqlSessionFactory != null){ sqlSession = sqlSessionFactory.openSession(); //講sqlSession與當(dāng)前線程綁定在一起 threadLocal.set(sqlSession); } } return sqlSession; } /** * 關(guān)閉SqlSession 并與當(dāng)前線程分開 */ public static void closeSqlSession(){ //從當(dāng)前線程中獲取SqlSession對象 SqlSession sqlSession = threadLocal.get(); //如果SqlSession對象非空 if(sqlSession != null){ //關(guān)閉SqlSession對象 sqlSession.close(); //分離當(dāng)前線程與SqlSession的關(guān)系 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號學(xué)生的信息與身份證信息 * @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號學(xué)生的信息與身份證信息 @Test public void testFindById() throws Exception{ StudentCardDAO dao = new StudentCardDAO(); Student student = dao.findById(1); System.out.println(student.getSid()+":"+student.getSname() } }
這時(shí)我們只能查詢1號學(xué)生的姓名,但是我們不能去查詢它的身份號號,因?yàn)榇藭r(shí)的card屬性的值為null,從StudentMapper.xml中可以看出
<select id="findById" parameterType="integer" resultMap="studentMap">
MyBatis在解析這一句的時(shí)候只能將查詢的數(shù)據(jù)封裝到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的關(guān)聯(lián)屬性 --> <association property="card" resultMap="cardNameSpace.cardMap"/>
那么此時(shí)的StudentMapper.xml的完整內(nèi)容如下:
<?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的關(guān)聯(lián)屬性 --> <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>
現(xiàn)在可以測試學(xué)生的身份證號碼了
將持久層類StuentCardDAO.java類的測試方法改為
//測試 查詢1號學(xué)生的信息與身份證信息 @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類中增加 查詢“哈哈”學(xué)生的信息與身份證信息的方法
/** * 查詢“哈哈”學(xué)生的信息與身份證信息 * @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(); } }
并增加測試方法哦
//測試 查詢“哈哈”學(xué)生的信息與身份證信息 @Test public void testFindByName() throws Exception{ StudentCardDAO dao = new StudentCardDAO(); Student student = dao.findByName("哈哈"); System.out.println(student.getSid()+":"+student.getSname()+":"+student.getCard().getNum()); }
當(dāng)然如果你現(xiàn)在就測試,你會(huì)死的很慘,因?yàn)槟銢]有在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數(shù)據(jù)庫腳本
-- 刪除數(shù)據(jù)庫 drop database if exists mybaits; -- 創(chuàng)建數(shù)據(jù)庫 create database if not exists mybatis default character set utf8; -- 選擇數(shù)據(jù)庫 use mybatis; -- 刪除數(shù)據(jù)表 drop table if exists student ; drop table if exists card; -- 創(chuàng)建數(shù)據(jù)表 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) ); -- 增加測試數(shù)據(jù) 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 ; //私有化構(gòu)造方法 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(){ //從當(dāng)前線程中獲取SqlSession對象 SqlSession sqlSession = threadLocal.get(); if(sqlSession == null){ if(sqlSessionFactory != null){ sqlSession = sqlSessionFactory.openSession(); //講sqlSession與當(dāng)前線程綁定在一起 threadLocal.set(sqlSession); } } return sqlSession; } /** * 關(guān)閉SqlSession 并與當(dāng)前線程分開 */ public static void closeSqlSession(){ //從當(dāng)前線程中獲取SqlSession對象 SqlSession sqlSession = threadLocal.get(); //如果SqlSession對象非空 if(sqlSession != null){ //關(guān)閉SqlSession對象 sqlSession.close(); //分離當(dāng)前線程與SqlSession的關(guān)系 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> <!-- 設(shè)置一個(gè)默認(rèn)的環(huán)境信息 --> <environments default="mysql_developer"> <!-- 連接MySQL環(huán)境信息 --> <environment id="mysql_developer"> <!-- MyBatis使用jdbc事務(wù)管理器 --> <transactionManager type="jdbc"/> <!-- MyBatis使用連接池方式來獲取連接對象 --> <dataSource type="pooled"> <!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 --> <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環(huán)境信息 --> <environment id="oracle_developer"> <!-- MyBatis使用jdbc事務(wù)管理器 --> <transactionManager type="jdbc"/> <!-- MyBatis使用連接池方式來獲取連接對象 --> <dataSource type="pooled"> <!-- 配置與數(shù)據(jù)庫交互的4個(gè)必要屬性 --> <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; /** * 學(xué)生 * @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類對應(yīng)的映射文件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的關(guān)聯(lián)屬性 --> <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號學(xué)生的信息與身份證信息 * @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(); } } /** * 查詢“哈哈”學(xué)生的信息與身份證信息 * @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號學(xué)生的信息與身份證信息 @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()); } //測試 查詢“哈哈”學(xué)生的信息與身份證信息 @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一對一映射初識(shí)教程,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對腳本之家網(wǎng)站的支持!
相關(guān)文章
導(dǎo)致MyEclipse內(nèi)存不足的原因分析及解決辦法
這篇文章主要介紹了導(dǎo)致MyEclipse內(nèi)存不足的原因分析及解決辦法的相關(guān)資料,需要的朋友可以參考下2016-01-01Java和JVM的重載識(shí)別,重寫方法是怎樣進(jìn)行的
這篇文章主要介紹了Java和JVM的重載識(shí)別,重寫方法是怎樣進(jìn)行的,違章圍繞了Java和JVM的重載識(shí)別,重寫方法展開相關(guān)資料,需要的小伙伴可以參考一下,希望對你的工作或?qū)W習(xí)有所幫助2022-01-01springboot后端配置多個(gè)數(shù)據(jù)源、Mysql數(shù)據(jù)庫的便捷方法
實(shí)現(xiàn)springboot 后端配置多個(gè)數(shù)據(jù)源、Mysql數(shù)據(jù)庫,只需要新建 Mapper、實(shí)體類 相應(yīng)的文件夾,將不同數(shù)據(jù)源的文件保存到對應(yīng)的文件夾下,添加綁定數(shù)據(jù)庫配置Config,就可以輕松完成2021-08-08SpringBoot Shiro 權(quán)限注解不起作用的解決方法
本文主要介紹了SpringBoot Shiro 權(quán)限注解不起作用的解決方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-07-07java8 stream 由一個(gè)list轉(zhuǎn)化成另一個(gè)list案例
這篇文章主要介紹了java8 stream 由一個(gè)list轉(zhuǎn)化成另一個(gè)list案例,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08