mybatis 语句

1. 参数传递

$与#的区别
1.$号只能读取对象里面的属性值,并且是通过getter方法读取
2.#会对传递的参数加上引号,$号不会  $会有sql注入问题
    如果作为对象传递进去,需要指定参数类型,就可以直接获取属性,map也是对象,,如果使用@param进行标记,获取属性就需要使用类。属性来获取,,

1.第一种方式 匿名参数 顺序传递参数0 ,1 或者arg0 arg1 或者param1 param2
	List<Employee> selectByGenderAndAge(Short gender,String age );
<select id="selectByGenderAndAge" resultMap="BaseResultMap" >
	select *  from employee where gender = #{param1} and age = #{param2}
</select>

第二种方式 使用@Param注解 按照参数名引用
	List<Employee> selectByGenderAndAge( @Param("gender") Short gender,@Param("age") String age );
<select id="selectByGenderAndAge" resultMap="BaseResultMap" >
	select * from employee where gender = #{gender} and age = #{age}
</select>

3.使用Map传递参数,k为名称,v存执 可以直接引用k 
    Map params = new HashMap<>();
    params.put("gender",gender);
    params.put("age",age);

    List result= employeeMapper.selectByMapParams(params);
List<Employee> selectByMapParams(Map params);
<select id="selectByMapParams" resultMap="BaseResultMap" parameterType="map">
  select * from employee
    where gender = #{gender} and age = #{age}
</select>

   如果要使用map中的k 和value 都作为参数,使用foech遍历
    
    
4.用过java bean传递多个参数,使用时parameterType指定为对应的bean类型即可,可以在mybatis.xml配置文件中配置别名,一般配置包,直接实用类名即可
	List <Employee> selectByBeans(Employee employee);
<select id="selectByBeans" resultMap="BaseResultMap" parameterType="com.wg.demo.po.Employee">
  select *
  from employee where gender = #{gender} and age = #{age}
</select>

  
5.直接使用JSON传递参数,如果传来的是Bean对象转成的json,可以直接使用,参数类型使用json解析器中的类
    List <Employee> findByJSONObject(JSONObject params);
<select id="findByJSONObject" resultMap="BaseResultMap" parameterType="com.alibaba.fastjson.JSONObject">
  select  *
  from employee where gender = #{gender} and age = #{age}
</select>

    
6.传递集合类型参数List、Set、Array 通过forech 遍历
    List <Employee> findByList(List list);
<select id="findByList" resultMap="BaseResultMap" >
    SELECT * from employee where age in
    <foreach collection="list" open="(" separator="," close=")" item="age">
    	#{age}
	</foreach>
</select>

主键返回的方法

1.自增主键

