<resultMap id="BaseResultMap" type="com.sf.gis.emergencytransport.entity.OrderCompany"> <id column="id" property="id" /> <result column="project_id" property="projectId" /> <result column="company_id" property="companyId" /> <result column="project_name" property="projectName" /> <result column="good_type" property="goodType" /> <result column="good_unit" property="goodUnit" /> </resultMap>
<select id="getCompanyOrderList" resultMap="BaseResultMap" >
select ep.name,op.type,op.unit,oc.*
from order_company oc
LEFT JOIN exp_project ep on ep.id = oc.project_id
LEFT JOIN order_company_product ocp on ocp.id = oc.order_product_id
left join order_product op on op.id = ocp.order_product_id
WHERE 1=1
<if test="projectName!=null and projectName !=''">
and ep.name = #{projectName}
</if>
<if test="order_no!=null and order_no !=''">
and oc.order_no = #{orderNo}
</if>
<if test="orderState!=null and orderState !=''">
and oc.order_state = #{orderState}
</if>
<if test="consignor!=null and consignor !=''">
and oc.consignor = #{consignor}
</if>
<if test="consignee!=null and consignee !=''">
and oc.consignee = #{consignee}
</if>
</select>
动态sql:
<select id="getUser" resultMap="u" parameterType="String"> select * from user2 <if test="address!=null and address !=''"> WHERE address LIKE concat('%',#{address},'%') </if> </select> public List<User> getUser(@Param("address") String address);
choose有点类似于Java中的switch,常常配合when和otherwise一起来使用 <select id="getUser2" resultMap="u"> SELECT * FROM user2 WHERE 1=1 <choose> <when test="id!=null"> AND id=#{id} </when> <when test="address!=null"> AND address=#{address} </when> <when test="username!=null"> AND user_name LIKE concat(#{username},'%') </when> <otherwise> AND 10>id </otherwise> </choose> </select>
<select id="getUser3" resultMap="u"> SELECT * FROM user2 <where> <choose> <when test="id!=null"> AND id=#{id} </when> <when test="address!=null"> AND address=#{address} </when> <when test="username!=null"> AND user_name LIKE concat(#{username},'%') </when> <otherwise> AND 10>id </otherwise> </choose> </where> </select>
<select id="getUser4" resultMap="u"> SELECT * FROM user2 <trim prefix="where" prefixOverrides="and"> AND id=1 </trim> </select>
<update id="update"> UPDATE user2 <set> <if test="username!=null"> user_name=#{username}, </if> <if test="password!=null"> password=#{password} </if> </set> WHERE id=#{id} </update>
<select id="getUserInCities" resultMap="u"> SELECT * FROM user2 WHERE address IN <foreach collection="cities" index="city" open="(" separator="," close=")" item="city"> #{city} </foreach> </select>
使用bind元素我们可以预先定义一些变量,然后在查询语句中使用 <select id="getUserByName" resultMap="u"> <bind name="un" value="username+'%'"></bind> SELECT* FROM user2 WHERE user_name LIKE #{un} </select>
mybatis缓存:
sqlsession 是connection更高级的封装
一级缓存:
系统默认开启一级缓存: 当我们获取到一个SqlSession对象之后,如果调用SqlSession中的同一个方法查询同一条数据, 那么第二次查询将不会去数据库中查询,因为第一次查询有缓存,直接调用缓存数据即可
二级缓存:
有的时候我们可能希望能够跨SqlSession进行数据缓存。 那么这个时候需要我们进行手动开启二级缓存。 只需要我们在userMapper.xml中配置<cache/>节点即可 <?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="org.sang.db.UserMapper"> <cache eviction="LRU" flushInterval="20000" size="1024" readOnly="true"/> <select id="getUser" resultType="org.sang.bean.User" parameterType="Long"> select * from user where id = #{id} </select> <insert id="insertUser" parameterType="org.sang.bean.User"> INSERT INTO user(username,password,address) VALUES (#{username},#{password},#{address}) </insert> <delete id="deleteUser" parameterType="Long"> DELETE FROM user where id=#{id} </delete> <select id="getAll" resultType="u"> SELECT * from user </select> </mapper>
开启二级缓存还要求我们的实体类可以序列化,实现Serializable接口即可 public class User implements Serializable{ private Long id; private String username; private String password; private String address; ... }
resultMap:
<resultMap> <constructor> <idArg/> <arg/> </constructor> <id/> <result/> <association property=""/> <collection property=""/> <discriminator javaType=""> <case value=""></case> </discriminator> </resultMap>
#association association是mybatis支持级联的一部分,我们知道在级联中有一对一、一对多、多对多等关系,association主要是用来解决一对一关系的 <resultMap id="provinceResultMapper" type="org.sang.bean.Province"> <id column="id" property="id"/> <association property="alias" column="id" select="org.sang.db.AliasMapper.findAliasByPid"/> </resultMap> <select id="getProvince" resultMap="provinceResultMapper"> SELECT * FROM province </select> public class Alias { private Long id; private String name; //省略getter/setter } public class Province { private Long id; private String name; private Alias alias; //省略getter/setter }
#collection collection是用来解决一对多级联的,还是上面那个例子,每个省份下面都会有很多城市 public class Province { private Long id; private String name; private Alias alias; private List<City> cities; //省略getter/setter } public class City { private Long id; private Long pid; private String name; //省略getter/setter } <resultMap id="provinceResultMapper" type="org.sang.bean.Province"> <id column="id" property="id"/> <association property="alias" column="id" select="org.sang.db.AliasMapper.findAliasByPid"/> <collection property="cities" column="id" select="org.sang.db.CityMapper.findCityByPid"/> </resultMap> <select id="findCityByPid" parameterType="long" resultType="org.sang.bean.City"> SELECT * FROM city WHERE pid=#{id} </select> <select id="getProvince" resultMap="provinceResultMapper"> SELECT * FROM province </select>
延迟加载: eager表示即时加载,lazy表示延迟加载 每次查询省份的时候都会去查询别名食物等表,有的时候我们可能并不需要这些数据但是却无可避免的要调用这个方法 <resultMap id="provinceResultMapper" type="org.sang.bean.Province"> <id column="id" property="id"/> <association property="alias" column="id" select="org.sang.db.AliasMapper.findAliasByPid" fetchType="eager"/> <collection property="cities" column="id" select="org.sang.db.CityMapper.findCityByPid" fetchType="lazy"/> <discriminator javaType="int" column="area"> <case value="1" resultMap="noodleResultMap"></case> <case value="2" resultMap="riceResultMap"></case> </discriminator> </resultMap> <resultMap id="noodleResultMap" type="org.sang.bean.Province" extends="provinceResultMapper"> <collection property="foods" column="area" select="org.sang.db.NoodleMapper.findNoodleByArea"/> </resultMap> <resultMap id="riceResultMap" type="org.sang.bean.Province" extends="provinceResultMapper"> <collection property="foods" column="area" select="org.sang.db.RiceMapper.findRiceByArea"/> </resultMap> <select id="getProvince" resultMap="provinceResultMapper"> SELECT * FROM province </select>
mybatis映射器配置细则:
select中字段的映射问题: <select id="getUser" resultType="user" parameterType="Long"> select * from user where id = #{id} </select> 如果sql返回字段与实体类字段不一致 <resultMap id="userMap" type="org.sang.bean.User"> <id property="id" column="id" javaType="long" jdbcType="NUMERIC"/> <result property="userName" column="user_name" javaType="string" jdbcType="VARCHAR"/> <result property="password" column="password" javaType="string" jdbcType="VARCHAR"/> <result property="address" column="address" javaType="string" jdbcType="VARCHAR"/> </resultMap>
select多条件查询 public ArrayList<User> getUserByAddressAndName2(Map<String,String> map); <select id="getUserByAddressAndName2" resultMap="userMap"> SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%') </select>
使用@param注解 public List<User> getUserByAddressAndName(@Param("username") String username, @Param("address") String address); <select id="getUserByAddressAndName" resultMap="userMap"> SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%') </select>
使用javaBean public class UserParams { private String username; private String address; //省略getter/setter } public ArrayList<User> getUserByAddressAndName3(UserParams params); <select id="getUserByAddressAndName3" resultMap="userMap" parameterType="org.sang.bean.UserParams"> SELECT * FROM user2 WHERE address=#{address} AND user_name LIKE concat(#{username},'%') </select>
insert中的主键回填 <insert id="insertUser" parameterType="u" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user2(user_name,password,address) VALUES (#{userName},#{password},#{address}) </insert> int i = userMapper.insertUser(user);
insert中主键自定义 <insert id="insertUser2" parameterType="u" useGeneratedKeys="true" keyProperty="id"> <selectKey keyProperty="id" resultType="long" order="BEFORE"> SELECT if(max(id) is null,1,max(id)+2) as newId FROM user3 </selectKey> INSERT INTO user3(id,user_name,password,address) VALUES (#{id},#{userName},#{password},#{address}) </insert>