6、MyBatis的SQL映射(mapper)⽂件
学习资源:动⼒节点
⽬录
MyBatis 的真正强⼤在于它的映射语句,也是它的魔⼒所在。由于它的异常强⼤,映射器的 XML ⽂件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进⾏对⽐,你会⽴即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且⽐普通的⽅法做的更好。
SQL 映射⽂件有很少的⼏个顶级元素(按照它们应该被定义的顺序):
cache:给定命名空间的缓存配置。
cache-ref:其他命名空间缓存配置的引⽤。
resultMap – 是最复杂也是最强⼤的元素,⽤来描述如何从数据库结果集中来加载对象。
parameterMap:已废弃!⽼式风格的参数映射。
sql:可被其他语句引⽤的可重⽤语句块。详见:
insert:映射插⼊语句
update:映射更新语句
delete:映射删除语句
select:映射查询语
1、指定约束⽂件
mybatis-3-mapper.dtd 是约束⽂件的名称,扩展名是 dtd。
<!DOCTYPE mapper
PUBLIC "-////DTD Mapper 3.0//EN"
"/dtd/mybatis-3-mapper.dtd">
开发技术flask框架约束⽂件作⽤:限制和检查在当前⽂件中出现的标签,属性必须符合 MyBatis 的要求。
2、Mapper标签
<mapper> 标签是 SQL 映射⽂件的根标签,对应 dao 包下的⼀个接⼝,在这个标签内部使⽤ sql 对应实现 dao 接⼝中的⽅法即可。
<mapper namespace="">
CRUD操作
<mapper>
namespace
意为命名空间,是<mapper>标签的⼀个属性,⽤于绑定连接 SQL 映射⽂件和 dao 接⼝。
⼀个 dao 接⼝对应⼀个 SQL 映射⽂件,所以为了区分不同的 dao 接⼝,命名空间要求是唯⼀的,推荐使⽤ dao 接⼝的全限定名称(可以⾃定义)。
<mapper namespace="com.chen.dao.StudentDao">
CRUD操作
<mapper>
3、CRUD
mysql语句的执行顺序MyBatis 默认不⾃动提交事务,所以 update、insert、delete 执⾏后需要⼿动 commit
在 SQL 映射⽂件中,只需要使⽤对应的标签语句写出我们要实现的 dao 接⼝的⽅法,之后再借助 MyBatis的 dao 动态代理,即可在 Java 代码中执⾏ dao 接⼝的⽅法。
CRUD 操作在 MyBatis 的帮助下,是很容易实现。但是 MyBatis 的 CRUD 语句也有⼀些复杂的部分:传参、返回值。
3.1、select
简单的 select 语句:
<select id="selectStudents" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student
</select>
Java 代码执⾏:
// 查询所有学⽣信息
// 返回值问题有些复杂
List<Student> = dao.selectStudents();
3.2、insert
简单的 insert 语句:
<insert id="insertStudent">
insert into student values (#{id},#{name},#{email},#{age})
</insert>
Java 代码执⾏:
// 插⼊⼀条学⽣信息
// 返回值表⽰执⾏ insert 后,影响数据库数据的⾏数
int rows = dao.insertStudent(new Student(1006, "lisa", "5981956@163", 24));
3.3、update
fontcreator怎么导入字体简单的 update 语句:
<update id="updateStudent">
update student set age = #{age} where id=#{id}
</update>
Java 代码执⾏:
// 更新 id 是 1001 的学⽣年龄为 37
// 返回值表⽰执⾏ update 后,影响数据库数据的⾏数
int rows = dao.updateStudent(1001, 37);
3.4、delete
简单的 delete 语句:
<delete id="deleteStudent">
delete from student where id=#{studentId}
</delete>
Java 代码执⾏:
// 删除 id 是 1002 的学⽣
// 返回值表⽰执⾏ insert 后,影响数据库数据的⾏数
int rows = dao.deleteStudent(1002);
4、# 和 $
4.1、#
#:占位符,告诉 mybatis 使⽤实际的参数值代替,并使⽤ PrepareStatement 对象执⾏ sql 语句, #{…} 代替 sql 语句的“?”。 这样做更安全、更迅速,通常也是⾸选做法。mapper⽂件:
<select id="selectStudentById" resultType="com.bjpowernode.domain.Student">
select id,name, email,age from student where id=#{studentId}
<\select>
mapper ⽂件转为 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}
4.2、$
$:字符串替换, 告诉 mybatis 使⽤ ${} 包含的“字符串”替换所在位置,使⽤ Statement 把 sql 语句和 ${} 的内容连接起来。
$ 主要⽤在替换表名,列名,不同列排序等操作。
使⽤实例1:分别使⽤ id , email 列查询 Student
接⼝⽅法
Student findById(int id);
mapper⽂件
<select id="findById" resultType="com.bjpowernode.domain.Student">
select * from student where id=${studentId}
</select>
mapper ⽂件转为 MyBatis 的执⾏是:
String sql="select id,name, email,age from student where id"+"1001";
Statement st = conn.statement(sql);
使⽤实例2:通⽤⽅法,使⽤不同列作为查询条件
磷是人体的常量元素吗
接⼝⽅法
Student findByDiffField(@Param("col") String colunName,@Param("cval") Object value);
mapper ⽂件:
<select id="findByDiffField" resultType="com.bjpowernode.domain.Student">
select * from student where ${col} = #{cval}
</select>
4.3、对⽐
# 使⽤?在sql语句中做站位的,使⽤ PreparedStatement 执⾏ sql,效率⾼
$ 不是占位符⽅式,⽽是字符串连接得⽅式,使⽤ Statement 对象执⾏ sql,效率低
# 能够避免 sql 注⼊,更安全;$ 有sql注⼊的风险,缺乏安全性
# ⼀般⽤来占位 sql 语句中 = 后⾯字段的值;$⼀般⽤来替换 sql 语句中的表名或者列名
5、传参问题
从 Java 代码中把接⼝的⽅法参数传递到 l ⽂件,需要遵守的规范
5.1、parameterType 属性
parameterType 是 CRUD 标签语句的⼀个属性,它对应 dao 接⼝中⽅法参数的类型,对应⽅法参数的类型不同,parameterType 也有不同的值对应,⼀般赋值为⽅法参数类型的全限定名或别名。如:
<select id="selectStudentById" parameterType="java.lang.Integer" resultTytpe="com.bjpowernode.domain.Student">
select id, name, email, age from student where id = #{id}
一级网站和二级网站的区别</select>
MyBatis 默认⽀持的别名(MyBatis 内部定义):
别名映射类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map/HashMap
但是对于⼤多数简单的使⽤场景,MyBatis 通过反射机制都能够发现接⼝⽅法的参数的类型,所以 parameterType 属性⼀般也不需要赋值。
5.2、传递⼀个简单类型的参数
Dao 接⼝中⽅法的参数是⼀个简单类型的参数(Java 基本类型和 String),那么在 l ⽂件中要获取这个参数,只需要使⽤占位符 #{ 任意字符 }即可获取,括号中的内容和⽅法的参数名⽆关。如:
接⼝⽅法:
Student selectById(int id);
mapper⽂件:
mapper ⽂件:
<select id="selectById" resultType="com.bjpowernode.domain.Student">
<!-- #{studentId} , studentId 是⾃定义的变量名称,和⽅法参数名⽆关 -->
select id,name,email,age from student where id=#{studentId}
</select>
sql update语句示例使⽤ #{} 之后, MyBatis 执⾏ sql 是使⽤ JDBC 中的 PreparedStatement 对象
由 MyBatis 执⾏下⾯的代码:
MyBatis 创建 Connection,PreparedStatement 对象
String sql="select id,name, email,age from student where id=?";
PreparedStatement pst = conn.preparedStatement(sql);
pst.setInt(1,1001);
执⾏ sql 封装为 resultType="com.bjpowernode.domain.Student" 这个对象 ResultSet rs = ps.executeQuery()
Student student = null;
()){
// 从数据库取表的⼀⾏数据,存到⼀个java对象属性中
student = new Student();
student.Int("id));
student.String("name"));
student.String("email"));
student.Int("age"));
}
return student;  // 给了dao⽅法调⽤的返回值
所以说,MyBatis 是封装的 JDBC 操作。
5.3、传递多个参数,使⽤ @Param
当 Dao 接⼝⽅法有多个参数,则需要通过名称使⽤参数。 在⽅法的所有形参前⾯加⼊ @Param(“⾃定义参数名”) ,那么在 mapper ⽂件使⽤ #{⾃定义参数名},l ⽂件就可以获取到这个参数。
使⽤实例:
接⼝⽅法:
public List<Student> selectStudentsByMulitParam(@Param("stuName"), String name, @Param("stuAge") Integer age);
mapper⽂件:
<select id="selectStudentByMulitParam" resultTtpe="com.bjpowernode.domain.Student">
select * from student where name=#{stuName} or age=#{stuAge}
</select>
5.4、传递多个参数,使⽤对象
使⽤ java 对象传递参数,java 的属性值就是 sql 需要的参数值,每⼀个属性就是⼀个参数,语法格式:#{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 } 。因为 javaType、jdbcType 的类型 MyBatis 都可以检测出来,所以⼀般不需要设置。 简化后的格式为: #{对象的属性} 。
可传递的的 Java 对象参数是灵活的,只需要 sql 映射语句的参数和对象的属性名⼀致即可。
使⽤实例:
创建保存参数值的对象 QueryParam :
public class QueryParam {
private String queryName;
private int queryAge;
//set , get ⽅法
}
接⼝⽅法:
List<Student> selectMultiObject(QueryParam queryParam);
mapper ⽂件:
<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student
where name=#{queryName,javaType=string,jdbcType=VARCHAR}
or age =#{queryAge,javaType=int,jdbcType=INTEGER}
</select>
<!-- 简化写法 -->
<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
select id,name,email,age from student where name=#{queryName} or age=#{queryAge}
</select>
5.5、传递多个参数,按位置
接⼝⽅法的参数位置从 0 开始, 引⽤参数语法 #{ arg 位置 } , 第⼀个参数是#{arg0},第⼆个是#{arg1}。
注意: mybatis3.3 版本和之前的版本使⽤ #{0} ,#{1} ⽅式, 从 mybatis3.4 开始使⽤ #{arg0} ⽅式。
但是传递多个参数的话,还是推荐使⽤ @Param 或 使⽤对象传参。
使⽤实例:
接⼝⽅法:
List<Student> 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>
5.6、传递多个参数,使⽤ Map
Map 集合可以存储多个值,使⽤ Map 可以向 mapper ⽂件⼀次传⼊任意多个参数。
Map 集合使⽤ String的 <key,Object> 类型的值存储参数。
mapper ⽂件使⽤ #{key} 引⽤ Map 中的数据。
使⽤实例:
定义⼀个 Map
Map<String,Object> data = new HashMap<String,Object>();
data.put(“myname”,”李⼒”);
data.put(“myage”,20);
接⼝⽅法
List<Student> 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>
不推荐使⽤ Map 传参的原因:
Map 的 key 定义具有随意性,key 的改变会引起占位符的改变
⽅法的参数是⼀个 Map ,⽆法直接确定该⽅法的参数个数、参数的类型,可读性很差
6、封装 MyBatis 的输出结果(查询结果)
在 MyBatis 中执⾏了 sql 语句,都会有返回⼀个 Java 对象: select 返回⼀个复杂的 Java 对象, update、 insert、 delete 返回⼀个整型值。那么我们应该如何为 MyBatis 指定返回值类型呢?
6.1、resultType
reslutType 是 <select> 标签的⼀个属性,只有 <select> 标签具有这个属性,并且必须要为这个属性赋值。
reslutType 是⽤于指定执⾏ sql 后得到的 ResultSet 转换为 Java 对象,这个 Java 对象的类型,指定
类型使⽤全限定名或类型的别名。reslutType 对返回结果的处理⽅式:
MyBatis 执⾏ sql 语句,然后调⽤实体类的⽆参构造⽅法,创建⼀个该类的空对象
MyBatis 把 ResultSet 的列值通过 setter 赋给对象的同名属性
6.1.1、返回简单类型
简单类型:Java 基本类型和 String。
别名映射类型
_byte byte
_long long

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。