MyBatis——dao代理的使用、深入理解参数(传递一个参数、传递多个参数、使用entity实体类传递、使用自定义类传递、按位置传递、使用Map传递)

简介: MyBatis——dao代理的使用、深入理解参数(传递一个参数、传递多个参数、使用entity实体类传递、使用自定义类传递、按位置传递、使用Map传递)

文章目录:


1.MyBatisdao代理

1.1 MyBatis提供代理 

1.2 使用MyBatis代理的要求 

1.3 MyBatis代理的实现方式

2.深入理解相关参数

2.1 parameterType

2.2 dao接口的方法形参列表中只有一个参数(重要!!!)

2.3 dao接口的方法形参列表中有多个参数(重要!!!)

2.4 dao接口的方法形参列表中使用entity实体类对象(重要!!!)

2.5 dao接口的方法形参列表中使用自定义类对象(重要!!!)

2.6 dao接口的方法形参列表中按位置传递参数(不推荐!!!)

2.7 dao接口的方法形参列表中按Map传递参数(不推荐!!!)

写在结尾

1.MyBatis的dao代理


1.1 MyBatis提供代理 

MyBatis创建 dao 接口的实现类对象,完成对 sql 语句的执行。也就是说,MyBatis会创建一个对象代替你的 dao 实现类的功能。


1.2 使用MyBatis代理的要求 

1.    mapper文件中的 namespace 一定是 dao 接口的全限定名称。

2.    mapper文件中标签的 id 属性值必须是 dao 接口的方法名称。 


1.3 MyBatis代理的实现方式

使用 SqlSession 对象的方法 getMapper(dao.class),在这里通过Java反射机制,来获取对应的 dao 接口中的相关内容。 

    @Test
    public void testSelectById() {
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.获取dao的代理
        StudentDao studentDao=session.getMapper(StudentDao.class);
        Student student=studentDao.selectById(1001);
        System.out.println("student = " + student);
        //3.关闭SqlSession对象
        session.close();
    }

    @Test
    public void testSelectStudents() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        //com.sun.proxy.$Proxy == StudentDaoImpl
        System.out.println("studentDao === " + studentDao.getClass().getName());
        List<Student> students=studentDao.selectStudents();
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }

在上面两个测试方法中,有等价的代码如下:👇👇👇

1.  StudentDao studentDao=session.getMapper(StudentDao.class);

2.  //等同于

3.  StudentDao studentDao=new StudentDaoImpl();

2.深入理解相关参数


理解参数就是:通过Java程序把数据传入到 mapper 文件中的 sql 语句。参数主要是指 dao 接口中方法的形参。

下面先给出MyBatis支持的Java类型的别名!!!

上图中,列表的左边为MyBatis支持的Java类型的别名,右边为通过反射机制得到的Java中的映射数据类型。 


2.1 parameterType

有关 parameterType 的理解,可以参考下面xml文件中的注释部分。

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    Student selectById(Integer id);
}
    <!--
        parameterType: 指定dao接口形参的类型
        这个属性的值可以使用 java 类型的全限定名称或者 mybatis定义的别名
        mybatis执行的sql语句:select id,name,email,age from student where id=?
        ? 是占位符,使用jdbc中的PreparedStatement执行这样的sql语句
        PreparedStatement pst=conn.preparedStatement("select id,name,email,age from student where id=?");
        给 ? 位置赋值
        参数Integer:执行pst.setInt(1,1001);  对应了mybatis中的 parameterType="java.lang.Integer"
        参数String:执行pst.setString(1,"1001");
        第一个用法:java类型的全限定名称 parameterType="java.lang.Integer"
        第二个用法:mybatis定义的java类型的别名 parameterType="intinteger"
        mybatis通过反射机制可以获取 dao 接口方法的参数类型,即parameterType可以不写
    -->
    <select id="selectById" parameterType="integer"
            resultType="com.bjpowernode.entity.Student">
        select id,name,email,age from student where id=#{studentId}
    </select>
    @Test
    public void testSelectById() {
        //1.获取SqlSession
        SqlSession session = MyBatisUtil.getSqlSession();
        //2.获取dao的代理
        StudentDao studentDao=session.getMapper(StudentDao.class);
        Student student=studentDao.selectById(1003);
        System.out.println("student = " + student);
        //3.关闭SqlSession对象
        session.close();
    }

