Mybatis 学习笔记
Mybatis 学习笔记
mybatis 环境搭建
一对一
从表实体应该包含一个主表实体的对象引用
一对多(主表是一)
主表实体应该包含从表实体的集合引用
多对多
两个实体各种包含对方的一个集合引用
<resultMap id="roleMap" type="role">
<!--column 要和sql语句中一致;若起了别名 写成别名 property 和类中属性一致-->
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="userRecords" ofType="userRecord">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
</collection>
</resultMap>
懒加载 对应的四种表关系
-
一对多,多地多: 通常懒加载
-
多对一,一对一: 通常立即加载(多对一特殊的一对一 ,按一对一处理)
1.在SqlMapConfig.xml中配置setting标签
<settings> <!-- 配置全局懒加载--> <setting name="lazyLoadingEnabled" value="true"/> <setting name="aggressiveLazyLoading" value="false"/> </settings>
2.在IAccoutDao.xml中配置association标签
<!--定义封装account和user的resultMap-->
<resultMap id="accountUserMap" type="Account">
<id property="id" column="id"></id>
<!--用户id-->
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<!--一对一的关系映射,配置封装user的内容
select属性的内容,查询用户的唯一标识符
column属性的内容:用户根据id查询时,所需要参数的值-->
<association property="user" column="uid" javaType="User" select="com.daniel.dao.IUserDao.findById">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<result property="birthday" column="birthday"></result>
</association>
</resultMap>
<select id="findAll" resultMap="accountUserMap">
select * from account
</select>
注解方式
一对一
- account类
public class Account implements Serializable {
private int id;
private int uid;
private double money;
//一对一 一个账户属于一个用户
private User user;
}
- user类
public class User implements Serializable{
private int id;
private String username;
private String sex;
private String address;
private Date birthday;
//一对多 一个用户拥有多个账户
private List<Account> accounts;
}
- IAccountMapper
public interface IAccountMapper {
/**
* 查询所有的账户关联出查询用户
* @return
*/
@Select("select * from account")
@Results(id = "accountUserMap",value = {
@Result(id = true ,column = "id", property = "id"),
@Result(column = "uid" , property = "uid"),
@Result(column = "money" , property = "money"),
//一对一的配置 column 关联查询需要的字段(account类中的) property 在account中的名字
@Result(column = "uid" , property = "user" , one = @One(select = "com.mybatisannotation.mapper.IUserMapper.getUserById",fetchType = FetchType.EAGER))
})
List<Account> findAll();
/**
* 根据用户id 查询账户 使用上面定义返回结果集
* @return
*/
@Select("select * from account a where a.uid=#{id}")
//使用上面定义返回结果集
@ResultMap(value="accountUserMap")
List<Account> findAccountByUid(int id);
}
一对多 一个用户拥有多个账户
@CacheNamespace(blocking = true)//
public interface IUserMapper {
/**
* 一对多 一般用到懒加载 查询所有的用户关联查询到他包含的用户
*/
@Select("select *from user_table")
@Results(id="userMap",value = {
//id=true 说明这一行是主键
@Result(id = true , column = "id" ,property = "id"),/**其他字段如果数据库一致可以省略不写但是当时实体类为userName 数据库表中为 username 要写 @Result(column = "username",property = "userName"),建立对应映射关系 */
@Result(column = "id" , property = "accounts" ,
many = @Many(select = "com.mybatisannotation.mapper.IAccountMapper.findAccountByUid",fetchType = FetchType.LAZY))
})
List<User> getUserAccount();
}
多对多 用户和角色
一个用户含有多个角色 ,一个角色关联多个用户(关键点即findUserByRid,findRoleByUid)
- 用户类
package com.mybatisannotation.domain;
public class User implements Serializable{
private int id;
private String username;
private String sex;
private String address;
private Date birthday;
private List<Account> accounts;
private List<Role> roles;
}
- 角色类
public class Role implements Serializable {
private int roleId;
private String roleName;
private String roleDesc;
private List<User> users;
}
- 用户mapper
/**
* 根据角色id查询用户(用户角色关联的关键)
* @return
*/
@Select("select * from user_table where id in(select uid from user_role where rid=#{rid}) ")
List<User> findUserByRid(int rid);
/**
* 获取所有用户,并且关联查出角色
* @return
*/
@Select("select * from user_table")
@Results({
@Result(id = true , property = "id", column = "id"),
@Result(property = "roles" ,column = "id", many =@Many(select = "com.mybatisannotation.mapper.IRoleMapper.findRoleByUid") )
})
List<User> getAll();
- 角色mapper
/**
* 根据角色id查询用户
* @return
*/
@Select("select * from role where id in(select rid from user_role where uid=#{uid})")
@Results(id = "role",value = {
@Result(id = true,column = "id", property = "roleId"),
@Result(column = "role_name",property = "roleName"),
@Result(column = "role_desc",property = "roleDesc")
})
List<Role> findRoleByUid(int uid);
@Select("select * from role")
@Results(id = "roleUser",value = {
@Result(id = true,column = "id", property = "roleId"),
@Result(column = "role_name",property = "roleName"),
@Result(column = "role_desc",property = "roleDesc"),
@Result(column = "id",property = "users" ,many = @Many(select = "com.mybatisannotation.mapper.IUserMapper.findUserByRid",fetchType = FetchType.LAZY))
})
List<Role> findAll();
- 用户测试类
/**根据角色id查找用户*/
@Test
public void findUserByRid(){
List<User> users = userMapper.findUserByRid(1);
for (User user : users) {
System.out.println(user);
}
}
@Test
public void getAll(){
List<User> users = userMapper.getAll();
for (User user : users) {
System.out.println("dddddd "+user);
System.out.println(user.getRoles());
}
}
- 角色测试类
@Test
public void findRoleByUid(){
List<Role> roles = roleMapper.findRoleByUid(10);
for (Role role : roles) {
System.out.println(role);
}
}
@Test
public void findAll(){
List<Role> roles = roleMapper.findAll();
for (Role role : roles) {
System.out.println(role);
System.out.println("***----****");
System.out.println(role.getUsers());
}
}
注解开启二级缓存
哪个Dao接口需要就写在哪儿
@CacheNamespace(blocking = true) //如上的例子