一:Mybatis简介
1.1 传统的JSBC编程
JDBC是由SUN公司提出的一系列规范,它只定义了接口规范,具体实现是由各个数据库厂商自己去实现的。JDBC是一种典型的桥接模式。
使用传统JDBC方式的弊端:1.工做量大。2.对异常捕获并且关闭资源!
1.2 ORM模式
由于JDBC模式的各种弊端,出现了对象关系映射(ORM)。ORM模型就是数据库的表和简单的java对象的映射关系模型,简称POJO。
1.3 hibernate
hibernate是通过配置文件,把数据库的数据直接映射到POJO上。是全表映射框架。
hibernate的缺陷:
1.全表映射带来的不方便,比如更新时需要发送所有的字段
2.无法根据不同的条件组装不同的sql
3.对多表和赋值的sql查询支持较差,需要自己写sql,返回后,需要自己讲数据组装为POJO
4.不能有效的支持存储过程
5.虽然有HQL,但是性能较差,大型互联网系统往往需要优化SQL,而Hibernate做不到。
1.4 mybatis
mybatis是半自动映射框架,需要手动匹配提供POJO,SQL和映射关系。Mybatis的前身是iBatis。mybatis可以自动完成映射,如果实体名和返回对象对应字段名相同。使用时,只需要一个接口,无需实现类。
所以一般大型的javaWeb的网站,都使用Mybatis。
二:MyBatis入门
2.1 核心组件
.SqlSessionFactoryBuilder:创建SqlSessionFactory
.SqlSessionFactory:创建SqlSession(会话)
.SqlSession:keyi:可以发送sql去执行并返回结果,也可以获取Mapper接口。
.SQL Mapper:由java接口和XML文件构成,需要给出对应的SQL和映射规则。他负责发送SQL去执行,并返回结果。
2.2 映射器
映射器是由Java接口和XML文件共同组成的。
2.3 生命周期
2.3.1 SqlSessionFactoryBuilder
SqlSessionFactoryBuilder就是利用XML或者Java】编码获得资源来构建SqlSessionFactory的,就是构造器的作用。所以,用完就可以回收,所以声明周期只存在于方法内部。2.3.2 SqlSessionFactory
作用是创建SqlSession,而SqlSession是一个会话,每次访问数据库,都要通过SqlSessionFactory创建SqlSession,所以SqlSessionFactory存在于整个生命周期。2.3.3 SqlSession
是一个会话。生命周期是在请求数据库处理事务的过程中。2.3.4 Mapper
Mapper是一个接口,作用就发送sql,返回我们要的结果。所以她是在一个sqlsession事务方法中,是方法界别。
第三章 配置
<?xml version="1.0" encoding = "UTF-8"?>
<configuration> <!-- 配置 -->
<properties/> <!-- 属性 -->
<setting/> <!-- 设置 -->
<typeAliases/> <!-- 类型命名 -->
<typeHandlers/> <!-- 类型处理器 -->
<objectFactory/> <!-- 对象工厂 -->
<plugins/> <!-- 插件 -->
<environments> <!-- 配置环境 -->
<environment> <!-- 配置变量 -->
<transactionManager/> <!-- 事务管理器 -->
<dataSource/> <!-- 数据源 -->
</environment>
</environments>
<databaseIdProvider/> <!-- 数据库厂商标识 -->
<mappers/> <!-- 映射器 -->
</configuration>
3.1 properties元素
配置属性的元素,让我们能在配置文件的上下文中使用它。
3.1.1 property 子元素
就是配置数据库四大参数。数据库driver、url、password、username
3.1.2 参数优先级
Mybatis加载配置参数如果出现重复设置了,后加载的参数会覆盖先加载的参数
加载顺序是
1:直接在配置文件里配置的properties元素。
2:根据propertie元素中是resource属性读取的其他属性文件里设置的属性。
3:读取作为方法参数传递的参数。
所以优先级(从高到低)是:
1.读取作为方法参数传递的属性,并覆盖同名属性
2.根据propertie元素中是resource属性读取的其他属性文件里设置的属性。
3.直接在配置文件里配置的properties元素。
不建议使用多出设置参数,容易混乱,首选使用properties文件。
3.2 设置
mybatis的别名是不区分大小写的
别名就是用一个简单的字符串去替代一些很长的字符串,比如类路路径"cn.wzl.nulidexiaoma.model.User",我们设置别名user来替代。某些时候会大大降低我们的工作。
3.2.1 系统别名
mybatis框架自动为我们定义好的别名:比如Byte,系统自动定义的别名是byte。
3.2.2 自定义别名
自定义别名有两种途径
方法一:在配置文件直接配置
比如我想给User类设置一个别名
在配置文件中配置
<typeAliases>
<typeAlias alias="user" type="cn.wzl.nulidexiaoma.model.User"/>
<typeAliases>
这时,user类的类路径就可以用user来表示。
方法二:通过注释@Alias实现
在User实体类上注解,
@Alias("user")
public class User implements Serializable {}
并且在配置文件上配置注解的类在哪个包下面,让mybatis扫描对应的包去解析注解
<typeAliases>
<package name="cn.wzl.nulidexiaoma.model"/>
<typeAliases>
这种方法适合需要自定义多个别名的时候,建议使用第二种。
3.4 typeHandler类型处理器
typeHandler就是将数据库查到的结果,转换成对应的java类型。就是jdbcType转变成javaType
3.4.1 系统定义的typeHandler
同上,系统默认帮我们设置了很多类型处理器,比如StringTypeHandler,所以我们平常用mybatis的时候都不需要我们自己设置,直接使用系统自带的就可以满足需求了。
使用系统定义的类型处理区要注意:
.数值类型的精度:数据库的int、double、decimal这些类型和java的精度长度都是不一样的。
.时间精度,取数据到日用DareOnlyTypeHandler即可,用到精度为秒的用SqlTimestampTypeHandler等
但是不排除以后碰到一些需要对数据库查到的数据进行其他处理的逻辑,所以我们需要学会重写覆盖类型处理器。
3.4.2 自定义typeHandler
自定义的步骤如下:
1.在配置文件上配置
<typeHandlers>
<typeHandler jdbcType="VARCHAR" javaType="string" handle="com,learn.chapter3.typeHandler.MyStringTypeHandler"/>
</typeHandlers>
从上面的配置可以猜出,处理的数据库类型是VARCHAR,java参数对应的类型是String,我们会使用MyStringTypeHandler类去进行处理。
有时候有多个typeHandler配置这个太麻烦,可以直接配置让mybatis去扫描我们放置typeHandler类的包。
<typeHandlers>
<package name="com,learn.chapter3.typeHandler"/>
</typeHandlers>
2.MyStringTypeHandler需要继承org.apache.ibatis.type.Base.TypeHandler来实现。去实现方法就可以了。
注意在自定义typeHandler类上面需要配置注释
1.@MappedTypes:指定哪些java类型被拦截
2.@MappedJdbcTypes:指定jdbcType的类型,此类型必须是存在于枚举类org.apache.ibatis.type.JdbcType里所罗列的枚举类型。
3.在结果集映射中需要定义那些实体类属性需要使用这个typeHandler。
这一步有三种方式:
方式1:直接在映射集里面定义具体typeHandler
<result column="name" property="name"
typeHandler="cn.wzl.nulidexiaoma.common.typehandler.MyStringTypeHandler"/>
方式2:在结果集的映射里面设置jdbcType和javaType
<result
column="name" property="name" javaType="string"
jdbcType="VARCHAR" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
这种配置要求javaType和jdbcType要和配置文件中配置的一模一样才能匹配到。
方式3:直接在sql语句参数设置具体的typeHandler
<insert id="insertUserByRemarkTypeHandler" parameterType="cn.wzl.nulidexiaoma.model.User">
insert into `user`(remark)
values(
#{remark,typeHandler=cn.wzl.nulidexiaoma.common.typeHandler.UserRemarkTypeHandler})
</insert>
3.4.3 枚举类型typeHandler
在mybatis中,枚举类型的typeHandler有自己特殊的规则。
mybatis内部提供了两个转化枚举类型的typeHandler给我们使用
org.apache.ibatis.type.EnumTypeHandler
org.apache.ibatis.type.EnumOrdinalTypeHandler
配置内容:和上面一样,只是把对应的typeHandler类名改成上诉类名就可以。这个类型处理器处理的是枚举类型。比如性别sex,我们不能还和往常一样直接String sex,而是要定义一个枚举类型sex。
两个类的区别就是,EnumTypeHandler插入数据库的是枚举对应的字符串,而EnumOrdinalTypeHandler是数字。
3.5 ObjectFactory
在Mybatis构建一个结果返回的时候,都会使用ObjectFactory(对象工厂)去构建POJO,我们也可以定制自己的对象工厂,但是一般自己用mybatis默认提供的就可以了。
自己定制对象工厂:和typeHandler很类似
在配置文件配置:
<ObjectFactory type="cn.wzl.nulidexiaoma.objectfactory.MyObjectFactory">
<property name="name" value="MyObjectFactory"/>
</ObjectFactory>
自己定义的MyObjectFactory类实现DefaultObjectFactory类,然后重写方法。
3.6 插件(后续再说)
3.7 environment配置环境
数据源:1.数据库源的配置 2:数据库事务的配置
transactionManager配置的是数据库事务,其中type有三种配置方式
1:JDBC
2:MANAGED 容易管理,在JNDI数据源中常用
3:自定义
dataSource:配置数据源连接的信息,type有四种方式
1:UNPOOLED:非连接池数据库
2:POOLED:连接池数据库
3:JNDI:JNDI数据源
4:自定义数据源
3.8 引入映射器
映射器就是我们在dao层写的Mapper文件。
引入这些配置文件有四种方式
方式1:在配置文件里用文件路径直接一个一个配置
<mappers>
<mapper resource="cn/wzl/nulidexiaoma/dao/user/UserMapper.xml">
</mappers>
方式2:直接要求mybatis去扫描指定包,自动加载所有的mapper(常用这种)
<mappers>
<package resource="cn.wzl.nulidexiaoma.dao">
</mappers>
方式3:用类名引入
<mappers>
<mapper resource="cn.wzl.nulidexiaoma.dao.user.UserMapper.xml">
</mappers>
方式4:用url引入
<mappers>
<mapper url="file:///var/mapper/cn/wzl/nulidexiaoma/dao/user/UserMapper.xml">
</mappers>
四:映射器
4.1
mybatis中的映射器大体就下面几个
select
insert
update
delete
parameterMap
sql
resultMap
cache
cache-ref
每个映射器有id属性作为唯一标识。paramterType作为参数类型,resultType是返回数值类型。
4.2 自动映射
有这么一个参数autoMappingBehavior,当它不设置为NONE的时候。Mybatis会提供自动映射功能。只要返回的sql列名和JavaBean属性一致,Mybatis就会帮助我们回填这些字段而无需配置。大部分我们java
采用驼峰命名,而数据库采用下划线分隔,这时候就要采用映射集合配置。例如:
<resultMap id="BaseResultMap" type="cn.wzl.nulidexiaoma.model.User" >
<id column="ID" property="id" jdbcType="INTEGER" />
<result column="USER_NAME" property="userName" jdbcType="VARCHAR" />
<result column="PASS_WORD" property="passWord" jdbcType="VARCHAR" />
<result column="NAME" property="name" jdbcType="VARCHAR" />
<result column="AGE" property="age" jdbcType="INTEGER" />
<result column="SEX" property="sex" jdbcType="VARCHAR" />
<result column="REMARK" property="remark" jdbcType="VARCHAR" />
</resultMap>
4.3 传递参数:
方式1::使用map
方式2:使用注解@Param()
方式3:javaBean
4.4 特殊字符#,$
$配置的参数在编译文件的时候就会加载进sql语句
#配置的参数是占位符,在编译的时候只是用?代替插进sql语句,真正运行的时候才把值传入。
用$要非常小心,容易造成sql注入。
4.6 懒加载(级联操作)具体实现在其他博客
一对一:比如学生证和学生是一对一关系
一对多:学生和班级是一对多关系
多对多:一个学生对对多门功课,一门功课对应多个学生