1.什么是动态SQL
简单的说就是我们写的sql语句并不是固定不变的,是可以根据我们所传的参数的不同,而进行不同的查询
例如:我们有一张User表 进行如下操作 可以在UserDao.xml配置文件中进行如下配置
配置的前提是接口中要有对应的方法
public interface UserDao {
public User selectUserById(int id);
// 根据姓名和性别同时查询
public List<User> getUser(User u);
// 根据多个id查询一堆user
public List<User> selectUserByIds(List<Integer> ids);
}
(1.要根据姓名和性别进行查询
<!-- 如果有很多sql重复的 没有必要每次都写 可以对他进行抽取 --><sqlid="selectUser">
select * from User
</sql><selectid="getUser"parameterType="user"resultType="user"><includerefid="selectUser"/><!-- 执行内部逻辑并拼接到外部的sql中 会自动删除第一个and --><where><!-- if标签 --><iftest="name != null and name != ''">
and name = #{name}
</if><iftest="sex != null and sex != ''">
and sex = #{sex}
</if></where></select>
(2.要通过多个id查询各个id所对应的用户
<selectid="selectUserByIds"parameterType="java.util.List"resultType="user"><includerefid="selectUser"/> where
id in
<foreachcollection="list"item="item"separator=","open="("close=")">
#{item}
</foreach></select>
配置完成后就可以在测试类中调用session.getMapper(UserDao.class)方法进行测试
MyBatis的关联查询
1.一对多表关系
(1.建表 这里以User表(用户)和Orders表(订单)为例
(2.创建实体类 两张表都要有对应的实体类 类中属性最好与表中字段名一致
(3.首先接口中要有对应的方法
public interface UserDao {
// 查询所有user以及对应的orders
public List<User> selectUserAndOrders();
}
(4.在UserDao.xml配置文件中进行配置
<!-- 当数据库类名与实体类属性名不对应 就是用resultMap手动映射 --><resultMaptype="user"id="UserMap"autoMapping="true"><!-- 把o_name的值映射到name属性上 --><resultproperty="name"column="u_name"/><resultproperty="id"column="u_id"/><!-- 该标签用来映射关联对象 多对一使用association标签--><collectionproperty="orders"autoMapping="true"ofType="Orders"><resultproperty="name"column="o_name"/><resultproperty="id"column="o_id"/></collection></resultMap><selectid="selectUserAndOrders"resultType="user"resultMap="UserMap">
select *,Orders.name o_name, Orders.id o_id,User.id u_id,User.name u_name
from User LEFT JOIN Orders ON User.id = Orders.userid
</select>
(5.配置完成后在测试类中用session.getMapper(UserDao.class)方法测试
2.多对多表关系
(1.建表 这里以User表(客户)和Groups表(分组表)为例
(2.创建实体类 两张表都要有对应的实体类(类中要有保存关联对象的容器的属性)
(3.接口中又对应的方法 这里就不在写接口了
(4.配置文件中的配置(sql语句为:查询所有群组及其包含的用户)
<resultMaptype="Groups"id="GroupsMap"autoMapping="true"><idproperty="g_id"column="g_id"/><!-- 坑点:多对多查询时 如果完全使用自动映射
相同记录如果有不同的关联记录 会生成多个对象
我们希望的是 将关联的数据放到集合中而不是创建新的对象
解决方案: 手动映射任意一条记录
--><!-- <result property="g_id" column="g_id"/> --><collectionproperty="users"ofType="User"autoMapping="true"></collection></resultMap><selectid="selectAllGroups"resultMap="GroupsMap">
select *
from Groups left JOIN u_r_g ON Groups.g_id = u_r_g.gid
left join User on u_r_g.uid = User.id;
</select>
(5.测试类中调用getMapper()进行测试