MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
一对一映射
在生活中,一对一的例子还是有的,比如啦,学生和身份证哦,或者在我国,实行的是一夫一妻制度哦。那么我们以学生和身份证每个学生只有一张身份证,而每张身份证的主人当然只有一个啦。
数据库脚本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
-- 删除数据库
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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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文件
1
2
3
4
5
6
7
8
9
|
<?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文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<?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文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
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中可以看出
1
|
<select id= "findById" parameterType= "integer" resultMap= "studentMap" >
|
MyBatis在解析这一句的时候只能将查询的数据封装到sid,sname中,所以怎么办?
在StudentMapper.xml中的
1
2
3
4
|
<resultMap type= "one2one.Card" id= "cardMap" >
<id column= "cid" property= "cid" />
<result column= "num" property= "num" />
</resultMap>
|
增加
1
2
3
4
5
|
<!--
引入CardMapper.xml文件中的映射信息
property表示Student的关联属性
-->
<association property= "card" resultMap= "cardNameSpace.cardMap" />
|
那么此时的StudentMapper.xml的完整内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<?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
2
3
4
5
6
7
|
//测试 查询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类中增加 查询“哈哈”学生的信息与身份证信息的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
/**
* 查询“哈哈”学生的信息与身份证信息
* @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
2
3
4
5
6
7
|
//测试 查询“哈哈”学生的信息与身份证信息
@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>配置信息
1
2
3
4
5
|
<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数据库脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
|
-- 删除数据库
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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
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文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
<?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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
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文件
1
2
3
4
5
6
7
8
9
|
<?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文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
<?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类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
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一对一映射初识教程,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://11841428.blog.51cto.com/11831428/1832270