dao代理
1.1mybatis提供代理
mybatis创建Dao接口的实现类对象,完成sql语句的执行。mybatis创建一个对象代替你的dao实现类功能。
1.2使用mybatis代理要求
- mapper文件中的namespace一定是dao接口的全限定名称
- mapper文件中标签的id是dao接口方法名称
1.3mybatis代理实现方式
使用SQLSession对象的方法getMapper(dao.class)
例如:现有StudentDao接口
SqlSession session = MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);
//上面的代码
StudentDao dao = session.getMapper(StudentDao.class);
等同于
StudentDao dao = new StudentDaoImpl();
对比
2、参数
参数是通过Java程序把数据传入到mapper文件中的sql语句。参数主要是指dao接口方法的形参。
2.1parameterType
parameterType:写在mapper文件中的 一个属性。 表示dao接口中方法的参数的数据类型。是在mybatis给sql语句的参数赋值时使用。
相当于在JDBC中使用preparedStatement.setXXX(位置,值),制定了XXX的类型
parameterType:mybatis通过反射机制可以获取dao接口方法参数的类型,可以不写
<!--
parameterType:指定dao接口形参的类型,
这个属性值可以使用java类型的全限定名称或者mybatis定义的别名
-->
<select id="selectById" parameterType="java.lang.Integer" resultType="com.fawde.domain.Student">
select id,name,email,age from student where id = #{studentId}
</select>
2.2 一个简单类型的参数
接口: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文件使用 #{自定义参数名 } |
|
例子 |
2.4 多个参数,使用java对象
方法的形参是一个Java对象,这个Java对象表示多个参数,使用对象的属性值作为参数使用
简单语法: #{属性名},mybatis调用此属性的getXXX()方法获取属性值
严格语法:#{属性名,javaType=java类型的全限定名称,jdbcType=mybatis中定义列的数据类型}
2.5 多个参数 按位置
2.6 多个参数 使用 Map
3.1 # 和 $
3.1 #占位符
语法格式:#{字符}
mybatis处理#{}使用jdbc对象是PrepareStatment对象
<select id="selectById" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where id=#{studentId}
</select>
mybatis创建PrepareStatment对象,执行sql语句
String sql = "select id,name,email,age from student where id=?"
PrepareStatment pst =conn.prepareStatment(sql);
pst.setInt(1,1001);//传递参数
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();
![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 />${}特点
- 使用Statment对象,执行sql语句,效率低。
- ${}占位符的值,使用的字符串连接的方式,有sql注入的风险,有代码安全的问题
- ${}数据是原样使用的,不会区分数据类型。
- #{}常常作为表名和列名,在能保证数据安全的情况下使用${}
<br /># 和 $区别<br /> 1. #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高<br /> 2. #能够避免sql注入,更安全。<br /> 3. $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低<br /> 4. $有sql注入的风险,缺乏安全性。<br /> 5. $:可以替换表名或者列名<br />
<a name="iHmiT"></a>
# 4、封装Mybatis输出结果
封装输出结果:MyBatis执行sql语句,得到ResultSet,转为Java对象
<a name="dKAA0"></a>
## 4.1 resultType
| resultType属性:在执行select时使用,作为<select>标签的属性出现的。 |
| --- |
| resultType:表示结果类型,MySQL执行sql语句,得到Java对象的类型,他的值有两种<br />- Java类型的全限定名称<br />- 使用别名<br /> |
```java
Student selectById(Integer id);
<select id="selectById" parameterType="java.lang.Integer" resultType="com.fawde.domain.Student">
select id,name,email,age from student where id = #{studentId}
</select>
resultType:现在使用Java类型的全限定名称,表示的意思是mybatis执行sql,把ResultSet中的数据转为Student类型的对象。mybatis会做以下操作:
1.调用com.fawde.domain.Student的无参数构造方法,创建对象
Student student = new Student();//使用反射机制创建对象
2.同名的列赋值给同名的属性
student.setId(rs.getInt("id"))
student.setName(rs.getInt("name"))
3.得到Java对象,如果dao接口返回值是List集合,mybatis把student对象放入到List集合
所以执行Student mystudent = dao.selectById(1001);
会得到数据库中id=1001这行数据,这行数据的列值赋值给mystudent对象的属性。
=>返回mystudent对象,相当于是id=1001这行数据
4.2 resultMap
resultMap:结果映射,自定义列名和Java对象的对应关系。常用在列名和属性名不同的情况。
用法:
- 先定义resultMap标签,指定列名和属性名称对应关系
- 在select标签使用resultMap属性,指定上面定义的resultMap的id值
4.3 实体类 属性名和列名不同的处理方式
使用列别名 和
使用
4.4 模糊 like
5、自定义别名
mybatis提供了对Java类型定义简短,好记名称
自定义别名的步骤:
1)在mybatis主配置文件,使用typeAliases标签声明别名
<!ELEMENT configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)>
//配置文件是有顺序的,typeAliases应该放在settings后面
<typeAliases>
<!--第一种语法格式
type : Java类型的全限定名称(自定义类型)
alias : 自定义别名
优点:别名可以自定义
缺点:每个类型必须单独定义
-->
<typeAlias type="com.fawde.domain.Student" alias="stu"/>
<!--第二种方式
name:包名,mybatis会把这个包中所有类名作为别名(不用区分大小写)
优点:使用方便,一次给多个类定义别名
缺点:别名不能自定义,必须是类名,有可能重复
-->
<package name="com.fawde.domain"/>
</typeAliases>
2)在mapper文件中,resultType=”别名”
- 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不要一起用,二选一