【1】动态sql之if
UserMapper.xml中
if标签中是条件
<select id="findUser" parameterType="user" resultType="User">
select * from test03
<where>
<if test="username != null">
username=#{username}
</if>
<if test="password != null">
and password=#{password}
</if>
</where>
</select>
测试
@Test
public void test01(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUsername("张三");
user.setPassword("1232");
List<User> user1 = mapper.findUser(user);
for (User user2 : user1) {
System.out.println(user2);
}
}
【2】mybatis中一对一、一对多、多对一以及多对多的配置
一对一:账单对用户,一个账单对应一个用户,此时将账单作为主表,用户为从表,主表的实体类中需要聚合一个从表的引用。如果两个表涉及业务,则都需要对应一个Mapper接口与xml文件。
工程结构:
配置:
<?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">
<!--namespace 命名空间 其中内容为持久层接口全类名-->
<mapper namespace="com.jy.mapper.AccountMapper">
<!--建立起实体属性和表字段的对应关系-->
<resultMap id="accountVo" type="account">
<!--匹配主键字段-->
<id column="tid" property="tid"></id>
<!--匹配非主键字段-->
<result column="money" property="money"></result>
<result column="uid" property="uid"></result>
<!--配置一对一的关系-->
<!--association标签的property属性填主表实体类聚合的从表的引用-->
<association property="user" column="uid" javaType="user">
<id column="uid" property="uid"></id>
<result column="username" property="username"></result>
<result column="password" property="password"></result>
</association>
</resultMap>
<select id="findAccountAll" resultType="User" resultMap="accountVo">
select * from ts_account a left join tb_user u on a.uid=u.uid
</select>
</mapper>
一对多:用户对账单 一个用户对应多个账单,此时用户表为主表,在主表中聚合从表的集合引用
多对一:反过来,多个账单对应一个用户,一对多与多对一只是角度不同
UserMapper.xml
<?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">
<!--namespace 命名空间 其中内容为持久层接口全类名-->
<mapper namespace="com.jy.mapper.UserMapper">
<!--建立起实体属性和表字段的对应关系-->
<resultMap id="userVo" type="user">
<!--匹配主键字段-->
<id column="uid" property="uid"></id>
<!--匹配非主键字段-->
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<!--配置一对多的关系,此时不能用association,而是用collection-->
<!--
collection标签的property属性填主表实体类聚合的从表的集合引用
ofType 集合引用的泛型,即account全类名,因设置了别名,所以写account
-->
<collection property="accounts" ofType="account">
<!--匹配主键字段-->
<id column="tid" property="tid"></id>
<!--匹配非主键字段-->
<result column="money" property="money"></result>
<result column="uid" property="uid"></result>
</collection>
</resultMap>
<select id="getUserList" resultMap="userVo">
select * from tb_user u left join ts_account a on u.uid = a.uid
</select>
</mapper>
多对多:用户和角色,一个用户可以对应多个角色,一个角色也可以对应多个用户.所以各自要聚合另一张表的集合引用。
多对多在设计表结构的时候,需要指定一个中间表
查询时将用户表作为的主表,所以在UserMapper.xml 中进行配置,如果将角色表作为主表也可以
UserMapper.xml
<?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">
<!--namespace 命名空间 其中内容为持久层接口全类名-->
<mapper namespace="com.jy.mapper.UserMapper">
<!--建立起实体属性和表字段的对应关系-->
<resultMap id="userVo" type="user">
<!--匹配主键字段-->
<id column="uid" property="uid"></id>
<!--匹配非主键字段-->
<result column="username" property="username"></result>
<result column="password" property="password"></result>
<!--配置多对多的关系-->
<collection property="roles" ofType="role">
<!--匹配主键字段-->
<id column="rid" property="rid"></id>
<!--匹配非主键字段-->
<result column="role_name" property="roleName"></result>
</collection>
</resultMap>
<select id="getUserList" resultMap="userVo">
select u.*,r.* from tb_user u left join user_role ur on u.uid = ur.uid
left join tb_role r on r.rid = ur.rid
</select>
</mapper>
测试类
/**
* 多对多之查询用户的所有角色
*/
@Test
public void test04(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = mapper.getUserList();
for (User user : userList) {
System.out.println(user);
}
}
【3】懒加载(延迟加载)和立即加载
什么是延迟加载?
真正在使用数据时才发起查询,不用的时候不查询,按需加载(懒加载)
什么是立即加载?
不管用不用,一调用方法,马上发起查询
- 针对一对多和多对多:通常使用延迟加载
- 针对多对一和一对一:通常使用立即加载
例如上面的一对多:用户对账单
在查询用户数据时,有没有必要将账单数据带出?
没有必要,采用延迟加载策略
在查询账单数据时,有没有必要将用户数据带出?
有必要,因为查询账单时需要知道账单对应的用户是谁,采用延迟加载策略。
配置延迟加载,在mybatis-config.xml中,注意settings
标签写在typeAliase
之前
<settings>
<!--开启当前工程的延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
(1)一对一示例:
AccountMapper.xml中进行单表查询:
在一对一关系配置标签association
中设置select属性,关联UserMapper.xml中的方法
立即加载结果:日志中显示进行了多个表的查询
开启延迟加载结果:只查询了一张表
(2)一对多示例
UserMapper.xml中进行单表查询
在一对多关系配置标签collection
中设置select属性,关联AccountMapper.xml中的方法
立即加载结果:进行了多表查询
开启延迟加载:只查询了一张表