文章目录:
2.2 dao接口的方法形参列表中只有一个参数(重要!!!)
2.4 dao接口的方法形参列表中使用entity实体类对象(重要!!!)
2.5 dao接口的方法形参列表中使用自定义类对象(重要!!!)
2.6 dao接口的方法形参列表中按位置传递参数(不推荐!!!)
2.7 dao接口的方法形参列表中按Map传递参数(不推荐!!!)
1.MyBatis的dao代理
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接口中方法的形参列表,从左到右,参数位置是:0,1,2,......
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.2、2.3、2.4、2.5 这几种方法来传递参数!!!
在这里就不再给出 mybatis.xml 主配置文件了,因为其中的数据源、读取mapper文件的标签内容都是不做修改的。