12.mybatis注解开发-复杂映射开发

mybatis注解开发-复杂映射开发


mybatis测试表结构.png

实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。

一、复杂关系映射的注解

1. @Results注解

该注解代替的是标签<resultMap>;该注解中可以使用单个@Result注解,也可以使用@Result集合

@Results(@Result)

# 或者

@Results({
    @Result(),
    @Result()
})

2. @Result注解

代替了<id>标签和<result>标签;@Result中属性介绍如下

属性 描述
id 是否为主键字段
column 数据库查询出的列名
property 需要装配的属性名
one 需要使用的@One注解 @Result(one=@One)
many 需要使用的@Many注解 @Result(many=@many)

3. @One注解(一对一)

代替了<association>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。

  1. @One注解属性(取不同的值)介绍(注解内容的注解?)

    • select: 指定多表查询的sqlmapper
    • fetchType: 会覆盖全局的配置参数lazyLoadingEnable..
  2. 使用格式

@Result(column="", property="",one=@One(select=""))

4. Many注解(多对一)

代替了<Collection>标签,是多表查询的关键,在注解中来指定子查询返回对象集合。注意,聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList),但是注解中可以不定义。

  1. 使用格式
@Result(property="",column="",many=@Many(select=""))

公共配置

  1. SqlMapConfig.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>
    <properties resource="JdbcConfig.properties"></properties>
    <typeAliases>
        <package name="com.itheima.domain"></package>
    </typeAliases>
    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 配置dao接口的位置
     1. 使用mapper标签配置class属性
     2. 使用package标签,直接指定dao接口所在的包
     -->
    <mappers>
        <package name="com.itheima.dao"></package>
    </mappers>
</configuration>
  1. User pojo
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;

private List<Account> accounts;
  1. Account pojo
private Integer id;
private Integer uid;
private Double money;

private User user;
  1. 测试方法
InputStream in;
       SqlSessionFactory factory;
       SqlSession session;
       AccountDao accountDao;
       UserDao userDao;

       @Before
       public void init() throws Exception {
           in = Resources.getResourceAsStream("SqlMapConfig.xml");
           factory = new SqlSessionFactoryBuilder()
                   .build(in);
           session = factory.openSession();
           accountDao = session.getMapper(AccountDao.class);
       }

       @After
       public void destroy() throws Exception {
           session.commit();
           session.close();
           in.close();
       }
       ...

三、使用注解实现一对一复杂关系映射以及延迟加载

比如,账户信息和用户信息是多对一的关系,加载账户信息并且加载该账户的用户信息。

  1. AccountDao 接口方法 findAll
/** 查询所有账户,采用延迟加载的方式查询账户的所属用户 */

@Select("select * from account")
@Results(id="accountMap",
    value = {
            @Result(id=true, column = "id", property = "id"),
            @Result(column = "uid", property = "uid"),
            @Result(column = "money", property = "money"),
            @Result(column = "uid", property = "user",
                    one = @One(select = "com.itheima.dao.UserDao.findById",
                                fetchType = FetchType.LAZY // 懒加载
                    )
            )
    }
)
List<Account> findAll();
  1. UserDao中的接口方法 findById
/** 根据id查询一个用户 */
@Select("select * from user where id = #{uid}")
@Results(id="userMap",
        value = {
                @Result(id=true, column="id",property = "userId"),
                @Result(column = "username", property = "userName"),
                @Result(column = "sex", property = "userSex"),
                @Result(column = "address", property = "userAddress"),
                @Result(column = "birthday", property = "userBirthday")
        })
User findById(Integer userId);
  1. 测试方法
List<Account> all = accountDao.findAll();
for (Account account : all) {
    System.out.println(account);
    System.out.println(account.getUser());
}

四、使用注解实现一对多复杂关系映射

user与account表示一对多的关系;查询用户信息时,也要查询关联的所有账户列表

  1. UserDao 接口方法 findAll
/** 查询所有用户 */
@Select("select * from user")
@Results(id="userMap",
        value = {
                @Result(id=true, column="id",property = "userId"),
                @Result(column = "username", property = "userName"),
                @Result(column = "sex", property = "userSex"),
                @Result(column = "address", property = "userAddress"),
                @Result(column = "birthday", property = "userBirthday"),
                @Result(column = "id", property = "accounts",
                        many = @Many(
                                select = "com.itheima.dao.AccountDao.findByUid",
                                fetchType = FetchType.LAZY // 懒加载
                        )
                )
        })
List<User> findAll();
  1. AccountDao 接口方法 findByUid
@Select("select * from account")
@Results(id="accountMap",
    value = {
            @Result(id=true, column = "id", property = "id"),
            @Result(column = "uid", property = "uid"),
            @Result(column = "money", property = "money"),
            @Result(column = "uid", property = "user",
                    one = @One(select = "com.itheima.dao.UserDao.findById",
                                fetchType = FetchType.LAZY
                    )
            )
    }
)
List<Account> findAll();

@Select("select * from account where uid = #{uid}")
@ResultMap("accountMap")
List<Account> findByUid(Integer uid);
  1. 测试方法
List<User> all = userDao.findAll();
for (User user : all) {
    System.out.println(user);
    System.out.println(user.getAccounts());
}

五、参数注解传递参数

  1. UserDao 接口方法
/** 注解参数案例 */
@Select("select * from user where username like #{pName} and address like #{pAddr}")
@ResultMap("userMap") // 复用上面【四】的ResultMap,而且还有懒加载功能
List<User> findbyNameAndAddress(@Param("pName") String name, @Param("pAddr") String address);
  1. 测试方法
/** 测试注解参数 */
@Test
public void testFindByNameAndAddr() {
    List<User> users = userDao.findbyNameAndAddress("%王%", "%北京%");
    for (User user : users) {
        System.out.println(user);
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,463评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,868评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,213评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,666评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,759评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,725评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,716评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,484评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,928评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,233评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,393评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,073评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,718评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,308评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,538评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,338评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,260评论 2 352

推荐阅读更多精彩内容