Table of Contents
01 MyBatis映射器:
1.1 接口映射器+xml映射器
1.2 接口映射器+注解
02 接口映射器+xml映射器 方式
2.1 mybatis配置文件 引入映射器:
2.2 XML映射文件 的几个顶级元素:
2.2.1 select元素 以及Select 元素的属性
2.2.2 insert, update 和 delete元素
2.2.3 sql代码段(可复用)
03 简单demo:
3.1 创建数据库:
3.2 mybatis配置文件:mybatisConfig.xml
3.3 实体类User.java:
3.4 持久层接口IUserDao.java:
3.5 对应的XML映射文件:
3.6 编写测试类DemoTest.java:
3.7 运行结果:
04 小结:
映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持XML映射器,所有的SQL语句都必须在XML文件中配置。而从MyBatis 3开始,开始支持接口映射器,其底层利用的是接口绑定技术。另外,接口映射器允许通过注解定义SQL语句,用以替代XML文件配置SQL。
先定义接口映射器,然后再定义xml映射器,其中xml映射器的namespace应该对应接口映射器的类名。
此类形式,将原先xml里面的sql配置信息,变成Java注解的形式写到接口映射器
这里先记录 接口映射器+xml映射文件,后面才写 接口映射器+注解 的笔记
在MyBatis配置文件中包含了
注意:此种⽅法要求mapper接⼝名称和mapper映射⽂件名称相同,且放在同⼀个⽬录中
SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):
cache
– 给定命名空间的缓存配置。cache-ref
– 其他命名空间缓存配置的引用。resultMap
– 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。sql
– 可被其他语句引用的可重用语句块。insert
– 映射插入语句update
– 映射更新语句delete
– 映射删除语句select
– 映射查询语句select 元素允许你配置很多属性来配置每条语句的作用细节。
属性 | 描述 |
---|---|
id | 在命名空间中唯一的标识符,可以被用来引用这条语句。对应接口中的某个方法名 |
parameterType | 将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler) 推断出具体传入语句的参数,默认值为未设置(unset)。 |
resultType | 从这条语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同时使用。 |
resultMap | 外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同时使用。 |
flushCache | 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。 |
useCache | 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。 |
fetchSize | 这是一个给驱动的提示,尝试让驱动程序每次批量返回的结果行数和这个设置值相等。 默认值为未设置(unset)(依赖驱动)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 中的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
resultSetType | FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖驱动)。 |
databaseId | 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。 |
resultOrdered | 这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。 这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。 |
resultSets | 这个设置仅对多结果集的情况适用。它将列出语句执行后返回的结果集并给每个结果集一个名称,名称是逗号分隔的。 |
查询语句是 MyBatis 中最常用的元素之一,简单查询的 select 元素是非常简单的。比如:
- namespace是对应接口的全限定名,于是 MyBatis 上下文就可以通过它找到对应的接口。
- id 标识了这条 SQL,id对应的是接口的某个方法
- resultType="student" 表示返回的是一个 Student 类型的返回值。而 student是配置文件 mybatis-config.xml 配置的别名,指代的是 com.mybatis.domain.Student
- parameterType="long" 说明传递给 SQL 的是一个 long 型的参数
- #{id} 表示传递进去的参数。
注意:这里并没有配置 SQL 执行后和 Student 的对应关系,它是如何映射的呢?其实,这里采用的是一种被称为自动映射的功能,MyBatis在默认情况下提供自动映射,只要SQL返回的列名能和POJO的属性对应起来即可。
数据变更语句 insert,update 和 delete 的实现非常接近:
属性 | 描述 |
---|---|
id | 命名空间中的唯一标识符,可被用来代表这条语句。 |
parameterType | 将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器推断出具体传入语句的参数,默认值为未设置(unset)。 |
flushCache | 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:true(对于 insert、update 和 delete 语句)。 |
timeout | 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖驱动)。 |
statementType | STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。 |
useGeneratedKeys | (仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。 |
keyProperty | (仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认值:未设置(unset)。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 |
keyColumn | (仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望使用多个生成的列,也可以设置为逗号分隔的属性名称列表。 |
databaseId | 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。 |
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where id = #{id}
delete from Author where id = #{id}
首先,如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就 OK 了。例如,如果上面的 Author 表已经对 id 使用了自动生成的列类型,那么语句可以修改为:
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
这个元素可以被用来定义可重用的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。它可以(在加载的时候)被静态地设置参数。 在不同的包含语句中可以设置不同的值到参数占位符上。比如:
${alias}.id,${alias}.username,${alias}.password
这个 SQL 片段可以被包含在其他语句中,例如:
refid="userColumns" 对应sql中的id
public class User {
private int id;
private String username;
private String sex;
private String address;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" +id+
",username=" +username+
",sex=" +sex+
"address=" +address+
"}";
}
}
public interface IUserDao {
/**
* 查找所有用户
* @return
*/
public List findAllUser();
}
注意:此种⽅法要求mapper接⼝名称和mapper映射⽂件名称相同,且放在同⼀个⽬录中
还有,这里个人喜欢叫Dao命名,而不是Mapper,看个人爱好
只要,接⼝名称和映射 ⽂件名称相同,且放在同⼀个⽬录中即可
public class DemoTest {
InputStream inputStream;
SqlSession session;
SqlSessionFactory sqlSessionFactory;
@Before
public void init() throws IOException {
//1.读取配置⽂件
inputStream = Resources.getResourceAsStream("mybatisConfig.xml");
//2.创建SqlSessionFactory的构建者对象,使⽤构建者创建⼯⼚对象SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//3.使⽤SqlSessionFactory⽣产SqlSession对象
session = sqlSessionFactory.openSession();
}
@After
public void destroy() throws IOException{
//6.释放资源
session.close();
inputStream.close();
}
@Test
public void test() throws IOException {
//4.使⽤SqlSession创建dao接⼝的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//5.使⽤代理对象执⾏查询所有⽅法
List users = userDao.findAllUser();
for (User user : users){
System.out.println(user);
}
}
}
@Before、@After、@Test是Junit的注解,@Before是运行前指定执行的方法是public void init(),@After类似
1.映射器只是一个接口,而不是一个实现类。初学者可能会产生一个很大的疑问:接口不是不能运行吗?的确,接口不能直接运行,但是MyBatis内部运用了动态代理技术,生成接口的实现类,从而完成接口的相关功能。只要明白 MyBatis 会为这个接口生成一个代理对象,代理对象会去处理映射器接口相关的逻辑即可。
然后调用mybatis对象SQLSession的getMapper()获取代理对象,调用接口的方法
2.我们并没有配置 SQL 执行后和 User 的对应关系,它是如何映射的呢?其实,这里采用的是一种被称为自动映射的功能,MyBatis在默认情况下提供自动映射,只要SQL返回的列名能和POJO的属性对应起来即可。
后面会讲到当 实体类属性 和 数据库列名 不一一相同 如何 做映射
3.接口绑定,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们直接调用接口方法就可以。
接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上 @Select、@Update等注解,里面包含Sql语句来绑定;另外一种就是通过xml里面写SQL来绑定,在这种情况下,要指定xml映射文件里面的namespace必须为接口的全路径名。
当Sql语句比较简单时候,用注解绑定,当SQL语句比较复杂时候,用xml绑定。
一般情况下,用xml绑定的比较多。
使用MyBatis的mapper接口调用时要注意的事项有:
(1)Mapper接口方法名和mapper.xml中定义的每个sql的id相同;
(2)Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同;
(3)Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同;
(4)Mapper.xml文件中的namespace即是mapper接口的类路径。