if
查询的条件,有可能是用户名,有可能是性别,也有可能是地址,也有可能都没有
测试方法
@Test
public void testFindUserByCondition() throws Exception{
User user = new User();
user.setUsername("老王");
List<User> users = userDao.findUserByCondition(user);
System.out.println(users);
}
xml配置
<select id="findUserByCondition" parameterType="com.mmz.domain.User" resultType="com.mmz.domain.User">
select * from user
<where>
<if test="username != null">
username = #{username}
</if>
</where>
</select>
如果还有条件判断应该怎么处理呢
使用where标签,可以自动处理第一个and
foreach标签
当我们遇到这种sql语句应该怎么去做呢
sql标签
用sql定义,前面有个id值
在想要用的时候,有标签Include标签,refid填入 sql定义的id值
mybatis中的多表查询
表之间的关系有几种:
一对多
一对一
多对多
多对一
订单和用户就是多对一
用户和订单就是一对多
举例: 一个用户可以下多个订单
多个订单属于同一个用户
一对一
一个人只能有一个身份证号
身份证号只能对应一个人
老师与学生 多对多
一个学生可以被多个老师教过
一个老师可以教多个学生
mybatis中的多表查询
示例:用户和账户
一个用户只能有一个帐号
一个帐号只属于一个用户
多个帐号也可以属于一个用户
步骤
1、建立两张表:用户表,账户表
让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
2、建立两个实体类:用户实体类和账户实体类
让用户和账户的实体类体现一对多的关系
3、建立两个配置文件 用户的配置文件 账户的配置文件
4、实现配置,当我们查询用户时,可以得到用户下账户信息。
当我们查询账户时,可以同时得到账户的所属用户信息
完成初始配置文件
完成需求
/*
* 查询所有账户,同时还要获取到当前账户的用户信息
* */
由于account表与user表的id都是一样的字段
第二个id自动起了别名
用as起别名的方式
test方法
@Test
public void testfindAllAccount(){
//5.执行查询所有方法
List<AccountUser> accountUsers =accountDao.findAllAccount();
for (AccountUser accountuser:accountUsers
) {
System.out.println(accountuser);
}
}
以上是不常用的方法
property是最后映射到的数据段
column是查询到的数据段
<resultMap id="accooutUserMap" type="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
<association property="user" column="uid" javaType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</association>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="accooutUserMap">
select u.*,a.id as aid,a.uid,a.money from account a ,user u where u.id = a.uid
</select>
一定要在association标签中,添加javaType的属性值,要不然会报空指针异常
自我总结
一对一的查询,通过表单来获取用户信息,用户id算外键。首先定义把User放到Account pojo类中的一个属性。然后定义resultMap,id是以后想要引用resultMap的标识,返回类型resultType的值就是id type是最后封装到哪个类中,封装到account中,定义在account表中的主键,id就是主键,result就是其他的字段,column是查询时候的字段,也就是相当于sql语句的字段。property是映射的字段。
然后下个assocation是外键的字段,property就是映射到字段,column就是查询字段
association中还有id和result标签
一对多的查询
查询所有用户,同时获取用户下面所有的账户信息
<?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">
<mapper namespace="com.itheima.dao.IUserDao">
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 -->
<!--定义user的resultmap-->
<resultMap id="userAccountMap" type="user">
<id column="id" property="id" ></id>
<result property="username" column="username"></result>
<result property="address" column="address"></result>
<result property="sex" column="sex"></result>
<result property="birthday" column="birthday"></result>
<collection property="accounts" ofType="account">
<id column="aid" property="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
</collection>
</resultMap>
<!-- 查询所有 -->
<select id="findAll" resultMap="userAccountMap">
select * from user u left outer join account a on u.id = a.uid
</select>
<!-- 根据id查询用户 -->
<select id="findById" parameterType="INT" resultType="user">
select * from user where id = #{uid}
</select>
</mapper>
对多对要记住,原来是association这个标签,一对多应该换成collection这个标签
多对多
一个用户可以有多个角色
一个角色可以赋予多个用户
步骤:建立两张表:用户表,角色表,让用户表和角色表具有多对多的关系
需要使用中间表,中间表包含各自的主键,在中间表是外键
2、建立两个实体类:用户实体、角色实体
让用户和角色实体体现多对多的关系,各自实体类中包含对方集合引用
3、建立两个配置文件, 用户配置、角色配置
4、查询用户,可以得到用户下的角色信息,查询角色,可以得到角色所属用户信息
通过角色查询下面所有的用户
<?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">
<mapper namespace="com.itheima.dao.IRoleDao">
<resultMap id="roleMap" type="role">
<id property="roleId" column="rid"></id>
<result property="roleName" column="role_name"></result>
<result property="roleDesc" column="role_desc"></result>
<collection property="users" ofType="user">
<id column="id" property="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="roleMap">
select u.*,r.id as rid,r.role_name,r.role_desc from role r
left outer join user_role ur on r.id = ur.rid
left outer join user u on u.id = ur.uid
</select>
</mapper>
package com.itheima.test;
import com.itheima.dao.IRoleDao;
import com.itheima.dao.IUserDao;
import com.itheima.domain.Role;
import com.itheima.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;
/**
* @author 黑马程序员
* @Company http://www.ithiema.com
*
* 测试mybatis的crud操作
*/
public class RoleTest {
private InputStream in;
private SqlSession sqlSession;
private IRoleDao iRoleDao;
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession(true);
//4.获取dao的代理对象
iRoleDao = sqlSession.getMapper(IRoleDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
// sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
/**
* 测试查询所有
*/
@Test
public void testFindAll(){
//5.执行查询所有方法
List<Role> roles =iRoleDao.findAll();
for (Role role:roles
) {
System.out.println(role);
System.out.println(role.getUsers());
}
}
}