1.案例
结合案例进行学习,案例准备如下
(1)创建一个books表如下
(2)编写BooksMapper接口
package com.its.mapper;
import com.its.pojo.Books;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface BooksMapper {
List<Books> selectBooksByTitle(String title);
List<Books> selectBooksByTitleAndAuthor(String title,int bookId,String author);
List<Books> selectBooksByTitleAndAuthor(@Param("title") String title, @Param("bookId") int bookId);
List<Books> selectBooksByBean(Books books);
List<Books> selectBooksByLikeTitle(@Param("title") String title);
}
编写BooksMapper.xml映射文件
<?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="com.its.mapper.BooksMapper">
<select id="selectBooksByTitle" resultType="com.its.pojo.Books">
select * from demo_test.books where title = #{title}
</select>
<select id="selectBooksByTitleAndAuthor" resultType="com.its.pojo.Books">
select * from demo_test.books where title = #{param1} and book_id = #{param2}
</select>
<select id="selectBooksByBean" resultType="com.its.pojo.Books">
select * from demo_test.books where title = #{title} and book_id = #{bookId}
</select>
<select id="selectBooksByLikeTitle" resultType="com.its.pojo.Books">
select * from demo_test.books where title like concat('%',#{title},'%')
</select>
</mapper>
在mybatis配置文件中添加映射关系
<!--映射文件的位置-->
<mappers>
<mapper resource="com/its/mapper/UserMapper.xml"/>
<mapper resource="com/its/mapper/BooksMapper.xml"/>
</mappers>
接下来编写测试文件如下:
package com.its;
import com.its.mapper.BooksMapper;
import com.its.pojo.Books;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class BooksMapperTest {
/*1.普通参数,单个参数,注意单个参数的传参,无论传的是啥,是否和方法的参数名一样无关,都能成功。
这是因为实际上映射文件就是这个接口的实现类对象,执行的查询就是重写了这个接口中的方法,所以这个方法中的参数
是可以自定义的,因此一个参数的时候你写啥都可以。
*/
@Test
public void books01(){
BooksMapper mapper = session.getMapper(BooksMapper.class);
List<Books> booksList = mapper.selectBooksByTitle("活着");
booksList.forEach(System.out::println);
}
/*
2.普通参数,两个参数的时候,就不能乱写了,因为不能识别你写的是两个参数中的那一个,这时你有三种方法传参
(1)使用arg0 和 arg1 ...只能按着顺序从小到大,要是从大到小也能运行,但是参数会反过来,查询不到结果。
(2)使用param1,param2 ...同上
(3)使用@Param("指定参数名")指定参数名字,调用的时候可以直接使用指定的参数名
*/
@Test
public void books02(){
BooksMapper mapper = session.getMapper(BooksMapper.class);
List<Books> booksList = mapper.selectBooksByTitleAndAuthor("活着",1);
booksList.forEach(System.out::println);
}
/*
3.传递一个对象,直接写对象的属性名和表的字段名对应即可
*/
@Test
public void books03(){
BooksMapper mapper = session.getMapper(BooksMapper.class);
Books books = new Books();
books.setTitle("活着");
books.setBookId(1);
List<Books> booksList = mapper.selectBooksByBean(books);
booksList.forEach(System.out::println);
}
/*
* 4.模糊查询,用concat()函数进行拼接,不能用'%#{}%'
* */
@Test
public void books04(){
BooksMapper mapper = session.getMapper(BooksMapper.class);
List<Books> booksList = mapper.selectBooksByLikeTitle("着");
booksList.forEach(System.out::println);
}
/*
* 5.$ 和 # 的区别
* 区别:$ 不会预编译 有SQL注入的风险 # 可以预编译
* */
SqlSession session;
//@Before这个注解会在@Tset注解运行之前执行
@Before //因为每一个测试时都需要有这步操作,所以统一写在这里,减少代码量
public void init() throws IOException {
//读取核心配置文件信息
InputStream is = Resources.getResourceAsStream("mybatis.xml");
//获取一个SqlSessionFactory 数据库会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
session = sqlSessionFactory.openSession();
}
//@After这个注解会在@Tset注解运行之后执行,通常用于释放资源等
@After
public void destroy(){
session.close();
}
}
2.单个方式传参
- 当只有一个参数时,可以直接使用 #{parameter} 的形式来引用参数。
【注意】
单个参数的传参,无论传的是啥,是否和方法的参数名一样无关,都能成功。
这是因为实际上映射文件就是这个接口的实现类对象,执行的查询就是重写了这个接口中 的方法,所以这个方法中的参数是可以自定义的,因此一个参数的时候你写啥都可以。
测试代码
映射文件中的SQL语句,与接口的参数名一样
执行测试代码,结果正常查询。
下面,将映射文件中的SQL语句中的参数与接口的参数名设置不一样
结果依然正确
3.多个参数传参
两个参数的时候,就不能乱写了,因为不能识别你写的是两个参数中的那一个,这时你有三种方法传参
(1)使用 arg0 和 arg1 ... 只能按着顺序从小到大,要是从大到小也能运行,但是参数会反过来,查询不到结果。
(2)使用param1,param2 ... 同上
(3)使用@Param("指定参数名")指定参数名字,调用的时候可以直接使用指定的参数名
代码测试1(错误传参)
接口方法
映射的sql 语句
执行测试代码,结果报错,不能识别参数。
【注意】尽管这里sql 语句中的#{ } 里设置的和接口参数一致,但也不能被识别,因为并不能确定对应的参数。
代码测试2(用arg0 和 arg1 )
接口方法和上面一样,在sql 语句中用上arg0 和 arg1 .......接收。
执行测试代码,结果如下,能正常识别,结果正确。
说明能够识别参数,参数是按照顺序传递进来的,如果将顺序反过来写,arg2,arg1,arg0 ,也能运行,但是,接受的参数会乱序,查询不到结果,会出现book_id = 书名,而 author = bookId 的结果。
代码测试3 (用@Param(" ")注解 )
只要在写接口的时候写上@Param("自定义的名字"),就可以在sql中引用自己定义的名字。
这里现在就可以使用了。测试结果正确。
4.对象传参
如果参数是一个对象(比如实体类),可以直接传递整个对象。在 SQL 映射文件中,可以通直接写对象的属性进行传递,mybatis会自动映射到数据库的字段名。(前提是表的字段名和对象除了驼峰命名不一致,其他都一样)
代码测试
1.mapper接口方法
2.sql映射语句
3.执行测试代码,结果正确