JavaEE程序设计【八】

==POJO:==
==一个简单的Java类,这个类没有实现/继承任何特殊的java接口或者类,不遵循任何主要java模型,约定或者框架的java对象。在理想情况下,POJO不应该有注解。==
==JavaBean:==

  • ==JavaBean是可序列化的,实现了serializable接口==
  • ==具有一个无参构造器==
  • ==有按照命名规范的set和gett,is(可以用于访问布尔类型的属性)方法==

一、MyBatis基础


中文文档

1、什么是MyBatis

MyBatis框架:ORM(Object/Relation Mapping)框架

可以把数据库表中的一行数据映射为一个java对象。

一行数据可以看做是一个java对象.操作这个对象,就相当于操作表中的数据。(由框架自动帮我们整合更新数据库)

功能

  • 1.提供了创建 Connection, statement, Resultset的能力,不用开发人员创建这些对象了
  • 2.提供了执行sq1语句的能力,不用你执行sql.
  • 3.提供了循环sql,把sql的结果转为java对象,list集合的能力。
  • 4.提供了关闭资源的能力,不用你关闭 Conneetion, statement, Resultset

开发人员只需要关注提供SQL语句。

2、添加MyBatis

使用Maven添加

1
2
3
4
5
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>

或者从github下载压缩包导入。如果底层采用的是MySQL数据库,还需要将MySQL数据库的驱动JAR包添加到应用程序的类路径

3、工作原理

mybatis使用的配置文件叫做sql映射文件:写sql语句的.一般一个表一个sql映射文件.

mybatis的主配置文件个项目就一个主配置文件主配置文件。它提供了数据库的连接信息和sql映射文件的位置信息

4、主配置文件

配置文件的名字可自己命名

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>

在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在<configuration>元素内配置。

