Mybatis框架(一)
1、JDBC访问数据库
JDBC是Sun公司为应用程序与数据库驱动之间提供的一组接口规范,它在操作数据库的时候流程如下:
1、注册驱动
2、建立连接
3、创建发送SQL语句的对象
4、发送SQL语句
5、对返回结果处理
6、资源释放
使用JDBC操作数据库存在种种问题:
1、频繁的创建、释放数据库连接,资源浪费;
2、SQL语句与Java代码在一块,不易维护;
3、传输传递硬编码问题;
4、结果集解析硬编码问题;
这就不得不说Mybatis这样一种持久层框架。mybatis针对JDBC出现的问题,都得到了很好的解决。
1、数据库连接池;
2、SQL语句与Java代码分离;
3、Mybatis自动将java对象映射至sql语句;
4、Mybatis自动将sql执行结果映射至java对象;
2、Mybatis的简单使用
2.1、Mybatis介绍
MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
2.2、Mybatis简单使用
全局配置文件mybatis-config.xml
全局配置文件,是对MyBatis 的核心行为的控制。
数据库配置文件db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/springcloud01?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
实体类文件
@Data
public class Employee {
private Integer eId;
private String eName;
private Date eInDate;
private Double eSalary;
private Integer dId;
}
接口文件
public interface EmployeeMapper {
//查询员工信息
public List<Employee> searchEmps();
}
对象映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pyn.dao.EmployeeMapper">
<resultMap type="emp" id="myEmp1">
<id property="eId" column="eid" />
<result property="eName" column="ename" />
<result property="eInDate" column="eindate" />
<result property="eSalary" column="esalary" />
<result property="dId" column="did" />
</resultMap>
<!--searchEmps() 查询所有员工信息-->
<select id="searchEmps" resultMap="myEmp1">
select * from employee
</select>
</mapper>
全局配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入数据库配置文件-->
<properties resource="db.properties"></properties>
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 控制全局缓存(二级缓存)-->
<setting name="cacheEnabled" value="true"/>
<!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
<typeAliases>
<typeAlias alias="emp" type="com.pyn.entity.Employee" />
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/EmployeeMapper.xml"/>
</mappers>
</configuration>
测试类
String resource = "mybatis-config.xml";
InputStream in = null;
SqlSessionFactory factory = null;
SqlSession session = null;
try{
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
in = Resources.getResourceAsStream(resource);
factory = builder.build(in);
session = factory.openSession();
EmployeeMapper mapper = session.getMapper(EmployeeMapper.class);
List<Employee> emps = mapper.searchEmps();
for(int i = 0;i<emps.size();i++){
System.out.print(emps.get(i));
}
}catch(IOException e){
}finally {
session.close();
}
2.3、Mybatis执行原理
1、SqlSessionFactoryBuilder去读取mybatis全局配置文件,然后build一个DefaultSqlSessionFactory;
2、当我们获取到SqlSessionFactory之后,就可以通过SqlSessionFactory去获取SqlSession对象;
3、通过MapperProxy动态代理咱们的dao,执行接口里面的方法的时候,其实是对应的mapperProxy在代理;
4、通过代理对象执行CURD操作;
3、Mybatis主要开发元素
实际上,在mybatis开发中,涉及到主要开发要素是:dao接口类,mapper映射文件,以及po实体类。它们之间的关系如下:
dao接口类中,定义了数据库操作的增删改查接口方法;po类定义接口方法的参数,可使用po类保存查询结果,或者为insert,update方法提供数据集参数。操作数据库表的SQL语句保存在mapper映射文件中。
3.1、mapper映射文件
在mapper映射文件中,主要包含如下配置元素:
mapper元素。该元素是最顶层的配置元素,其属性namespace指向接口全类型名,在mapper元素下面,包含如下子元素:resultMap元素,select元素,insert元素,update元素,delete元素。
3.1.1、resultMap元素
使用resultMap配置节,建立po类的数据字段与查询结果集的列名之间的映射关系。当po类的数据字段与查询结果集的列名不一致的时候,使用resultMap建立两者之间的映射关系。注意:resultMap与resultType不可同时存在,后者主要用于简单查询并且查询结果集与po类的数据字段一致。
<resultMap type="emp" id="myEmp1">
<id property="eId" column="eid" />
<result property="eName" column="ename" />
<result property="eInDate" column="eindate" />
<result property="eSalary" column="esalary" />
<result property="dId" column="did" />
</resultMap>
1、type属性执行po类的全类型名,即:包名+类名。如果在mybatis配置文件中,为po类建立了别名,可以引用该别名。
2、id属性应该全局唯一,它被select元素的resultMap属性引用。
3、<id>子元素用来建立po数据字段与查询结果集主键列之间的映射关系。
4、<result>子元素用来建立po数据字段与查询结果集非主键列之间的映射关系。
5、property属性用来指定po类的数据字段名。
6、column属性用来指定数据库表的列名。
3.1.2、select元素
在mapper文件中,使用select元素来管理select语句。
<select id="searchEmps" resultMap="myEmp1">
select * from employee
</select>
1、id属性就是对应执行查询方法的方法名;
2、resultMap建立结果集列和po属性的关联 与resultType不可共存,后者查询结果集与po属性相同;
3、parameterType属性,传递参数的类型;
注意:
resultType属性的值可以是如下情形:
1.基本数据类型,如:int,String等;
2.class数据类型,如:java bean,这里输入的是全类型名或者别名;
3.map数据类型。包括:单对象和集合两种;
4.集合数据类型,是集合元素的类型,而非集合本身;
3.1.3、insert/update/delete元素
上述三种分别对应添加、修改、删除功能。功能类似。
添加
<insert id="insertEmp" parameterType="emp">
insert into employee(ename,eindate,esalary,did)
values(#{eName},#{eInDate},#{eSalary},#{dId})
</insert>
删除
<delete id="deleteEmp" parameterType="int">
delete from employee where eid = #{eId}
</delete>
修改
<update id="updateEmp" parameterType="emp">
update employee set ename = #{eName},eindate = #{eInDate},
esalary = #{eSalary},did = #{dId}
where eid = #{eId}
</update>
3.1.4、小结
在mapper映射文件中,当然不仅仅只有上述几个元素,当然还有其他的元素,上述四个元素对应数据库操作的查询、添加、修改、删除。
注意:
1、映射文件的Namespace必须等于接口的全路径名称;
2、映射文件的sql唯一标示id必须等于接口方法的名称;
3、映射文件的parameterType必须等于接口方法的参数类型;
4、映射文件的resultType/resultMap必须等于接口方法的返回类型;
3.2、全局配置文件
mybatis-config.xml文件(当然名字可以修改)全局配置文件,主要包含以下元素,从上往下依次为(注意顺序不可乱):
3.2.1、properties属性
properties属性主要用来加载/修改属性properties配置文件,例如:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
全局配置文件引入
<!--引入数据库配置文件-->
<properties resource="db.properties"></properties>
3.2.2、settings属性
mybatis框架运行时可以调整一些运行参数。比如,开启二级缓存,开启延迟加载等等。全局参数会影响mybatis的运行行为。比较常用的有以下几个:
cacheEnabled:在全局范围内启用或禁用缓存配置 任何映射器在此配置下,默认True;
lazyLoadingEnabled:在全局范围内启用或禁用延迟加载。禁用时,所有相关联的将热加载。默认True;
logImpl:指定MyBatis的日志实现使用。如果此设置是不存在的记录的实施将自动查找。默认not set;
aggressiveLazyLoading:启用时,有延迟加载属性的对象将被完全加载后调用懒惰的任何属性。否则,每一个属性是按需加载。默认True;
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 控制全局缓存(二级缓存)-->
<setting name="cacheEnabled" value="true"/>
<!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
3.2.3、typeAliases属性
typeAliases元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。
//1. 使用<typeAliases>元素配置别名的方法如下:
<typeAliases>
<typeAlias alias="emp" type="com.pyn.entity.Employee"/>
</typeAliases>
//2. 当POJO类过多时,可以通过自动扫描包的形式自定义别名,别名默认为类名首字母小写具体如下:
<typeAliases>
<package name="com.pyn.entity"/>
</typeAliases>
//3.在2的前提下,可以通过注解@Alias()重新起个别名
@Data
@Alias("employee")
public class Employee {
private Integer eId;
private String eName;
private Date eInDate;
private Double eSalary;
private Integer dId;
}
3.2.4、typeHandler属性
typeHandler的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。
//1.注册一个类的类型处理器
<typeHandlers>
<typeHandler handler="com.pyn.type.EmployeetypeHandler" />
</typeHandlers>
//2.注册一个包中所有的类型处理器
<typeHandlers>
<package name="com.pyn.type" />
</typeHandlers>
3.2.5、objectFactoty属性
objectFactoty元素,MyBatis中默认的ObjectFactory的作用是实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。通常使用默认的ObjectFactory即可。
3.2.6、plugins属性
plugins元素,用来配置插件,MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。<plugins>元素的作用就是配置用户所开发的插件。
3.2.7、environments属性
environments元素用于对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,我们可以通过<environments>元素配置多种数据源,即配置多种数据库。
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--
environments:mybatis可以配置多种环境 ,default指定使用某种环境。
environment:配置一个具体的环境信息;必须有两个标签;id代表当前环境的唯一标识
transactionManager:事务管理器;
type:事务管理器的类型;JDBC(JdbcTransactionFactory)|MANAGED(ManagedTransactionFactory)
自定义事务管理器:实现TransactionFactory接口.type指定为全类名
dataSource:数据源;
type:数据源类型:
1、POOLED:表示支持JDBC数据源连接池。这样可避免每次请求都要创建新的连接;
2、UNPOOLED:表示不支持数据源连接池。这样每次请求都会进行打开和关闭数据库连接操作;
3、JNDI:表示支持外部数据源连接池。比如JNDI;
4、自定义数据源:实现DataSourceFactory接口,type是全类名;
-->
3.2.8、databaseIdProvider属性
databaseIdProvider多数据库支持,mybatis可以根据不同的数据库厂商执行不同的语句,基于映射语句中的databaseId属性。
<databaseIdProvider type="DB_VENDOR">
<!-- 为不同的数据库厂商起别名 -->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
#在映射文件中,执行对应操作的时候 加入标识databaseId
<select id="getEmpById" resultType="emp"
databaseId="mysql">
select * from employee where eid = #{eid}
</select>
3.2.9、mapper属性
mapper元素作用是指定MyBatis映射文件的位置。
# 1 单个加载映射文件
<mappers>
<mapper resource="mybatis/EmployeeMapper.xml"/>
</mappers>
# 2 加载接口 注意接口名要和映射文件名保持一致
<mappers>
<mapper class="com.pyn.mapper.EmployeeMapper"/>
</mappers>
# 3 批量加载 mapper接口名称和mapper映射文件名称相同,且放在同一个目录中
<mappers>
<mapper class="com.pyn.mapper"/>
</mappers>