mybatis快速入门高级篇-动态sql(if、where、chose、set、foreach)-解决数据库字段名与实体类属性名不匹配、多表查询

动态 SQL

动态 SQL 语句是在应用程序运行时被编译和执行的,如,一个客户一个 web 网站,输入姓名,手机号
等…条件名称 访问数据库的时候,用户输入的 SQL 语句是不确定性的,因此 SQL 语句只能被动态地编译。动态
SQL 的应用的场景很多,因此应用程序都使用动态 SQL来操作。(根据不同的条件需要执行不同的 SQL 命令)

If

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分

dao层

 /**
     * 动态sql
     * 当字段值不为空以字段查询条件,当字段值为空查询所有
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByIf(BookModel bookModel);

mapper

	<select id="getBookListByIf" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book where 1=1
        <!-- 如果name条件为空,下面语句不会执行,只会执行上面语句 -->
        <if test="name != null and name != ''">
            and name = #{name}
        </if>
    </select>

测试

//main方法中调用
 		BookModel bookModel = new BookModel();
 		//不设置书的名称,查询所有数据
 		//设置书的名称,只查询书名的数据
        bookModel.setName("大头儿子小头爸爸");
        getBookListByIf(bookModel);
//方法
public static void getBookListByIf(BookModel bookModel) throws Exception{
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookListByIf = mapper.getBookListByIf(bookModel);
        for (BookModel book : bookListByIf){
            System.out.println(book);
        }

    }

动态sql模糊匹配

dao层

/**
     * 模糊查询所有数据
     * @param bookModel 根据name模糊查询
     * @return
     */
    List<BookModel> getBookListByLikeName(BookModel bookModel);

mapper

 	<select id="getBookListByLikeName" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book where 1=1
        <if test="name != null and name != ''">
            and name like concat('%',#{name},'%')
        </if>
    </select>

测试

//main方法中调用
	getBookListByLikeName("小");

//方法
public static void getBookListByLikeName(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByLikeName(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

where

where 有内容会则生成 where 关键字,如果没有内容则不生成 where 关键字

dao层

	/**
     * where查询
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByWhere(BookModel bookModel);

mapper

	<select id="getBookListByWhere" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book
            <where>
            	<!-- 如果name不为空 -->
            	<!--  select * from book where name like '%nameValue%' -->
                <if test="name != null and name !=''">
                    name like concat('%',#{name},'%')
                </if>
                <!-- 如果price不为空 -->
                <!--  select * from book where name like '%name%' and price = priceValue -->
                <if test="price != null and price != ''">
                    and price = #{price}
                </if>
            </where>
    </select>

测试

//main方法中调用
	getBookListByWhere("大");

//方法
 public static void getBookListByWhere(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        //添加price,判断两个条件
        //bookModel.setPrice(211.0);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByWhere(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

choose,when,otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

dao层

	/**
     * choose,when,otherwise
     * 只要三者中有一个成立,其他都不执行。
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByChoose(BookModel bookModel);

mapper

	<select id="getBookListByChoose" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book
        <where>
            <choose>
            	<!-- 如果name不为空 -->
            	<!-- select * from book where name like '%nameValue%' -->
                <when test="name != null and name != ''">
                    name like concat('%',#{name},'%')
                </when>
                <!-- 如果name为空 price不为空 -->
                <!-- select * from book where price = priceValue -->
                <when test="price != null and price != ''">
                    price = #{price}
                </when>
                 <!-- 如果name为空 price为空 -->
                  <!-- select * from book where 1=1 -->
                <otherwise>
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>

测试

//main中调用
	getBookListByChoose("大");

//方法
	public static void getBookListByChoose(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        //虽然添加了price,但是只会执行name的查询条件,如果都没有条件执行,执行最后的otherwise里的条件,相当于switch
        //bookModel.setPrice(211.0);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByChoose(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

set

dao层

/**
     * 动态修改信息
     * @param bookModel
     * @return
     */
    int updateBookBySqlSet(BookModel bookModel);

mapper

<update id="updateBookBySqlSet" parameterType="model.BookModel">
        update book
        <set>
            <!-- 如果java测试类的name,price都不写入,注释掉,然后mapper的<set>自然两个if都不
            进入,sql就会出现问题,因此加入id=#{id} -->
            id = #{id},
            <if test="name != null and name != ''">
                name=#{name},
            </if>
            <!-- 如果添加额外的修改条件,却没给赋值,会赋值默认值 -->
            <!-- 如果没有添加额外的修改条件,数据库本身的值不变,把下面的if注释掉,看看数据库的两种情况 -->
            <if test="price != null and price != null">
                price=#{price},
            </if>
        </set>
        where id = #{id}
    </update>

测试

//main中调用
	updateBookBySqlSet();

//方法
 public static void updateBookBySqlSet() throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName("假如给我三天光明");
        bookModel.setId(9);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        int i = mapper.updateBookBySqlSet(bookModel);
        sqlSession.commit();
        System.out.println(i > 0 ? "修改成功" : "修改失败");

    }

foreach

  • 使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)
  • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符。
  • 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值

dao层

    /**
     * 根据指定id查询,比如查询id为5,6,7的数据
     * @param ids
     * @return
     */
    List<BookModel> getBookByIn(int[] ids);

mapper

	<select id="getBookByIn" resultType="model.BookModel">
        select * from book where id in
        <foreach collection="array" item="id" index="i" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

测试

//main方法中调用
  getBookByIn();
  
//方法
public static void getBookByIn() throws Exception{
        int[] ids = {5,6,7};
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);

        List<BookModel> books = mapper.getBookByIn(ids);
        for (BookModel book : books) {
            System.out.println(book);
        }
    }

