Mybatis框架Dao代理

              3.1 Dao 代理实现数据库操作

3.1.1 步骤

   (1) 去掉 Dao 接口实现类

  Mybatis框架Dao代理

 

 

   (2) getMapper 获取代理对象

  只需调用 SqlSession 的 getMapper()方法,即可获取指定接口的实现类对 象。该方法的参数为指定 Dao 接口类的 class 值。

package com.hrf;

import com.hrf.Utils.MybatisUtils;
import com.hrf.dao.StudentDao;
import com.hrf.domain.Student;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;


public class MybatisTest {
    @Test
    public void testSelectById(){
        //获取SqlSession
        SqlSession session = MybatisUtils.getSqlSession();
        //获取dao的代理
        StudentDao dao = session.getMapper(StudentDao.class);
        Student student = dao.SelectStudentById(1001);
        System.out.println("学生信息"+student);
        session.close();

    }


}
.       `

  使用工具类:

StudentDao studentDao = 
MyBatisUtil.getSqlSession().getMapper(StudentDao.class);

getMapper()创建的对象,是代替我们自己创建的 StudentDaoImpl 类

  3.2 深入理解参数

  从 java 代码中把参数传递到 mapper.xml 文件。

    3.2.1 parameterType

      parameterType: 接口中方法参数的类型, 类型的完全限定名或别名。这个属 性是可选的,因为 MyBatis 可以推断出具体传入语句的参数,默认值为未设置 (unset)。接口中方法的参数从 java 代码传入到 mapper 文件的 sql 语句。

      int 或 java.lang.Integer

       hashmap 或 java.util.HashMap

       list 或 java.util.ArrayList

       student 或 com.bjpowernode.domain.Student

      更多看资源中的有关别名的文件或者 mybatis-3.5.1.pdf 的 15 页。

      <select>,<insert>,<update><delete>都可以使用parameterType指定类型

    例如: 

<select id="SelectStudentById" parameterType="java.lang.Integer"
            resultType="com.hrf.domain.Student">
        select id,name,email,age from student where id=#{StudenId}
    </select>

  3.2.2 [掌握]一个简单参数

    Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占 位符 #{ 任意字符 },和方法的参数名无关。

  定义接口方法

 Student selectById(int id);

  配置文件写sql语句

<select id="selectById" resultType="com.hrf.domain.Student">
        select * from  student where id = #{StudentId}
    </select>

  编写测试类

@Test
    public void selectId(){
       SqlSession session = MybatisUtils.getSqlSession();
       StudentDao studentDao = session.getMapper(StudentDao.class);
       Student student = studentDao.selectById(1005);
       System.out.println("学生信息"+student);
       session.close();
   }

    测试结果:

  Mybatis框架Dao代理

 

   3.2.3 [掌握]多个参数-使用@Param

    当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加 入@Param(“自定义参数名”),mapper 文件使用#{自定义参数名}。

    例如定义:LIst<Student> selectStudent(@Param("psersonName") String name){....}

  mapper文件

      select * from student where name = #{personName}

  示例:

    创建接口方法

 List<Student> selectSomeStudent(@Param("studentName") String name,
                                   @Param("StudentAge") int age);

  mapper配置文件sql语句

<select id="selectSomeStudent" resultType="com.hrf.domain.Student">
        select * from student where name = #{studentName} or age = #{StudentAge}
    </select>

  测试类:

@Test
    public void selectSomeStudent(){
       SqlSession session = MybatisUtils.getSqlSession();
       StudentDao dao = session.getMapper(StudentDao.class);
       List<Student> students = dao.selectSomeStudent("王五", 20);
       for (Student stu : students){
           System.out.println("查到的学生信息"+stu);
           session.close();
       }
   }

    测试结果:  

    Mybatis框架Dao代理

 

 3.2.4 [掌握]多个参数-使用对象

  使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个 属性就是一个参数。

  语法格式:#{property.javaType = java中数据类型名,jdbcType=数据类型名称}

  javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。常用格 式 #{ property }

  (mybatis-3.5.1.pdf 第 43 页 4.1.5.4 小节:)

  Mybatis框架Dao代理

 

   创建一个实体类对象

  

package com.hrf.domain;

public class QueryParam {
    private String queryName;
    private int queryAge;

    public String getQueryName() {
        return queryName;
    }

    public void setQueryName(String queryName) {
        this.queryName = queryName;
    }

    public int getQueryAge() {
        return queryAge;
    }

    public void setQueryAge(int queryAge) {
        this.queryAge = queryAge;
    }
}

  创建接口方法:

 List<Student> selectMultiObject(QueryParam queryParam);

  mapper文件sql语句:

<select id="selectMultiObject" resultType="com.hrf.domain.Student">
        select *  from student where name=#{queryName} or id = #{queryAge}
    </select>

  编写测试类

@Test
    public void selectMultiObject(){
       SqlSession session = MybatisUtils.getSqlSession();
       StudentDao dao = session.getMapper(StudentDao.class);
       QueryParam queryParam = new QueryParam();
       queryParam.setQueryName("王五");
       queryParam.setQueryAge(26);
       List<Student> students = dao.selectMultiObject(queryParam);
       for (Student stu : students){
           System.out.println("学生信息"+stu);
           session.close();
       }
   }

  测试结果:

    Mybatis框架Dao代理

 

   3.2.5 [了解]多个参数-按位置

    参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0},第二个是#{arg1

    (注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开 始使用#{arg0}方式。)

        接口方法:

         List selectByNameAndAge(String name,int age);

        mapper 文件:

<select id="selectByNameAndAge" 
resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{arg0} or age 
=#{arg1}
</select>

        测试方法:

@Test
public void testSelectByNameAndAge(){
 //按位置参数 
 List<Student> stuList = studentDao.selectByNameAndAge("李力",20);
 stuList.forEach( stu -> System.out.println(stu));
}

  3.2.6 [了解]多个参数-使用 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);

  接口方法:List selectMultiMap(Map<string,object> map);

   mapper 文件:

<select id="selectMultiMap" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where name=#{myname} or age 
=#{myage}
</select>

  测试方法:

@Test
public void testSelectMultiMap(){
   Map<String,Object> data = new HashMap<>();
   data.put("myname","李力");// #{myname} 
   data.put("myage",20); // #{myage} 
   List<Student> stuList = studentDao.selectMultiMap(data);
   stuList.forEach( stu -> System.out.println(stu));
}

  3.2.7 [掌握] #和$

    #:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的“?”。这样做更 安全,更迅速,通常也是首选做法,

   mapper 文件

<select id="selectById" resultType="com.bjpowernode.domain.Student">
 select id,name,email,age from student where id=#{studentId}
</select>

  转为 MyBatis 的执行是:

    String sql=” select id,name,email,age from student where id=?”;

    PreparedStatement ps = conn.prepareStatement(sql);

     ps.setInt(1,1005);

  解释:

  where id=? 就是 where id=#{studentId}

  ps.setInt(1,1005) , 1005 会替换掉 #{studentId}

  $ 字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的内容连接起来。主要用在替换表名,列名,不同 列排序等操作。

  #{}的特点:

    1)使用的PrepareStatement对象,执行sql语句,效率高

    2)使用的PrepareStatement对象,能避免sql语句,sql语句执行更安全

    3)#{}常常作为列值使用,位于等号右边,#{}位置的值和数据类型有关的

  ${}的特点:

    1)使用Statement对象,执行sql语句,效率低

    2)${}占位符的值,使用的字符串链接方式,有sql注入的风险,有代码安全的问题

    3)${}数据是原样使用的,不会区分数据类型

    4)${}常用做表名或者列名,在能保证数据安全的情况下使用${}

  

示例:

  创建接口方法:

List<Student> queryStudent(@Param("studentId") String name);

  在mapper文件中写sql语句:

<select id="queryStudent" resultType="com.hrf.domain.Student">
        select * from student  order by ${studentId} desc
    </select>

 

  编写测试类方法

@Test
    public void queryStudent(){
       SqlSession session = MybatisUtils.getSqlSession();
       StudentDao dao = session.getMapper(StudentDao.class);
       List<Student> students = dao.queryStudent("id");
       for (Student stu : students){
           System.out.println("stu==>"+stu);
           session.close();
       }
   }

 

  测试结果:

  Mybatis框架Dao代理

 

 

上一篇:盘一盘常见的6种索引失效情况


下一篇:BZOJ 3280: 小R的烦恼 & BZOJ 1221: [HNOI2001] 软件开发