mybatis注解开发-复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置<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>
标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
-
@One注解属性(取不同的值)介绍(注解内容的注解?)
- select: 指定多表查询的sqlmapper
- fetchType: 会覆盖全局的配置参数lazyLoadingEnable..
使用格式
@Result(column="", property="",one=@One(select=""))
4. Many注解(多对一)
代替了
<Collection>
标签,是多表查询的关键,在注解中来指定子查询返回对象集合。注意,聚集元素用来处理“一对多”的关系。需要指定映射的Java实体类的属性,属性的javaType(一般为ArrayList),但是注解中可以不定义。
- 使用格式
@Result(property="",column="",many=@Many(select=""))
公共配置
- 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>
- User pojo
private Integer userId;
private String userName;
private Date userBirthday;
private String userSex;
private String userAddress;
private List<Account> accounts;
- Account pojo
private Integer id;
private Integer uid;
private Double money;
private User user;
- 测试方法
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();
}
...
三、使用注解实现一对一复杂关系映射以及延迟加载
比如,账户信息和用户信息是多对一的关系,加载账户信息并且加载该账户的用户信息。
- 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();
- 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);
- 测试方法
List<Account> all = accountDao.findAll();
for (Account account : all) {
System.out.println(account);
System.out.println(account.getUser());
}
四、使用注解实现一对多复杂关系映射
user与account表示一对多的关系;查询用户信息时,也要查询关联的所有账户列表
- 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();
- 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);
- 测试方法
List<User> all = userDao.findAll();
for (User user : all) {
System.out.println(user);
System.out.println(user.getAccounts());
}
五、参数注解传递参数
- 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);
- 测试方法
/** 测试注解参数 */
@Test
public void testFindByNameAndAddr() {
List<User> users = userDao.findbyNameAndAddress("%王%", "%北京%");
for (User user : users) {
System.out.println(user);
}
}