select元素
1、statement的id属性配合Mapper的全限命名,组成一个唯一的标识,用于标识这条SQL。
2、parameterType表示这个statement接受的参数类型。
3、resultType表示返回结果,单条记录所映射的Java类型。
4、#{value}表示占位符,是被传递进去的参数。
5、${value}把传入的参数,拼接到SQL中。
6、编写SQL的时候,最后面一定不要加分号。
7、传递多个参数,可用Map或者List、JavaBean,也可以使用@param注解(不需要设定parameterType)。
8、flushCache表示是否刷新缓存。
占位符#{}
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行Java类型和JDBC类型转换,#{}可以有效防止SQL注入。#{}可以接收简单类型值或POJO属性值。如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
拼接符${}
${}表示拼接SQL串,通过${}可以将parameterType传入的内容拼接在SQL中且不进行Java类型和JDBC类型转换, ${}可以接收简单类型值或POJO属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
输出映射resultType
使用resultType进行输出映射时,只有查询出来的列名和POJO中属性名一致,该列才能映射成功。如果查询出来的列名和POJO中的属性名全部不一致,就不会创建POJO对象。只要查询出来的列名和POJO中的属性有一个一致,就会创建POJO对象。如果输出的结果只有一行一列,可以使用简单类型进行输出映射。不管输出POJO对象还是POJO对象的集合,resultType类型是一样的,只是在接口文件中的返回值不一样。生成的动态代理对象是根据返回值的类型来确定是调用selectone方法还是selectList方法。
输出映射resultMap
如果查询出来的列名和POJO的属性名不一致,可以通过定义一个resultMap队列名和POJO属性名之间作一个映射关系。查询的列名和POJO属性名不一致时,可以通过定义一个resultMap,对列名和POJO属性名之间做一个映射关系。当需要用到其他Mapper的resultMap时,需要加上namespace属性。
<resultMap type="com.feige.user" id="userResultMapper">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="hobby" property="hobby"/>
</resultMap>
分页RowBounds
Mybatis分页只能运用于小数据量的查询,原理是执行查询后,按照偏移量和限制条数返回查询结果。对于大量的数据查询,它的性能并不佳,需要用其它分页插件。
User findUserByName(String name, RowBounds rowBounds) throws Exception;
注:Mapper.xml中不需要任何关于RowBounds参数信息,Mybatis会自动识别它,并进行分页。
主键回填
数据库插入一条信息时,数据库会自动生成主键,有时候还需要这个主键关联其他业务。所以,获取这条插入数据的主键是很有必要的。我们想要的效果是,插入一条User记录,parameterType中User对象的id属性,会自动获取数据库插入的主键值。
一对一映射(一)
需求:查询订单关联查询用户,订单和用户是一对一关系。
第一步,在订单的类中,加入User这个属性。
public class Orders{
private String order_id;
private String order_num;
private User user;
......
第二步,定义Mappe.xml。
<resultMap type="orders" id="ordersUserresultMap">
<!--如果是联合主键,id属性为多个-->
<id column="order_id" property="order_id"/>
<result column="order_num" property="order_num"/>
<result column="user_id" property="user_id"/>
<association property="user" javaType="user">
<!--user_id是唯一标识用户的列,也就是外键-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersUserResultMap" resultMap="ordersUserresultMap">
select orders.* ,user.username, user.sex, user.address from orders,user where orders.user_id=user.id
</select>
第三步,定义Mappe.java。
public List<Orders> findOrdersUserResultMap() throws Exception;
一对一映射(二)
需求:查询订单关联查询用户,订单和用户是一对一关系。
第一步,定义视图类OrdersCustomVo.java。
public class OrdersCustomVo extends Orders{
private String username;
private String sex;
private String address;
......
第二步,定义视图类Mapper.xml。
<select id="findOrdersUser" resultType="ordersCustomVo">
select orders.* ,user.username, user.sex, user.address from orders,user where orders.user_id=user.id
</select>
第三步,定义Mappe.java。
public List<Orders> findOrdersUser() throws Exception;
总结:个人认为啊,一对一映射情况下使用resultType定义输出映射相对简单,因为这样只需要去添加一个POJO类就行了,按需求添加额外需要的属性,就可以完成映射。而相对于resultType来说,resultMap就显得稍微麻烦一些了。
一对多映射
需求:查询订单关联查询明细,订单和订单明细一对多关系。
第一步:在订单的类中加入明细属性。
public class Orders{
private String order_id;
private String order_num;
private User user;
private List<OrderDetails> orderDetails;
......
第二步:定义Mapper.xml。
<!--订单关联用户查询resultMap定义-->
<resultMap type="orders" id="ordersUserresultMap">
<!--配置映射的订单信息-->
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="createTime" property="createTime"/>
<result column="note" property="note"/>
<result column="updateTime" property="updateTime"/>
<association property="user" javaType="user">
<!--id标签:唯一标识用户的列也就是外键-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<!--使用extends继承了上面的resultMap定义-->
<resultMap type="orders" id="ordersAndOrdersDetailResultMap" extends="ordersUserresultMap">
<!--ofType这个list集合中对象的属性-->
<collection property="orderDetails" ofType="orderdetail">
<id column="ordersdetail_id" property="id"/>
<result column="item_id" property="item_id"/>
<result column="num" property="num"/>
</collection>
</resultMap>
<!--查询订单,用户,及订单明细,一对多查询-->
<select id="ResultMap" resultMap="ordersAndOrdersDetailResultMap">
select orders.* ,user.username, user.sex, user.address,ordersdetail.id ordersdetail_id,ordersdetail.item_id,ordersdetail.num
from orders,user,ordersdetail
where orders.user_id=user.id and ordersdetail.orders_id=orders.id
</select>
第三步:定义Mapper.java。
public List<Orders> selectOrders( ) throws Exception;
总结:为什么这个例子我们不用resultType来执行,其实结果早就给大家了,上面执行SQL的结果,实际上只有四个订单信息,但是使用resultType会返回8条信息,也就是没有完成去重(订单信息重复),还需要我们去手动去重,不是很方便。
多对多映射
需求:查询用户及用户所购买的商品信息。用户和订单一对多,订单和订单明细一对多,一对多是多对多的特例,查询用户和购买商品的关系中订单和订单明细是多对多关系。
第一步:映射思路。
1、将用户信息映射到User中。
2、在User类中添加订单列表属性Listorders。
3、在Orders类中添加订单明细列表属性,ListorderDetails。
4、在OrderDetail类中添加Item属性。
第二步:定义Mapper.xml。
<!--查询用户和商品的信息-->
<resultMap type="user" id="UserAndItemResultMap">
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!--定义订单信息,一个用户对应多个订单-->
<collection property="ordersList" ofType="orders">
<id column="id" property="id"/>
<result column="user_id" property="user_id"/>
<result column="number" property="number"/>
<result column="createTime" property="createTime"/>
<result column="note" property="note"/>
<result column="updateTime" property="updateTime"/>
<!--一个订单包含多个订单明细-->
<collection property="orderDetails" ofType="orderdetail">
<id column="ordersdetail_id" property="id"/>
<result column="item_id" property="item_id"/>
<result column="num" property="num"/>
<!--一个订单明细对应一个商品-->
<association property="items" javaType="items">
<id column="itemid" property="id"/>
<result column="itemname" property="itemname"/>
<result column="price" property="price"/>
</association>
</collection>
</collection>
</resultMap>
<!--查询用户及商品的信息,订单和订单明细是多对多关系-->
<select id="findUserAndItemResultMap" resultMap="UserAndItemResultMap">
select orders.* ,user.username, user.sex, user.address,ordersdetail.id ordersdetail_id,ordersdetail.item_id,
ordersdetail.num, items.id itemid,items.itemname, items.price from orders,user,ordersdetail,items
where orders.user_id=user.id and ordersdetail.orders_id=orders.id and items.id = ordersdetail.item_id
</select>
第三步:定义Mapper.java。
public List<User> findUserAndItemResultMap() throws Exception;