不一样的Java

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执行原理

mybatis执行流程

1、SqlSessionFactoryBuilder去读取mybatis全局配置文件,然后build一个DefaultSqlSessionFactory;
2、当我们获取到SqlSessionFactory之后,就可以通过SqlSessionFactory去获取SqlSession对象;
3、通过MapperProxy动态代理咱们的dao,执行接口里面的方法的时候,其实是对应的mapperProxy在代理;
4、通过代理对象执行CURD操作;

3、Mybatis主要开发元素

实际上,在mybatis开发中,涉及到主要开发要素是:dao接口类,mapper映射文件,以及po实体类。它们之间的关系如下:


mybatis主要元素

dao接口类中,定义了数据库操作的增删改查接口方法;po类定义接口方法的参数,可使用po类保存查询结果,或者为insert,update方法提供数据集参数。操作数据库表的SQL语句保存在mapper映射文件中。

3.1、mapper映射文件

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>
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,997评论 6 502
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,603评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,359评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,309评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,346评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,258评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,122评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,970评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,403评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,596评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,769评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,464评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,075评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,705评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,848评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,831评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,678评论 2 354

推荐阅读更多精彩内容