可以看到在输出结果中,出现了 Parameters 这一项,就是说参数类型是 Integer


2.2 dao接口的方法形参列表中只有一个参数(重要!!!)

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    //dao接口的方法形参是一个简单类型
    //简单类型:java基本数据类型和String
    Student selectByEmail(String email);
}
    <!--
        dao接口是一个简单类型的参数(java 基本类型和 String)
        mapper文件获取这个参数值:使用 #{任意字符}
    -->
    <select id="selectByEmail" resultType="com.bjpowernode.entity.Student">
        select id,name,email,age from student where email=#{studentEmail}
    </select>
    @Test
    public void testOneParameter() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        Student student=studentDao.selectByEmail("zhangsan@qq.com");
        System.out.println("email === " + student);
        session.close();
    }

2.3 dao接口的方法形参列表中有多个参数(重要!!!)

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    /*
     *  多个简单类型的参数
     *  使用 @Param 命名参数,注解都是mybatis提供的
     *  位置:在形参定义的前面
     *  属性:value 自定义的参数名称
     */
    List<Student> selectByNameOrAge(@Param("myname") String name,
                                    @Param("myage") Integer age);
}
    <!--
        多个简单类型的参数
        当你使用了 @Param 命名后,例如 @param("myname")
        在mapper中,使用 #{命名的参数},即 #{myname}
    -->
    <select id="selectByNameOrAge" resultType="com.bjpowernode.entity.Student">
        select id,name,email,age from student where name=#{myname} or age=#{myage}
    </select>
    @Test
    public void testSelectByNameOrAge() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        List<Student> students=studentDao.selectByNameOrAge("张三",20);
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }

2.4 dao接口的方法形参列表中使用entity实体类对象(重要!!!)

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    /*
     *  一个java对象作为参数(对象有属性,每个属性有set、get方法)
     */
    List<Student> selectByObject(Student student);
}
<!--
    一个java对象作为方法的参数,使用对象的属性作为参数值
    简单的语法:#{属性名},mybatis调用此属性的getXXX()方法
-->
<select id="selectByObject" resultType="com.bjpowernode.entity.Student">
    select id,name,email,age from student where name=#{name} or age=#{age}
</select>
<!--
    也可以写成下面这种复杂的更详细的格式:
    javaType=java中数据类型名
    jdbcType=数据库中数据类型名称
-->
<select id="selectByObject" resultType="com.bjpowernode.entity.Student">
    select id,name,email,age
    from student
    where name=#{name,javaType=java.lang.String,jdbcType=VARCHAR} or
          age=#{age,javaType=java.lang.Integer,jdbcType=INTEGER}
</select>
    @Test
    public void testSelectByObject() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        Student student=new Student();
        student.setName("张三");
        student.setAge(20);
        List<Student> students=studentDao.selectByObject(student);
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }

2.5 dao接口的方法形参列表中使用自定义类对象(重要!!!)

首先,我们新建一个自定义类,如下图:👇👇👇 

package com.bjpowernode.vo;
/**
 *
 */
public class QueryParam {
    private Object p1;
    private Object p2;
    public Object getP1() {
        return p1;
    }
    public void setP1(Object p1) {
        this.p1 = p1;
    }
    public Object getP2() {
        return p2;
    }
    public void setP2(Object p2) {
        this.p2 = p2;
    }
}
package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import com.bjpowernode.vo.QueryParam;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    List<Student> selectByQueryParam(QueryParam param);
}
<select id="selectByQueryParam" resultType="com.bjpowernode.entity.Student">
    select id,name,email,age from student where name=#{p1} or age=#{p2}
