11.2 注解的使用示例2 一对一关联关系
目录结构
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
| E:\workspace_web2\MyAOneToOneTest ├─src │ ├─db.properties │ ├─domain │ │ ├─Card.java │ │ └─Person.java │ ├─fractory │ │ └─SqlSessionFratoryTools.java │ ├─log4j.xml │ ├─mapper │ │ ├─CardMapper.java │ │ └─PersonMapper.java │ ├─mybatis-config.xml │ ├─mybatis_tb_card_tb_person.sql │ └─test │ └─OneToOneTest.java └─WebContent ├─META-INF └─WEB-INF └─lib ├─ant-1.9.6.jar ├─ant-launcher-1.9.6.jar ├─asm-5.2.jar ├─cglib-3.2.5.jar ├─commons-logging-1.2.jar ├─javassist-3.22.0-CR2.jar ├─log4j-1.2.17.jar ├─log4j-api-2.3.jar ├─log4j-core-2.3.jar ├─mybatis-3.4.5.jar ├─mysql-connector-java-5.1.44-bin.jar ├─ognl-3.1.15.jar ├─slf4j-api-1.7.25.jar └─slf4j-log4j12-1.7.25.jar
|
创建数据库表
首先,给之前创建的mybatis
数据库创建两个表tb_card
和tb_person
,并插入测试数据。SQL
脚本如下使用方式:
保存成.sql
文件,然后使用Navicat
导入(设置编码格式utf-8
,免得乱码).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| DROP TABLE IF EXISTS `tb_card`; CREATE TABLE `tb_card` ( `id` int(11) NOT NULL AUTO_INCREMENT, `code` varchar(18) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `tb_card` VALUES ('1', '43280119980091');
DROP TABLE IF EXISTS `tb_person`; CREATE TABLE `tb_person` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(18) NOT NULL, `sex` varchar(18) NOT NULL, `age` int(11) DEFAULT NULL, `card_id` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `card_id` (`card_id`), CONSTRAINT `tb_person_ibfk_1` FOREIGN KEY (`card_id`) REFERENCES `tb_card` (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
INSERT INTO `tb_person` VALUES ('1', '小明', '男', '22', '1');
|
创建持久化类
Card.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package domain; public class Card { private Integer id; private String code; public Card() { } public Card(Integer id, String code) { this.id = id; this.code = code; } @Override public String toString() { return "Card [id=" + id + ", code=" + code + "]"; } }
|
Person.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package domain; public class Person { private Integer id; private String name; private String sex; private Integer age; private Card card; public Person() { super(); } @Override public String toString() { return "Person [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", card=" + card + "]"; } }
|
mapper接口
CardMapper接口
1 2 3 4 5 6 7
| package mapper; import org.apache.ibatis.annotations.Select; import domain.Card; public interface CardMapper { @Select("select * from tb_card where id=#{id}") Card selectCardById(Integer id); }
|
PersonMapper接口
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 mapper; import org.apache.ibatis.annotations.One; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.mapping.FetchType; import domain.Person; public interface PersonMapper { @Select("select * from tb_person where id=#{id}") @Results( {@Result( property = "id", column = "id", id = true ), @Result( property = "name", column = "name" ), @Result( property = "sex", column = "sex" ), @Result( property = "age", column = "age" ), @Result( property = "card", column = "card_id", one = @One( select = "mapper.CardMapper.selectCardByCardID", fetchType = FetchType.EAGER ) )} ) Person selectPersonById(@Param("id") Integer id); }
|
selectPersonById
方法使用了@Select
注解,其根据id
查询对应的Person
数据。因为需要将Person
对应的Card
数据也查询出来,所以Person
的Card
属性使用了一个@Result
结果映射。column="card_id"
,property="card"
表示Person
的Card
属性对应tb_person
表的card_id
列,one
属性表示是一个一对一关联关系,@one
注解的select
属性表示需要关联执行的SQL
语句,fetchType
表示查询的类型是立即加载(EAGER
)还是懒加载(LAZY
)。
测试类
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
| package test; import org.apache.ibatis.session.SqlSession; import domain.Person; import fractory.SqlSessionFratoryTools; import mapper.PersonMapper; public class OneToOneTest { public static void main(String[] args) { SqlSession sqlSession = null; try { sqlSession = SqlSessionFratoryTools.getSqlSession(); PersonMapper personMapper = sqlSession.getMapper(PersonMapper.class); Person person = personMapper.selectPersonById(1); System.out.println(person); sqlSession.commit(); } catch (Exception e) { sqlSession.rollback(); e.printStackTrace(); } finally { if (sqlSession != null) sqlSession.close(); } } }
|
运行效果
运行OneToOneTest
类的main
方法,该方法通过SqlSession
的getMapper(Class<T> type)
方法获得mapper
接口的代理对象PersonMapper
。调用PersonMapper
的selectPersonById
方法时会执行该方法上的注解。需要注意的是,Person
的一对一关联使用的注解@one
的select
属性,要执行的SQL
语句在CardMapper
接口的selectCardById
方法的注解中。控制台显示如
1 2 3 4 5 6 7
| DEBUG [main] ==> Preparing: select * from tb_person where id=? DEBUG [main] ==> Parameters: 1(Integer) DEBUG [main] ====> Preparing: select * from tb_card where id=? DEBUG [main] ====> Parameters: 1(Integer) DEBUG [main] <==== Total: 1 DEBUG [main] <== Total: 1 Person [id=1, name=小明, sex=男, age=22, card=Card [id=1, code=43280119980091]]
|
可以看到,查询Peson
信息时Person
对应的Card
对象也被查询出来了.
原文链接: 11.2 注解的使用示例2 一对一关联关系