==常用:properties、environments、mappers==

  • <properties>

    • 一个配置属性的元素,该元素通常用来将内部的配置外在化,即通过外部的配置来动态的替换内部定义的属性。例如,数据库的连接等属性,就可以通过典型的Java属性文件中的配置来替换,具体方式如下:

      • 1.编写db.properties

        1
        2
        3
        4
        jdbc.driver=com.mysql.jdbc.Driver
        jdbc.url=jdbc:mysql://localhost:3306/mybatis
        jdbc.username=root
        jdbc.password=root
      • 2.配置<properties… />属性

        <properties resource="db.properties" />

      • 3.修改配置文件中数据库连接的信息

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        <dataSource type="POOLED">
        <!-- 数据库驱动 -->
        <property name="driver" value="${jdbc.driver}" />
        <!-- 连接数据库的url -->
        <property name="url" value="${jdbc.url}" />
        <!-- 连接数据库的用户名 -->
        <property name="username" value="${jdbc.username}" />
        <!-- 连接数据库的密码 -->
        <property name="password" value="${jdbc.password}" />
        </dataSource>
  • <settings>

    • 主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。通常不需要开发人员去配置 ,读者作为了解即可。

      <settings>元素中的常见配置的使用方式如下

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <settings>
      <setting name="cacheEnabled" value="true" />
      <setting name="lazyLoadingEnabled" value="true" />
      <setting name="multipleResultSetsEnabled" value="true" />
      <setting name="useColumnLabel" value="true" />
      <setting name="useGeneratedKeys" value="false" />
      <setting name="autoMappingBehavior" value="PARTIAL" />
      ...
      </settings>
  • <typeAliases>

    • 用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意
      义在于减少全限定类名的冗余。

      • 方法1.使用<typeAliases>元素配置别名的方法如下

        使用后直接写包名即可

        1
        2
        3
        <typeAliases>
        <typeAlias alias="user" type="cn.edu.ccc.ch7.po.User"/>
        </typeAliases>
      • 方法2.通过自动扫描包的形式自定义别名,具体如下:

        使用后直接写包名即可

        1
        2
        3
        <typeAliases>
        <package name=" cn.edu.ccc.ch7.po"/>
        </typeAliases>
      • 注意:如果在程序中使用了注解,则别名为其注解的值 。

    • MyBatis框架默认为许多常见的Java类型提供了相应的类型别名,如下表所示

  • <typeHandler>

    • typeHandler:将预处理语句中传入的参数从javaType(Java类型)转换为
      jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。

    • 在配置文件中注册自定义的类型处理器,它的使用方式有两种。

      • 1.注册一个类的类型处理器

        1
        2
        3
        <typeHandlers>
        <typeHandler handler="cn.edu.ccc.ch7.type.CustomtypeHandler" />
        </typeHandlers>
      • 2.注册一个包中所有的类型处理器

        1
        2
        3
        <typeHandlers>
        <package name="cn.edu.ccc.ch7.type" />
        </typeHandlers>
  • ObjectFactory

    • MyBatis中默认的ObjectFactory的作用是实例化目标类,它既可以通过默认构
      造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。
      由于自定义ObjectFactory在实际开发时不经常使用,这里只需要了解即可 。通常使用默认的ObjectFactory。自定义ObjectFactory,具体如下:

      • 1.自定义一个对象工厂

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        public class MyObjectFactory extends DefaultObjectFactory {
        private static final long serialVersionUID = -4114845625429965832L;
        public <T> T create(Class<T> type) {
        return super.create(type);
        }
        public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes,
        List<Object> constructorArgs) {
        return super.create(type, constructorArgTypes, constructorArgs);
        }
        public void setProperties(Properties properties) {
        super.setProperties(properties);
        }
        …….
        }
      • 2.在配置文件中使用<objectFactory>元素配置自定义的ObjectFactory

        1
        2
        3
        <objectFactory type="cn.edu.ccc.ch7.factory.MyObjectFactory">
        <property name="name" value="MyObjectFactory"/>
        </objectFactory>
  • <plugins>

    • MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种拦截调用是通过插件来实现的。<plugins>元素的作用就是配置用户所开发的插件。
    • 如果想要进行插件开发,必须要先了解其内部运行原理,因为在试图修改或重写已有方法的行为时,很可能会破坏MyBatis原有的核心模块。关于插件的使用,不做详细讲解,只需了解<plugins>元素的作用即可,有兴趣可以查找官方文档等资料自行学习。
  • <environments>

    • MyBatis的环境配置实际上就是数据源的配置,可以通过<environments>元素配置多种数据源,即配置多种数据库。

      • 使用<environments>元素进行环境配置的示例如下:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        <environments default="development">
        <environment id="development">
        <transactionManager type="JDBC" />
        <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>
      • 1.UNPOOLED:不使用连接池,配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。在使用时,需要配置5种属性。

      • 2.POOLED:此数据源利用“池”的概念将JDBC连接对象组织起来,这种方式使得并发Web应用可以快速的响应请求,是当前流行的处理方式。在使用时,可以配置更多的属性。 (只要池子中有连接就能拿来用)

      • 3.JNDI:可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。在使用时,需要配置2个属性。

    • 在MyBatis中,可以配置两种类型的事务管理器,分别是JDBC和MANAGED。关于这两个事务管理器的描述如下:

      • JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务的作用域。
      • MANAGED:此配置从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false来阻止它默认的关闭行为。
    • 注意:如果项目中使用的是Spring+ MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来实现事务管理 。

  • <mappers>

    • 用于指定MyBatis映射文件的位置,一般可以使用以下4种方法引入映射器文件(文件方式不常用,因为开发环境和使用环境不一定相同),具体如下。

      • 1.使用类路径引入(最常用)

        1
        2
        3
        <mappers>
        <mapper resource="cn/edu/ch7/mapper/UserMapper.xml"/>
        </mappers>
      • 2.使用本地文件路径引入

        1
        2
        3
        <mappers>
        <mapper url="file:///D:/cn/edu/mapper/UserMapper.xml"/>
        </mappers>
      • 3.使用接口类引入

        1
        2
        3
        <mappers>
        <mapper class="cn.edu.ch7.mapper.UserMapper"/>
        </mappers>
      • 4.使用包名引入

        1
        2
        3
        <mappers>
        <package name="cn.edu.ch7.mapper"/>
        </mappers>
  • <databaseIdProvider>

    • 用来支持多厂商数据库

      • 在主配置文件中配置:

        1
        2
        3
        4
        <databaseIdProvider type="DB_VENDOR">
        <property name="MySQL" value="mysql"/>
        <property name="Oracle" value="oracle" />
        </databaseIdProvider>
      • 在映射文件中配置

        1
        2
        3
        4
        5
        6
        <select id="SelectTime" resultType="String" databaseId="mysql">
        SELECT NOW() FROM dual
        </select>
        <select id="SelectTime" resultType="String" databaseId="oracle">
        SELECT 'oralce'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual
        </select>

