dao代理

1.1mybatis提供代理

mybatis创建Dao接口的实现类对象,完成sql语句的执行。mybatis创建一个对象代替你的dao实现类功能。

1.2使用mybatis代理要求

  1. mapper文件中的namespace一定是dao接口的全限定名称
  2. mapper文件中标签的id是dao接口方法名称

image.png

1.3mybatis代理实现方式

使用SQLSession对象的方法getMapper(dao.class)
例如:现有StudentDao接口

  1. SqlSession session = MyBatisUtils.getSqlSession();
  2. StudentDao dao = session.getMapper(StudentDao.class);
  3. Student student = dao.selectById(1001);
  4. //上面的代码
  5. StudentDao dao = session.getMapper(StudentDao.class);
  6. 等同于
  7. StudentDao dao = new StudentDaoImpl();

对比

代理
image.png
image.png
传统
image.pngimage.png

2、参数

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

2.1parameterType

parameterType:写在mapper文件中的 一个属性。 表示dao接口中方法的参数的数据类型。是在mybatis给sql语句的参数赋值时使用。
相当于在JDBC中使用preparedStatement.setXXX(位置,值),制定了XXX的类型
image.png
parameterType:mybatis通过反射机制可以获取dao接口方法参数的类型,可以不写

  1. <!--
  2. parameterType:指定dao接口形参的类型,
  3. 这个属性值可以使用java类型的全限定名称或者mybatis定义的别名
  4. -->
  5. <select id="selectById" parameterType="java.lang.Integer" resultType="com.fawde.domain.Student">
  6. select id,name,email,age from student where id = #{studentId}
  7. </select>

2.2 一个简单类型的参数

  1. 接口:public Student selectStudentById(Integer id) <br /> mapper:select id,name, email,age from student where id=#{studentId}

| 定义 |
- 简单类型: mybatis把java的基本数据类型和String都叫简单类型。
- 在mapper文件获取简单类型的一个参数的值,使用 #{任意字符}
| | —- | —- | | 例子 | 接口:public Student selectStudentById(Integer id)
mapper:select id,name, email,age from student where id=#{studentId} |

2.3 多个参数,使用@Param命名参数

@Param 命名参数,在方法的形参前面使用的,定义参数名。这个名称可以用在mapper.

在方法形参前面加入 @Param(“自定义参数名”)
mapper文件使用 #{自定义参数名 }
例子 image.png


2.4 多个参数,使用java对象

方法的形参是一个Java对象,这个Java对象表示多个参数,使用对象的属性值作为参数使用
简单语法: #{属性名},mybatis调用此属性的getXXX()方法获取属性值
严格语法:#{属性名,javaType=java类型的全限定名称,jdbcType=mybatis中定义列的数据类型}
image.png

2.5 多个参数 按位置

image.png

2.6 多个参数 使用 Map

image.png
image.png

3.1 # 和 $

3.1 #占位符

语法格式:#{字符}
mybatis处理#{}使用jdbc对象是PrepareStatment对象

  1. <select id="selectById" resultType="com.bjpowernode.domain.Student">
  2. select id,name,email,age from student where id=#{studentId}
  3. </select>
  4. mybatis创建PrepareStatment对象,执行sql语句
  5. String sql = "select id,name,email,age from student where id=?"
  6. PrepareStatment pst =conn.prepareStatment(sql);
  7. pst.setInt(1,1001);//传递参数
  8. ResultSet rs =pst.executeQuery();