</select>


    @Test
    public void testSelectByObject2() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        QueryParam param=new QueryParam();
        param.setP1("李四");
        param.setP2(15);
        List<Student> students=studentDao.selectByQueryParam(param);
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }

2.6 dao接口的方法形参列表中按位置传递参数(不推荐!!!)

参数位置:dao接口中方法的形参列表,从左到右,参数位置是:012......

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
/**
 *
 */
public interface StudentDao {
    //使用位置获取参数
    List<Student> selectByPosition(String name,Integer age);
}
<!--
    使用位置获取参数值,dao接口方法是多个简单类型的参数
    语法:#{arg0},#{arg1}...
-->
<select id="selectByPosition" resultType="com.bjpowernode.entity.Student">
    select id,name,email,age from student where name=#{arg0} or age=#{arg1}
</select>
    @Test
    public void testSelectByPosition() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        List<Student> students=studentDao.selectByPosition("张三",15);
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }

2.7 dao接口的方法形参列表中按Map传递参数(不推荐!!!)

package com.bjpowernode.dao;
import com.bjpowernode.entity.Student;
import java.util.List;
import java.util.Map;
/**
 *
 */
public interface StudentDao {
    //使用Map作为参数
    List<Student> selectStudentByMap(Map<String,Object> map);
}
<!--
    使用Map传递参数
    在mapper文件中,获取map的值,是通过key获取的,语法:#{key}
-->
<select id="selectStudentByMap" resultType="com.bjpowernode.entity.Student">
    select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
    @Test
    public void testSelectByMap() {
        SqlSession session=MyBatisUtil.getSqlSession();
        StudentDao studentDao=session.getMapper(StudentDao.class);
        Map<String,Object> map=new HashMap<>();
        map.put("myname","张三");
        map.put("myage",20);
        List<Student> students=studentDao.selectStudentByMap(map);
        students.forEach( stu-> System.out.println("stu = " + stu));
        session.close();
    }


写在结尾


上面的所有实例,给出的代码都是这几块:

1.    dao接口中的相关方法体

2.    mapper文件中的相关标签(每个标签对应着 dao 接口中的一个方法体)

3.    测试类中的测试方法(每个测试方法对应着 dao 接口中某个方法体的具体实现)

4.    程序的运行结果

推荐大家使用 2.22.32.42.5 这几种方法来传递参数!!!

在这里就不再给出 mybatis.xml 主配置文件了,因为其中的数据源、读取mapper文件的标签内容都是不做修改的。

相关文章
|
30天前
|
XML Oracle Java
mybatis反向生成实体类、dao层以及映射文件
mybatis反向生成实体类、dao层以及映射文件
13 1
|
30天前
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
Mybatis+mysql动态分页查询数据案例——条件类(HouseCondition)
15 1
|
12天前
|
SQL Java 数据库连接
MyBatis精髓揭秘:Mapper代理实现的黑盒探索
MyBatis精髓揭秘:Mapper代理实现的黑盒探索
22 1
|
1月前
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl
ssm(Spring+Spring mvc+mybatis)Dao层实现类——DeptDaoImpl
12 0
|
1月前
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
ssm(Spring+Spring mvc+mybatis)Dao接口——IDeptDao
8 0
|
1月前
ssm(Spring+Spring mvc+mybatis)实体类——Dept
ssm(Spring+Spring mvc+mybatis)实体类——Dept
11 0
|
1月前
|
Java 数据库连接 mybatis
mybatis简单案例源码详细【注释全面】——Dao层映射文件(UserMapper.xml)【重要】
mybatis简单案例源码详细【注释全面】——Dao层映射文件(UserMapper.xml)【重要】
10 0
|
1月前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
41 1
|
1月前
|
druid Java 数据库连接
Spring Boot3整合MyBatis Plus
Spring Boot3整合MyBatis Plus
45 1
|
3月前
|
Java 数据库连接 Maven
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!
SSM框架整合:掌握Spring+Spring MVC+MyBatis的完美结合!