5、映射配置文件

从文档中摘录:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
<select id="selectBlog" resultType="Blog">
select * from Blog where id = #{id}
</select>
</mapper>
  • 1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

这句话指定限制文件。mybatis-3- mapper.dtd是约束文件的名称,扩展名是dtd的.用来限制,检查在当前文件中出现的标签,属性必须符合 mybatis的要求.

  • 1
    2
    3
    4
    5
    <mapper namespace="org.mybatis.example.BlogMapper">
    <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
    </select>
    </mapper>
    • mapper是当前文件的根标签,必须的.
    • namespace:叫做命名空间,唯一值的,可以是自定义的字符串.但是我们开发要求使用dao接口的全限定名称.
    • 在当前文件中,可以使用特定的标签,表示数据库的特定操作.
      < select>:表示执行查询, select语句
      < update>:表示更新数据库的操作,就是在< update>标签中写的是 update sql语句
      < insert>:表示插入,放的是 insert语句
      < delete>:表示删除,执行的 delete语句
      • id:你要执行的sql语法的唯一标识, mybatis会使用这个id的值来找到要执行的sql语句可以自定义,但是要求你使用接口中的方法名称.
      • resultType:表示结果类型的,是sql语句执行后得到 Resultset,遍历这个 Resultset得到java对象的类型
  • 常用属性

  • <insert>元素的特有属性

    • 执行插入操作后,很多时候需要返回插入成功的数据生成的主键值,此时就可以通过上面讲解的3个属性来实现。

      • 1.对于支持主键自助增长的数据库(如MySQL),可以通过如下配置实现:

        1
        2
        3
        4
        5
        <insert id="addCustomer" parameterType="cn.edu.ch7.po.Customer"
        keyProperty="id" useGeneratedKeys="true" >
        insert into t_customer(username,jobs,phone)
        values(#{username},#{jobs},#{phone})
        </insert>
  • <update><delete>元素的使用比较简单,它们的属性配置也基本相同。

    • 1.<update><delete>元素的常用属性如下:

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <update
      id="updateCustomer"
      parameterType="cn.edu.ccc.ch7.po.Customer"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
      <delete
      id="deleteCustomer"
      parameterType="cn.edu.ccc.ch7.po.Customer"
      flushCache="true"
      statementType="PREPARED"
      timeout="20">
    • 2.<update><delete>元素的使用示例如下:

      1
      2
      3
      4
      5
      6
      7
      8
      <update id="updateCustomer" parameterType="cn.edu.ccc.ch7.po.Customer">
      update t_customer
      set username=#{username},jobs=#{jobs},phone=#{phone}
      where id=#{id}
      </update>
      <delete id="deleteCustomer" parameterType="Integer">
      delete from t_customer where id=#{id}
      </delete>
  • <SQL>元素

    • SQL复用:在一个映射文件中,通常需要定义多条SQL语句,这些SQL语句的组成可能有一部分是相同的(如多条select语句中都查询相同的id、username、jobs字段),如果每一个SQL语句都重写一遍相同的部分,势必会增加代码量,导致映射文件过于臃肿。将这些SQL语句中相同的组成部分抽取出来统一提供引用方式。

      1
      2
      3
      4
      5
      6
      7
      8
      <sql id="customerColumns"> id,username,jobs,phone</sql>

      <select id="findCustomerById" parameterType="Integer"
      resultType="cn.edu.ccc.ch7.po.Customer">
      select <include refid="customerColumns"/>
      from t_customer
      where id = #{id}
      </select>
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      !--定义表的前缀名 -->
      <sql id="tablename">
      ${prefix}customer
      </sql>
      <!--定义要查询的表 -->
      <sql id="someinclude">
      from
      <include refid="${include_target}" />
      </sql>
      <!--定义查询列 -->
      <sql id="customerColumns">
      id,username,jobs,phone
      </sql>
      <select id="findCustomerById" parameterType="Integer"
      resultType="cn.edu.ccc.ch7.po.Customer">
      select
      <include refid="customerColumns"/>
      <include refid="someinclude">
      <property name="prefix" value="t_" />
      <property name="include_target" value="tablename" />
      </include>
      where id = #{id}
      </select>

      通过<include>元素的refid属性引用id为someinclude的代码片段,先加入from,再通过获取<property>元素的值来组成表名

  • <resultMap>

    • <resultMap>元素表示结果映射集,是MyBatis中最重要也是最强大的元素。它的主要作用是定义映射规则、级联的更新以及定义类型转化器等。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      <resultMap type="" id="">
      <constructor> <!-- 类在实例化时,用来注入结果到构造方法中-->
      <idArg/> <!-- ID参数;标记结果作为ID-->
      <arg/> <!-- 注入到构造方法的一个普通结果-->
      </constructor>
      <id/> <!-- 用于表示哪个列是主键-->
      <result/> <!-- 注入到字段或JavaBean属性的普通结果-->
      <association property="" /> <!-- 用于一对一关联 -->
      <collection property="" /> <!-- 用于一对多关联 -->
      <discriminator javaType=""> <!-- 使用结果值来决定使用哪个结果映射-->
      <case value="" /> <!-- 基于某些值的结果映射 -->
      </discriminator>
      </resultMap>
      1
      2
      3
      4
      5
      6
      <resultMap id="BaseResultMap" type="cn.edu.ch6.dao.Customer">
      <id column="id" jdbcType="INTEGER" property="id" />
      <result column="username" jdbcType="VARCHAR" property="username" />
      <result column="jobs" jdbcType="VARCHAR" property="jobs" />
      <result column="phone" jdbcType="VARCHAR" property="phone" />
      </resultMap>

      ResultMap详解

      ==Mybatis中resultMap使用==

    • 属性描述
      property需要映射到JavaBean 的属性名称。
      column数据库中数据表的列名或者标签别名。
      javaType一个完整的类名,或者是一个类型别名。如果你匹配的是一个JavaBean,那MyBatis 通常会自行检测到。然后,如果你是要映射到一个HashMap,那你需要指定javaType 要达到的目的。
      jdbcType数据表支持的类型列表。这个属性只在insert,update 或delete 的时候针对允许空的列有用。JDBC 需要这项,但MyBatis 不需要。如果你是直接针对JDBC 编码,且有允许空的列,而你要指定这项。
      typeHandler使用这个属性可以覆写类型处理器。这项值可以是一个完整的类名,也可以是一个类型别名。
    • resultType将查询到结果映射封装成pojo类型中,前提是该pojo类的属性名和查询到的数据库表的字段名一致。这种映射封装mybatis帮我们自动做好了,不需要我们自己考虑。所以看起来我们是我们查询一些数据,然后返回类型是pojo。实际上内部映射封装不需要我们实现。

    • resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。

      • 现在针对上面案例,使用resultMap实现数据库表不变,现在有一个类属性名和字段对应不上,那么如何实现这这个类和表一一对应呢?
-----------------------本文结束 感谢阅读-----------------------
坚持原创技术分享,您的支持将鼓励我继续创作!恰饭^.^~