{}特点

  • 使用PrepareStatment对象,执行sql语句,效率高。
  • 使用PrepareStatment对象,能避免sql语句,sql语句执行更安全
  • {}常常作为列值使用的,位于等号的右侧,#{}位置的值和数据类型有关

    3.2 $占位符

    语法格式:${字符}
    mybatis执行${}占位符sql语句 ```java

${}表示字符串连接,把sql语句的其他内容和${}内容使用字符串(+)连接的方式连在一起

String sql=”select id,name, email,age from student where id=” + “1001”;

mybatis 创建Statement对象,执行sql语句。 Statement stmt = conn.createStatement(sql); ResultSet rs =stmt.executeQuery();

  1. ![image.png](https://cdn.nlark.com/yuque/0/2021/png/21675987/1634866337350-5aad34ae-bd43-4c7c-bbfc-befe0a4dfc32.png#clientId=u952e7c0a-148f-4&from=paste&height=374&id=u2d6a77ed&margin=%5Bobject%20Object%5D&name=image.png&originHeight=537&originWidth=985&originalType=binary&ratio=1&size=85022&status=done&style=none&taskId=u02b9ff4a-e4c0-4a15-9cf6-b5c63ed97ba&width=686.4999694824219)<br />${}特点
  2. - 使用Statment对象,执行sql语句,效率低。
  3. - ${}占位符的值,使用的字符串连接的方式,有sql注入的风险,有代码安全的问题
  4. - ${}数据是原样使用的,不会区分数据类型。
  5. - #{}常常作为表名和列名,在能保证数据安全的情况下使用${}
  6. <br /># $区别<br /> 1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高<br /> 2. #能够避免sql注入,更安全。<br /> 3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低<br /> 4. $有sql注入的风险,缺乏安全性。<br /> 5. $:可以替换表名或者列名<br />
  7. <a name="iHmiT"></a>
  8. # 4、封装Mybatis输出结果
  9. 封装输出结果:MyBatis执行sql语句,得到ResultSet,转为Java对象
  10. <a name="dKAA0"></a>
  11. ## 4.1 resultType
  12. | resultType属性:在执行select时使用,作为<select>标签的属性出现的。 |
  13. | --- |
  14. | resultType:表示结果类型,MySQL执行sql语句,得到Java对象的类型,他的值有两种<br />- Java类型的全限定名称<br />- 使用别名<br /> |
  15. ```java
  16. Student selectById(Integer id);
  17. <select id="selectById" parameterType="java.lang.Integer" resultType="com.fawde.domain.Student">
  18. select id,name,email,age from student where id = #{studentId}
  19. </select>
  20. resultType:现在使用Java类型的全限定名称,表示的意思是mybatis执行sql,把ResultSet中的数据转为Student类型的对象。mybatis会做以下操作:
  21. 1.调用com.fawde.domain.Student的无参数构造方法,创建对象
  22. Student student = new Student();//使用反射机制创建对象
  23. 2.同名的列赋值给同名的属性
  24. student.setId(rs.getInt("id"))
  25. student.setName(rs.getInt("name"))
  26. 3.得到Java对象,如果dao接口返回值是List集合,mybatis把student对象放入到List集合
  27. 所以执行Student mystudent = dao.selectById(1001);
  28. 会得到数据库中id=1001这行数据,这行数据的列值赋值给mystudent对象的属性。
  29. =>返回mystudent对象,相当于是id=1001这行数据

image.png
image.png

4.2 resultMap

resultMap:结果映射,自定义列名和Java对象的对应关系。常用在列名和属性名不同的情况。
用法:

  1. 先定义resultMap标签,指定列名和属性名称对应关系
  2. 在select标签使用resultMap属性,指定上面定义的resultMap的id值

image.png

4.3 实体类 属性名和列名不同的处理方式

使用列别名 和

image.png

使用

image.png

4.4 模糊 like

image.png
image.png

5、自定义别名

mybatis提供了对Java类型定义简短,好记名称
自定义别名的步骤:
1)在mybatis主配置文件,使用typeAliases标签声明别名

  1. <!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
  2. //配置文件是有顺序的,typeAliases应该放在settings后面
  1. <typeAliases>
  2. <!--第一种语法格式
  3. type : Java类型的全限定名称(自定义类型)
  4. alias : 自定义别名
  5. 优点:别名可以自定义
  6. 缺点:每个类型必须单独定义
  7. -->
  8. <typeAlias type="com.fawde.domain.Student" alias="stu"/>
  9. <!--第二种方式
  10. name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写)
  11. 优点:使用方便,一次给多个类定义别名
  12. 缺点:别名不能自定义,必须是类名,有可能重复
  13. -->
  14. <package name="com.fawde.domain"/>
  15. </typeAliases>

2)在mapper文件中,resultType=”别名”
image.png
image.png

  1. mybatis的输出结果
    mybatis执行了sql语句,得到java对象。

    1)resultType结果类型, 指sql语句执行完毕后, 数据转为的java对象, java类型是任意的。
    resultType结果类型的它值 1. 类型的全限定名称 2. 类型的别名, 例如 java.lang.Integer别名是int


    处理方式:
    1. mybatis执行sql语句, 然后mybatis调用类的无参数构造方法,创建对象。
    2. mybatis把ResultSet指定列值付给同名的属性。




    对等的jdbc
    ResultSet rs = executeQuery(“ select id,name, email,age from student” )
    while(rs.next()){
    Student student = new Student();
    student.setId(rs.getInt(“id”));
    student.setName(rs.getString(“name”))
    }

    2) 定义自定义类型的别名
    1)在mybatis主配置文件中定义,使定义别名
    2)可以在resultType中使用自定义别名


    3)resultMap:结果映射, 指定列名和java对象的属性对应关系。
    1)你自定义列值赋值给哪个属性
    2)当你的列名和属性名不一样时,一定使用resultMap


    resultMap和resultType不要一起用,二选一