mybatis真正强大的地方,是可以灵活的运用sql语句进行查询。
在mapper映射文件中可以使用\
为了避免多次遇到同一段判断代码时的累赘,可以使用SQL片段来重复利用代码。
如下:
<sql id="thereissqlblock">
<if test="goods!=null and user!=null">
<if test="user.name!=null and user.name!='' ">
AND user.password=#{goods.price}
</if>
</if>
</sql>
<select id="selectUseIf" parameterType="userQuery" resultType="user">
SELECT * FROM USER
<where>
<include refid="thereissqlblock"></include>
</where>
</select>
具体分析:
if标签\<>里的test判断的是输入的参数的值,而\<>外则是相应的sql语句块(另外,#表示占位符,$为匹配符)。若不符合if test里的条件,则会执行select * from user,及不设置条件会查询出所有记录,若符合,则会把sql片段拼接到原语句。
foreach对应sql语句为:
SELECT * FROM USER WHERE userid=1 OR userid=2 OR userid=3
SELECT * FROM USER WHERE userid IN(1,2,3)
对于多个对象的输入查询,foreach可以解决遍历参数数组的问题。首先在参数对象中定义一个list集合并生成set和get方法,
private List<T> list;
//set和get方法
在mapper参数类型parameterType设置为list存放对象类型,接着:
<if test="users!=null">
<foreach collection="users" item="theuser" open="AND (" close=")" separator="or">
userid=#{theuser.userid}
</foreach>
</if>
使用:
User user1=new User();
User user2=new User();
user1.setUserid(1111);
user2.setUserid(1112);
List<User> users=new ArrayList<>();
users.add(user1);
users.add(user2);
userQuery.setUsers(users);
userMapper.selectForeach(userQuery).stream().forEach(System.out::println);
即可查出id为1111,1112的俩条记录。
定义表,orders:订单,custom:用户。外键关联
一个用户可发起多个订单,一个订单对应一个用户。
在对应类里添加属性。
orders:private Custom custom;
custom:private List\
订单对用户为一对一关系,则根据订单查用户有如下几种方法:
创建一个新类继承Orders,在该类里添加custom的属性并生成set和get方法。然后直接使用该类查询即可,实际应用中应该加上一个输入的参数ordersid这里我懒没加
<mapper namespace="com.me.mapper.OrdersMapper">
<select id="findCO" resultType="customOrders">
SELECT custom.*,orders.* FROM custom,orders WHERE orders.customid=custom.id
</select>
</mapper>
怎么解决2的问题呢?使用resultMap添加association标签关联即可解决
<resultMap type="orders" id="resultmap1">
<id column="orderid" property="orderid" />
<result column="thing" property="thing"/>
<result column="customid" property="customid"/>
<association property="custom" javaType="com.me.domain.Custom">
<id column="customid" property="id"/>
<result column="name" property="name"/>
<result column="nowdate" property="nowdate"/>
<result column="sex" property="sex"/>
</association>
</resultMap>
<select id="findCCO" resultMap="resultmap1">
SELECT orders.*,custom.* FROM custom,orders WHERE orders.customid=custom.id
</select>
这里,在resultMap里少添加或者在select后面少写一项属性,得到的对象属性就会少一项属性的值(所以不要偷懒少写属性)。
上面的一对一反过来,问题就变成了一对多,即一个custom对应多个orders。
对于一对多关系,我直接介绍最有效率的方法:
使用resultMap:
<resultMap type="custom" id="ccus">
<id column="id" property="id" />
<result column="name" property="name" />
<result column="nowdate" property="nowdate"/>
<result column="sex" property="sex"/>
<collection property="orders" ofType="com.me.domain.Orders">
<id column="order_id" property="orderid"/>
<result column="thing" property="thing" />
<result column="customid" property="customid"/>
</collection>
</resultMap>
<select id="selectCus" resultMap="ccus">
SELECT c.*,o.orderid order_id,o.thing,o.customid FROM custom c,orders o WHERE c.id=o.customid
</select>
注意这里是collection,执行后会把符合条件的orders一条一条映射到custom的list\
注意事项:如果关联表中有列名和主表列名相同,必须要设置别名,否则查询结果会有问题。