<!--
        useGeneratedKeys:是否返回主键
        keyProperty:主键返回了给User哪个属性
        keyColumn:指定列   插入过后 获得uid这一列的值 作为主键返回 赋值给User对象的uid属性
    -->
    <insert id="insert" parameterType="cn.cdqf.pojo.User" useGeneratedKeys="true" keyProperty="uid"
     keyColumn="uid">
        insert into mybaties2 (uname,age) values(#{uname},#{age})
    </insert>
--------------------------------------------------------------------
public void insert() {
        User user = new User("zhangsan", 25);
        SqlSession sqlSession = SqlSessionUtil.sqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        int insert = userDao.insert(user);

        sqlSession.commit();
        System.out.println("insert = " + user.getUid());
        SqlSessionUtil.close(sqlSession);
    }

2. 非自增主键

非自增主键需要在执行insert sql之前指定一个主键值 给要插入的记录,
<insert id="insert" parameterType="cn.cdqf.pojo.User">
        <!--order:在数据插入前 还是插入后
               oracle:before
                   序列号(类似于在java里面写一个生成id的方法),不在表里面生成
                   插入数据库之前就会触发序列号自增,先插入了再去拿,
                   A:想插入数据  先去拿id 10
                   B:像插入 拿到11
               Mysql:插入过程生成id after ,如果使用before 要注意,如果是新的connection并且第一次插入,获取的主键是零
        -->
                   //keyColumn 主键, keyProperty返回给对象的哪个属性 resultType根据表中的填
        <selectKey keyColumn="uid" keyProperty="uid" resultType="int" order="AFTER">
            select last_insert_id();<!--获得当前mysql的这个库最后一次插入数据库自增的id-->
        </selectKey>
        insert  into user(uname) values(#{uname})
    </insert>
--------------------------------------------------------------------
public void insert() {
        User user = new User("zhangsan", 25);
        SqlSession sqlSession = SqlSessionUtil.sqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        int insert = userDao.insert(user);

        sqlSession.commit();
        System.out.println("insert = " + user.getUid());
        SqlSessionUtil.close(sqlSession);
    }
                    

mybais转义

xml中写uid<{uid}报错 认为是标签的开头 使用<![CDATA[代码]]>  进行包裹转义
<![CDATA[代码]]>

常见标签

//test中条件满足 ,if标签中的sql语句才会出现
<if test="name!=null and name!=''"></if> :里面的条件满足才执行标签里面sql语句


//where标签,给语句开头加上where关键字 并且去掉第一个and
如果名字不为空或者不为空字符串,则根据名字模糊查询,age不为空且大于零 就看年龄大于传入值查询
	<select id="queryByNameAndAge" resultType="cn.dream.pojo.User">
        select * from mybaties2
        <where>
            <if test="name!=null and name != '' ">
               and uname like concat('%',#{name},'%')
            </if>
            <if test="age != null and age>0">
                and age>#{age}
            </if>
        </where>
    </select>




//<set></set> 开头加上加上set关键字 去掉末尾的, 
     <update id="set1" parameterType="User">
         update mybaties2
         <set>
             <if test="user.uname!=null">
                 uname=#{user.uname},
             </if>
             <if test="user.age != null" >
                 age=#{user.age},
             </if>
         </set>
         where uid=#{user.uid}
    </update>


//<trim></trim>     prefix前 suffix 后 加关键字  ;或者 prefixOverrides   suffixOverrides覆盖掉前后多余某个字符
    <select id="queryByNameAndAge" resultType="user" >
        select <include refid="BaseSql"></include> from mybaties2
        <trim prefix="where" prefixOverrides="and" >
            <if test="name!=null and name != '' ">
                and uname like concat('%',#{name},'%')
            </if>
            <if test=" age != null and age!=''">
                and age > #{age}
            </if>
        </trim>
    </select>


//<choose><when>A</when><otherwise>B</otherwise></choose> when条件满足执行A 否则执行B
    <select id="queryByNameAndAge2" resultType="cn.dream.pojo.User">
        <bind name="aa" value="'%'+uname+'%'"/>
        select * from mybaties2
        <where>
            <choose>
                <when test="uname!=null and uname!=''" >
                    uname like #{aa}
                </when>
                <otherwise>
                    and age>#{age}
                </otherwise>
            </choose>
        </where>
    </select>

#把%uname参数 %拼接起来赋值给aaa  使用就只需要#{aaa} ,方便拼接
<bind name="aaa" value="'%'+uname+'%'"/>
    
 #相当于定义一个sql语句可以多出引用    
<sql id='a'>定义sql</sql>  其它地方直接使用<include refid='a'></include>
       


//<foreach></foreach> 集合数组 map//使用方法类似jsp中的el表达式

    

	//数组集合
    List<User> userList = Arrays.asList(new User("张三", 20), new User("liming", 60));   
     <update id="batchInsert">
        INSERT INTO mybaties2 (uname,age) values
        <foreach collection="values" item="user" separator=",">
             (#{user.uname},#{user.age})
        </foreach>
    </update>      

      
    //使用map中的key和value
      void  batchInsert2(@Param("map") Map<String,Object> map);  
     <insert id="batchInsert2">
            insert into mybaties2 (uname,age) values
            <foreach collection="map" index="key" item="value" separator="," >
                (#{key},#{value})
            </foreach>
      </insert> 
        
      //map使用value 
         <foreach collection="map.values"  item="key" separator="," >
            (#{key}
        </foreach>

ResulltMap结果映射

如果Bean的属性名与数据库中不一致,直接查询属性值会设置不进去

解决方法1

通过查询时给字段取别名,这样查询出来的字段就与属性名一致了

2.ResultMap映射

属性与字段名不匹配

<resultMap id="BaseMap1" type="Student">
  <id column="s_id" property="sId"></id>
  <result column="s_name" property="sName"></result>
  <result column="t_id" property="tId"></result>
</resultMap>   

一对一

//一个学生对应一个老师
<resultMap id="BaseMap1" type="Student">
  <id column="s_id" property="sId"></id>
  <result column="s_name" property="sName"></result>
  <result column="t_id" property="tId"></result>
  <association property="teacher" javaType="Teacher">
    <id column="t_id" property="tId"></id>
    <result column="t_name" property="tName"></result>
    <result column="sex" property="sex"></result>
    <result column="salary" property="salary"></result>
    <result column="course" jdbcType="VARCHAR" property="course" javaType="String" ></result>
  </association>
</resultMap>

在查询体中通过id调用
  <select id="selectById" resultType="cn.dream.pojo.Student" resultMap="BaseMap1">
      select s.*,t.* from student s JOIN teacher t on s.t_id=t.t_id where s.s_id=#{param1}
  </select>



一对一的另一种形式 ,使用对应的Bean的查询方法
<resultMap id="BaseMap2" type="Student">
    <id column="s_id" property="sId"></id>
    <result column="s_name" property="sName" ></result>
    <result column="t_id" property="tId" ></result>   
    //使用查询出来的学生id作为参数查询老师
   <association property="teacher" javaType="Teacher" column="t_id" select="cn.dream.dao.TeacherDao.selectByPrimaryKey">
   </association>
  </resultMap>
    <select id="selectById" resultType="cn.dream.pojo.Student" resultMap="BaseMap2">
        select s.*,t.* from student s JOIN teacher t on s.t_id=t.t_id where s.s_id=#{param1}
    </select>

一对多

一对多
//一个老师对应多个学生
<resultMap id="BaseResultMap2" type="cn.dream.pojo.Teacher">
  <id column="t_id" jdbcType="INTEGER" property="tId" javaType="Int" />
  <result column="t_name" jdbcType="VARCHAR" property="tName" />
  <result column="sex" jdbcType="VARCHAR" property="sex" />
  <result column="salary" jdbcType="FLOAT" property="salary" />
  <result column="course" jdbcType="VARCHAR" property="course" />
  <collection property="studentList" ofType="Student">
    <id column="s_id" property="sId" jdbcType="INTEGER" javaType="Int" ></id>
    <result column="s_name" property="sName"></result>
    <result property="tId" column="t_id" ></result>
  </collection>
</resultMap>

<select id="queryById" resultMap="BaseResultMap2">
  select t.*,s.* from teacher t join student s on t.t_id=s.t_id
  where t.t_id=#{tId}
</select>

延迟加载

开启延迟加载

关联关系中,可以通过配置达到按需加载
<setting name ="aggressiveLazyLoading" value="false"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>

一二级缓存

​ 缓存是一般的ORM 框架都会提供的功能,目的就是提升查询的效率和减少数据库的压力。跟Hibernate 一样,MyBatis 也有一级缓存和二级缓存,并且预留了集成第三方缓存的接口。

一级缓存

也叫本地缓存是sqlSession缓存 cache,默认开启

  • 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;

  • 不同的 SqlSession 之间的缓存是相互隔离的;

  • 用一个 SqlSession, 可以通过配置使得在查询前清空缓存;

    在对应查询语句中 作出配置,就不会使用缓存
    <select id="queryByNameAndAge" resultType="user"  flushCache="true">
        select <include refid="BaseSql"></include> from mybaties2
        <trim prefix="where" prefixOverrides="and" suffix="" suffixOverrides="">
            <if test="name!=null and name != '' ">
                and uname like concat('%',#{name},'%')
            </if>
            <if test=" age != null and age!=''">
                and age > #{age}
            </if>
        </trim>
    </select>
    
    
  • 任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。

二级缓存

是针对同一个sqlSessionfactory 中的多个sqlsession 会存储sql语句,

当发出同一个查询sql时 之前有的会自动返回之前查询到的值

默认关闭,开启缓存 在mybatis 配置文件中配置

<setting name="cacheEnabled" value="true"/>

哪个类要开启缓存就在哪个类的mapper中 加入 <cache/>标签
  • 在同一个 SqlSession 中, Mybatis 会把执行的方法和参数通过算法生成缓存的键值, 将键值和结果存放在一个 Map 中, 如果后续的键值一样, 则直接从 Map 中获取数据;
  • 不同的 SqlSession 之间的缓存是相互隔离的;
  • 用一个 SqlSession, 可以通过配置使得在查询前清空缓存;
  • 任何的 UPDATE, INSERT, DELETE 语句都会清空缓存。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值