mybatis 框架是现在比较流行的一个持久层框架,以下是我自己写的一些总结,主要讲的时它的使用方式,详细资料请访问他们的官网。
mybatis 是一个优秀的基于 java 的持久层框架,它内部封装了 jdbc,使开发者只需要关注 sql 语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement
等繁杂的过程。
mybatis 通过 xml 或注解的方式将要执行的各种 statement
配置起来,并通过 java 对象和 statement
中sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java 对象并返回。
采用 ORM 思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。
ORM:
Object Relational Mappging 对象关系映射
简单的说:就是把数据库表和实体类及实体类的属性对应起来让我们可以操作实体类就实现操作数据库表。
它的使用方法分为两种一种是 xml 配置文件,另一种是直接使用注解。
这两种方式各有优势,其中 xml 配置文件的优势在于思路清晰,维护方便,在需要修改项目时,不需要重新编译,只需要修改配置文件即可;而注解开发,因为不需要去配置文件,所以它的开发速度更快,也是因为这点,近几年来也更流行使用注解开发。
首先是主配置文件编写,以及需要注意的地方。在配置完之后,就可以选择两种不同开发方式了。
properties
标签配置时,我们可以配置文件来指定属性配置。这样,下面的数据库信息就可以引用配置文件,方便以后修改。typeAliases
标签,我们可以也可以采用自定义别名的方式来开发,别名不区分大小写。mappers
标签有两种子标签
mapper
标签里面有两个常用属性(注意:资源路径之间用/分隔,包路径用.分隔。)
mapper
标签里的的 resource
属性使用相对于类路径的资源,使用 xml 开发时才使用。mapper
标签里的的 class
属性使用 mapper
接口类路径,使用注解开发时才使用。(注意:此种方法要求 mapper
接口名称和 mapper
映射文件名称相同,且放在同一个目录中。)package
标签里的 name
属性指定包下的所有 mapper
接口,两种开发方式均可使用,也更为常用,它可以用来替代 mapper
标签。(注意:此种方法要求 mapper
接口名称和 mapper
映射文件名称相同,且放在同一个目录中。)只是写了映射配置文件的编写以及其中需要注意的地方。
mapper
标签时,其中的 namespace
属性必须是 dao 类的全限定类名,因为 mabatis 框架是根据 namespace
属性和 statemen
标签中的 id
属性来对数据库进行操作的,也就是根据com.itheima.dao.IUserDao.findAll 反射来确定的。resultMap
标签来指定列名及其对应的变量名,当我们在对查询结果封装需要用到它时,就可以直接使用 resultMap
属性来引用它,如果不需要时,就可以直接使用 resultType
属性来直接指定所要封装的类。insert
delete
update
select
四种标签
#{xxx}
来作为占位符使用,当只有一个条件时,花括号里的内容可以随便写,当有多个条件时,花括号里的内容就必须与实体类中的变量名相同。#{name}
或'%${value}%'
,前者花括号内可以随便写,而后者必须写 value
,但是前者的 % 符号只能在 java 语句中去拼接,而后者就可以在配置文件中写好。
where
标签是用来代替 sql 语句中的 where
或者 and
关键字的,它会根据实际情况判断。if
标签是用来判断是否需要用到这个条件时的。foreach
标签就是进行范围查询时使用,其中的 collection
属性对应实体类中的变量名,open
和 close
属性就是单纯的拼接,item
属性是指定每一个遍历的变量名,separator
属性是指定分隔符。标签体中的内容与就是每一次遍历的占位符,花括号里的内容与 item
属性保持一致。在 mybatis 中只有一对一和一对多,它将多对多当成了多个一对多,而多对一就是多个一对一。
association
标签来指定关联的对应表的单条数据,其中的 property
属性对应实体类中的变量名,column
属性对应关联的外键名称,javaType
指定要封装的实体类。在标签体中,必须先写从表的主键列。
collection
标签来指定关联的对应表的多条数据,其中其中的 property
属性对应实体类中的变量名,ofType
指定每一条数据所要封装的实体类。在标签体中,必须先写从表的主键列。延迟加载就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载。在一对多时通常采用延迟加载,而在一对一时通常采用立即加载,因为这样能提高数据库性能。
首先要在主配置文件中开启延迟加载
然后在映射文件中进行配置
association
标签或者是 collection
标签中添加 select
属性来指定关联的表需要用到哪个方法来查询,即对应的类的dao接口的全限定名.方法名,以及 column
属性来指定关联的外键名称。可以省去我们在多表查询时编写复杂的 sql 语句。在使用注解开发时,不要有映射配置文件的存在,否则程序会以为你要使用 xml 配置文件开发。
public interface IUserDao {
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "sex",property = "userSex"),
@Result(column = "birthday",property = "userBirthday")
})
List findAll();
@Select("select * from user where id=#{id} ")
@ResultMap("userMap")
User findById(Integer userId);
}
@Insert
@delete
@Update
@Select
四种注解。@Results
标签来指定列名及其对应的变量名。当其它的方法在对查询结果封装需要用到它时,就可以直接使用 @ResultMap
注解来引用它。@Select("select * from user where id=#{id} ")
@ResultMap("userMap")
User findById(Integer userId);
@Select("select * from user where username like #{username} ")
@ResultMap("userMap")
List findUserByName(String username);
#{xxx}
来作为占位符使用,当只有一个条件时,花括号里的内容可以随便写,当有多个条件时,花括号里的内容就必须与实体类中的变量名相同。#{name}
,花括号内可以随便写。使用注解进行动态 sql 语句查询时,需要用到上述 xml 开发方式里的动态 sql 语句查询的标签,并且将其置于
标签中,将其当作脚本执行,使用起来极其不便,不推荐使用。
@Select("select * from account")
@Results(id="accountMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column = "uid",
one=@Oneselect(select="com.itheima.dao.IUserDao.findById",
fetchType= FetchType.EAGER))
})
List findAll();
在一对一查询时,使用 @Result
注解来指定关联的对应表的单条数据,其中的 property
属性对应实体类中的变量名,column
属性对应关联的外键名称,然后在注解中使用@One
注解添加 select
属性来指定关联的表需要用到哪个方法来查询,即对应的类的dao接口的全限定名.方法名,以及 fetchType
属性来指定加载方式。
@Select("select * from user")
@Results(id="userMap",value={
@Result(id=true,column = "id",property = "userId"),
@Result(column = "username",property = "userName"),
@Result(column = "address",property = "userAddress"),
@Result(column = "sex",property = "userSex"),
@Result(column = "birthday",property = "userBirthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "com.itheima.dao.IAccountDao.findAccountByUid",
fetchType = FetchType.LAZY))
})
List findAll();
在一对多查询时,使用 @Result
注解来指定关联的对应表的单条数据,其中的 property
属性对应实体类中的变量名,column
属性对应关联的外键名称,然后在注解中使用@Many
注解添加 select
属性来指定关联的表需要用到哪个方法来查询,即对应的类的dao接口的全限定名.方法名,以及 fetchType
属性来指定加载方式。