resultMap(解决数据库字段与实体类属性名不匹配问题)

mapper.xml文件

<!-- 如果数据库字段名和实体类的属性名一致,可以不用配置resultMap,mybatis会隐式自动的创建一个 ResultMap -->
<!-- 结果映射 -->
	<!-- id: resultMap的别名,唯一标识,由数据库操作调用 -->
	<!-- type: 指定类型 -->
    <resultMap id="book" type="model.BookModel">
    	<!-- id:指定和数据表主键字段对应的标识属性 -->
    	<!-- property:property表示实体类的属性 -->
    	<!-- column:数据库的字段名 -->
    	<!-- result:指定结果集字段和实体类属性的映射关系 -->
        <id property="id" column="t_id" />
        <result property="name" column="t_name"/>
        <result property="price" column="t_price"/>
        <result property="num" column="t_num"/>
    </resultMap>
	
	<!-- resultMap:引入resultMap的id,作为返回值类型 -->
    <select id="findAll" resultMap="book">
        select * from book;
    </select>

第二种解决数据库字段名与实体类属性名不匹配方法

	<!-- 我们可以在sql语句中直接设置别名,mybtais会自动隐式映射 -->
 <select id="findAll" resultMap="book">
        select 	
        	t_id as id,
        	t_name as name,
        	t_price as price,
        	t_num as num
		from book;
    </select>

多表查询

dao层

List<Map<String,Object>> findPurBooMap();

mapper

<select id="findPurBooMap" resultType="map">
	select p.id,p.`name`,p.bid,b.id `book.id`,b.bookName `book.bookName`,b.auth
	`book.auth`,b.price `book.price`,b.publish `book.publish` 
	from purchaser p LEFT JOINbook b 
	ON b.id = p.id
</select>

测试

    public static void findPurBooMap() throws Exception{
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<Map<String,Object>> maps = mapper.findPurBooMap();
        for (Map<String, Object> map : maps) {
            for (Object string : map.keySet()){
                System.out.println(string+":"+map.get(string));
            }
        }
    }
  • 26
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值