MyBatis04--深度理解参数
一、深度理解参数
1.parameterType
parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从 java 代码传入到
mapper 文件的 sql 语句。
int 或 java.lang.Integer
hashmap 或 java.util.HashMap
list 或java.util.ArrayList
student 或 com.suyv.mybatis.domain.Student
select,insert,update,delete都可以使用 parameterType 指定类型。
例如:
<delete id="deleteStudent" parameterType="int">
delete from student where id=#{studentId}
</delete>
等同于
<delete id="deleteStudent" parameterType="java.lang.Integer">
delete from student where id=#{studentId}
</delete>
2.MyBatis 传递参数
从 java 代码中把参数传递到 mapper.xml 文件。
3.一个简单参数
Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。
接口方法:
Student selectById(int id);
mapper 文件:
<select id="selectById" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from student where id=#{id}
</select>
测试方法:
@Test
public void testSelectById(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
Student student = dao.selectById(1001);
System.out.println(student);
}
结果展示:
4.多个参数-使用@Param
当 Dao 接口方法多个参数,需要通过名称使用参数。在方法形参前面加入@Param(“自定义参数名”),
mapper 文件使用#{自定义参数名}。
例如定义
List selectStudent( @Param(“personName”) String name ) { … }
mapper 文件 select * from student where name = #{ personName}
接口方法:
public List<Student> selectMulitParam(@Param("myname") String name, @Param("myage") Integer age);
mapper 文件:
<select id="selectMulitParam" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from Student where name=#{myname} or age=#{myage}
</select>
测试方法:
@Test
public void testselectMulitParam(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectMulitParam("妲己",22);
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
结果展示:
5.多个参数-使用对象
使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。
语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 }
javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格式 #{ property }
接口方法:
public List<Student> selectMulitObject(Student student);
mapper 文件:
<select id="selectMulitObject" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from Student where name=#{name} or age=#{age}
</select>
测试方法:
@Test
public void testselectMulitObject(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
Student student = new Student();
student.setName("妲己");
student.setAge(22);
List<Student> students = dao.selectMulitObject(student);
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
结果展示:
6.多个参数-按位置
参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}, 第二个是#{arg1}
注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。
接口方法:
public List<Student> selectMulitPosition(String name,Integer age);
mapper 文件
<select id="selectMulitPosition" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from Student where name=#{arg0} or age=#{arg1}
</select>
测试方法:
@Test
public void testselectMulitPosition(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectMulitPosition("妲己",22);
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
结果展示:
7.多个参数-使用 Map
Map 集合可以存储多个值,使用Map向 mapper 文件一次传入多个参数。Map 集合使用 String的 key,Object 类型的值存储参数。 mapper 文件使用 # { key } 引用参数值。
例如:
Map<String,Object> data = new HashMap<String,Object>();
data.put(“myname”,”李四”);
data.put(“myage”,20);
接口方法:
public List<Student> selectMulitMap(Map<String,Object> map);
mapper 文件:
<select id="selectMulitMap" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from Student where name=#{mapname} or age=#{mapage}
</select>
测试方法:
@Test
public void testselectMulitMap(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Map<String,Object> map = new HashMap<>();
map.put("mapname","妲己");
map.put("mapage",22);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectMulitMap(map);
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
结果展示:
8.#和$
通用方法,使用不同列作为查询条件
接口方法:
public List<Student> selectUse$Order(@Param("colName") String colName);
mapper 文件:
<select id="selectUse$Order" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from Student order by ${colName}
</select>
测试方法:
@Test
public void testselectUse$Order(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectUse$Order("name");
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
结果展示:
二、封装 MyBatis 输出结果
1.resultType
resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。
注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
resultType 和 resultMap,不能同时使用。
1)简单类型
接口方法:
public int countStudent();
mapper 文件:
<select id="countStudent" resultType="int">
select count(*) from Student
</select>
测试方法:
@Test
public void testCountStudent(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
int counts = dao.countStudent();
System.out.println("学生总人数:"+ counts);
}
运行截图:
2)Map
sql 的查询结果作为 Map 的 key 和 value。推荐使用 Map<Object,Object>。
注意:Map作为接口返回值,sql 语句的查询结果最多只能有一条记录。大于一条记录是错误。
接口方法:
public Map<Object,Object> selectReturnMap(int id);
mapper 文件:
<select id="selectReturnMap" resultType="java.util.HashMap">
select name,email from student where id = #{studentId}
</select>
测试方法:
@Test
public void testReturnMap(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
Map<Object,Object> retMap = dao.selectReturnMap(1002);
System.out.println("查询结果是 Map:"+retMap);
}
运行截图:
2.resultMap
resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。
常用在列名和 java 对象属性名不一样的情况。
使用方式:
1.先定义 resultMap,指定列名和属性的对应关系。
2.在中把 resultType 替换为 resultMap。
接口方法:
public List<Student> selectAllStudents();
mapper 文件:
<!--定义resultMap
id:自定义名称,表示你定义的这个resultMap
type:java类型的全限定名称
-->
<resultMap id="studentMap" type="com.suyv.mybatis.domain.Student">
<!--列名和java属性的关系-->
<!--主键列,使用id标签
column :列名
property:java类型的属性名
-->
<id column="id" property="id" />
<!--非主键列,使用result-->
<result column="name" property="name" />
<result column="email" property="email" />
<result column="age" property="age" />
</resultMap>
<select id="selectAllStudents" resultMap="studentMap">
select id,name, email , age from student
</select>
测试方法:
@Test
public void testselectAllStudents(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//调用dao的方法,执行数据库操作
List<Student> students = dao.selectAllStudents();
for (Student stu:students){
System.out.println(stu);
}
sqlSession.close();
}
运行截图:
3.实体类属性名和列名不同 的 处理方式
1)使用resultMap
步骤:
- 创建新的实体类MyStudent
package com.suyv.mybatis.domain;
public class MyStudent {
private Integer stuid;
private String stuname;
private String stuemail;
private Integer stuage;
public Integer getStuid() {
return stuid;
}
public void setStuid(Integer stuid) {
this.stuid = stuid;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public String getStuemail() {
return stuemail;
}
public void setStuemail(String stuemail) {
this.stuemail = stuemail;
}
public Integer getStuage() {
return stuage;
}
public void setStuage(Integer stuage) {
this.stuage = stuage;
}
@Override
public String toString() {
return "MyStudent{" +
"stuid=" + stuid +
", stuname='" + stuname + '\'' +
", stuemail='" + stuemail + '\'' +
", stuage=" + stuage +
'}';
}
}
- 接口方法
List<MyStudent> selectMyStudent();
- mapper 文件:
<resultMap id="myStudentMap" type="com.suyv.mybatis.domain.MyStudent">
<!--列名和java属性的关系-->
<id column="id" property="stuid" />
<!--非主键列,使用result-->
<result column="name" property="stuname" />
<result column="email" property="stuemail" />
<result column="age" property="stuage" />
</resultMap>
<!--列名和属性名不一样:第一种方式-->
<select id="selectMyStudent" resultMap="myStudentMap">
select id,name, email , age from student
</select>
4.测试方法
@Test
public void testSelectMyStudents(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<MyStudent> students = dao.selectMyStudent();
for(MyStudent stu: students){
System.out.println("学生="+stu);
}
sqlSession.close();
}
运行截图:
2)使用列别名和resultType
步骤:
- 接口方法
List<MyStudent> selectDiffColProperty();
- mapper 文件:
<!--列名和属性名不一样:第二种方式
resultType的默认原则是 同名的列值赋值给同名的属性, 使用列别名(java对象的属性名)
-->
<select id="selectDiffColProperty" resultType="com.suyv.mybatis.domain.MyStudent">
select id as stuid ,name as stuname, email as stuemail , age stuage from student
</select>
- 测试方法
@Test
public void testSelectDiffColProperty(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
List<MyStudent> students = dao.selectDiffColProperty();
for(MyStudent stu: students){
System.out.println("学生="+stu);
}
sqlSession.close();
}
运行截图:
三、模糊 like
模糊查询的实现有两种方式, 一是 java 代码中给查询数据加上“%” ; 二是在 mapper 文件 sql 语句的
条件位置加上“%”
需求:查询姓名有“明”的
例 例 1: java 代码中提供要查询的 “%明% ”
接口方法:
List<Student> selectLikeOne(String name);
mapper 文件:
<select id="selectLikeOne" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from student where name like #{name}
</select>
测试方法:
@Test
public void testSelectLikeOne(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备好like的内容
String name = "%明%";
List<Student> students = dao.selectLikeOne(name);
for(Student stu: students){
System.out.println("#######学生="+stu);
}
sqlSession.close();
}
运行截图:
例 2:mapper 文件中使用 like name “%” #{xxx} “%”
接口方法:
List<Student> selectLikeTwo(String name);
mapper 文件:
<select id="selectLikeTwo" resultType="com.suyv.mybatis.domain.Student">
select id,name,email,age from student where name like "%" #{name} "%"
</select>
测试方法:
@Test
public void testSelectLikeTwo(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//准备好like的内容
String name = "明";
List<Student> students = dao.selectLikeTwo(name);
for(Student stu: students){
System.out.println("*******学生="+stu);
}
sqlSession.close();
}
运行截图: