注:以下信息是从各种渠道收集来的信息进行整合!!!
目录
第一部分 开发环境和配置概述
第二部分 JSP&Servlet
第三部分 Mybatis
第1章 初识MyBatis框架
1. 框架的优势
相比于使用JSP+Servlet技术进行软件开发,使用框架有以下优势:
- 如事务处理、安全性、数据流控制等都可以交给框架处理,程序员只需要集中精力完成系统的业务逻辑设计,降低了开发难度。
- 提高代码规范性和可维护性:当多人协同进行开发时,代码的规范性和可维护性就变得非常重要。成熟的框架都有严格的代码规范,能保证团队整体的开发风格统一。
- 提高软件性能:使用框架进行软件开发,可以减少程序中的冗余代码。例如,使用Spring框架开发时,通过Spring的IOC特性,可以将对象之间的依赖关系交给Spring控制,方便解耦,简化开发;使用MyBatis框架开发时,MyBatis提供了XML标签,支持动态的SQL,开发人员无需在类中编写大量的SQL语句,只需要在配置文件中进行配置即可。
2. 传统JDBC的劣势
JDBC是Java程序实现数据访问的基础,JDBC的劣势主要有以下几个方面:
- 数据库连接创建、释放频繁会造成系统资源浪费,从而影响系统性能。
- SQL语句在代码中硬编码,造成代码不易维护。在实际应用的开发中,SQL变化的可能性较大。在传统JDBC编程中,SQL变动需要改变Java代码,违反了开闭原则。
- 用PreparedStatement向占有位符号传参数存在硬编码,因为SQL语句的where条件不一定,可能多也可能少,修改SQL需要修改代码,造成系统不易维护。
- JDBC对结果集解析存在硬编码(查询列名),SQL变化导致解析代码变化,造成系统不易维护。
3. Mybatic介绍
MyBatis是一个支持普通SQL查询、存储过程以及高级映射的持久层框架,它消除了几乎所有的JDBC代码和参数的手动设置以及对结果集的检索,使用简单的XML或注解进行配置和原始映射,将接口和Java的POJO映射成数据库中的记录,使得Java开发人员可以使用面向对象的编程思想来操作数据库。
MyBatis框架是一个ORM(Object/Relation Mapping,即对象关系映射)框架。所谓的ORM就是一种为了解决面向对象与关系型数据库中数据类型不匹配的技术,它通过描述Java对象与数据库表之间的映射关系,自动将Java应用程序中的对象持久化到关系型数据库的表中。ORM框架的工作原理可以通过一张图来展示:
针对JDBC编程的劣势,MyBatis提供了以下解决方案,具体如下:
- 数据库连接创建、释放频繁会造成系统资源浪费,从而影响系统性能。
解决方案:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。 - SQL语句在代码中硬编码,造成代码不易维护。在实际应用的开发中,SQL变化的可能较大。在传统JDBC编程中,SQL变动需要改变Java代码,违反了开闭原则。
解决方案:MyBatis将SQL语句配置在MyBatis的映射文件中,实现了与Java代码的分离。 - 使用preparedStatement向占有位符号传参数存在硬编码,因为SQL语句的where条件不一定,可能多也可能少,修改SQL需要修改代码,造成系统不易维护。
解决方案:MyBatis自动将Java对象映射至SQL语句,通过Statement中的parameterType定义输入参数的类型。 - JDBC对结果集解析存在硬编码(查询列名),SQL变化导致解析代码变化,造成系统不易维护。
解决方案:MyBatis自动将SQL执行结果映射至Java对象,通过Statement中的resultType定义输出结果的类型。
4. Mybatis环境搭建
使用MyBatis框架进行数据库开发之前,需要先搭建MyBatis环境,MyBatis环境搭建主要有如下基本步骤。
4.1 创建工程
创建Maven工程。
4.2 引入相关依赖
在项目的pom.xml文件中导入MySQL驱动包、Junit测试包、MyBatis的核心包等相关依赖。
4.3 数据库准备
创建数据库,编写几条测试数据。
4.4 编写数据库连接信息配置文件
mysql.driver = com.mysql.cj.jdbc.Driver
mysql.url = jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
mysql.username = root
mysql.password = root
4.5 编写核心配置文件和映射文件
在项目的src/main/resources目录下创建MyBatis的核心配置文件,该文件主要用于项目的环境配置,如数据库连接相关配置等。核心配置文件可以随意命名,但通常将其命名为mybatis-config.xml。
<configuration>
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
</dataSource>
</environment>
</environments>
</configuration>
5. Mybatis工作原理
- MyBatis 读取核心配置文件 mybatis-config.xml 。mybatis-config.xml 核心配置文件主要配置了 MyBatis 的运行环境等信息。
- 加载映射文件 Mapper.xml。Mapper.xml 文件配置了操作数据库的 SQL 语句,需要在 mybatis-config.xml 中加载才能执行。mybatis-config.xml 可以加载多个映射文件,每个映射文件对应数据库中的一张表。
- 构造会话工厂。通过 MyBatis 的环境等配置信息构建会话工厂SqlSessionFactory,用于创建 SqlSession。
- 创建会话对象。由会话工厂 SqlSessionFactory 创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。
- 创建执行器。会话对象本身不能直接操作数据库,MyBatis 底层定义了一个 Executor 接口用于操作数据库,执行器会 根据 SqlSession 传递的参数动态的生成需要执行的 SQL 语句,同时负责查询缓存的维护。
- 封装 SQL 信息。SqlSession 内部通过执行器 Executor 操作数据库,执行器将待处理的 SQL 信息封装到MappedStatement 对象中,MappedStatement 对象中存储了要映射的 SQL 语句的 id、参数等。Mapper.xml 文件中一个 SQL 语句对应一个 MappedStatement 对象,SQL 语句的 id 即是 MappedStatement 的 id。Executor 执行器会在执行 SQL 语句之前,通过 MappedStatement 对象将输入的参数映射到 SQL 语句中。
- 操作数据库。根据动态生成的 SQL 操作数据库。
- 输出结果映射。执行 SQL 语句之后,通过 MappedStatement 对象将输出结果映射至 Java 对象中。
第2章 MyBatis的核心配置
1. Mybatis的核心对象
// 使用MyBatis提供的Resources类加载MyBatis的配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
// 构建SqlSessionFactory工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 构建会话对象
SqlSession sqlSession = sqlSessionFactory.openSession();
1.1 SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder.build(Reader reader,String environment,Properties properties)
上述build()方法中,参数Reader是字符流,它封装了XML文件形式的配置信息;参数environment和参数properties为可选参数。其中,参数environment决定将要加载的环境,包括数据源和事务管理器;参数properties决定将要加载的properties文件。
SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用程序执行期间都会存在。如果我们多次创建同一个数据库的SqlSessionFactory对象,那么该数据库的资源将很容易被耗尽。通常每一个数据库都只创建一个SqlSessionFactory对象,所以在构建SqlSessionFactory对象时,建议使用单例模式。
1. 2 SqlSessionFactory对象
SqlSessionFactory的openSession()方法:
参数execType有三个可选值:
- ExecutorType.SIMPLE:表示为每条语句创建一条新的预处理语句。
- ExecutorType.REUSE:表示会复用预处理语句。
- ExecutorType.BATCH:表示会批量执行所有更新语句。
参数autoCommit可设置是否开启自动提交事务
参数connection可提供自定义连接。
1.3 SqlSession对象
每一个线程都应该有一个自己的SqlSession对象,并且该对象不能共享。SqlSession对象是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在类的静态字段、对象字段或任何类型的管理范围(如Servlet的HttpSession)中使用。SqlSession对象使用完之后,要及时的关闭,SqlSession对象通常放在finally块中关闭。
2. MyBatis核心配置文件
2.1 Mybatis核心配置文件中的主要元素
<configuration>元素是整个XML配置文件的根元素,相当于MyBatis各元素的管理员。<configuration>有很多子元素,MyBatis的核心配置就是通过这些子元素完成的。需要注意的是,在核心配置文件中,<configuration>的子元素必须按照上图由上到下的顺序进行配置,否则MyBatis在解析XML配置文件的时候会报错。
2.2 < properties >元素
在MyBatis核心配置文件mybatis-config.xml中使用<properties… />元素引入db.properties文件,以获取数据库连接信息。
<properties resource="db.properties" />
2.3 < settings >元素
<settings>
<!-- 是否开启缓存 -->
<setting name="cacheEnabled" value="true" />
<!-- 是否开启延迟加载,如果开启,所有关联对象都会延迟加载 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 是否开启关联对象属性的延迟加载,如果开启,对任意延迟属性的调用都
会使用带有延迟加载属性的对象向完整加载,否则每种属性都按需加载 -->
<setting name="aggressiveLazyLoading" value="true" />
...
</settings>
2.4 < typeAliases >元素
核心配置文件若要引用一个POJO实体类,需要输入POJO实体类的全限定类名,而全限定类名比较冗长,如果直接输入,很容易拼写错误。这时可以使用<typeAliases>元素为POJO实体类设置一个简短的别名,再通过MyBatis的核心配置文件与映射文件相关联。例如,POJO实体类User的全限定类名是com.example.pojo.User,未设置别名之前,映射文件的select语句块若要引用POJO类User,必须使用其全限定类名。
- 在<typeAliases>元素下,使用多个<typeAlias>元素为每一个全限定类逐个配置别名。
<typeAliases>
<typeAlias alias="User" type="com.example.pojo.User"/>
<typeAlias alias="Student" type="com.example.pojo.Student"/>
<typeAlias alias="Employee" type="com.example.pojo.Employee"/>
<typeAlias alias="Animal" type="com.example.pojo.Animal"/>
</typeAliases>
- 通过自动扫描包的形式自定义别名。
<typeAliases>
<package name="com.example.pojo"/>
</typeAliases>
除了可以使用<typeAliases>元素为实体类自定义别名外,MyBatis框架还为许多常见的Java类型(如数值、字符串、日期和集合等)提供了相应的默认别名。例如别名**_byte映射类型byte**、_long映射类型long等,别名可以在MyBatis中直接使用,但由于别名不区分大小写,所以在使用时要注意重复定义的覆盖问题。
2.5 < environments >元素
MyBatis可以配置多套运行环境,如开发环境、测试环境、生产环境等,我们可以灵活选择不同的配置,从而将SQL映射到不同运行环境的数据库中。不同的运行环境可以通过<environments>元素来配置,但不管增加几套运行环境,都必须要明确选择出当前要用的唯一的一个运行环境。
MyBatis的运行环境信息包括事务管理器和数据源。在MyBatis的核心配置文件中,MyBatis通过<environment>元素定义一个运行环境。<environment>元素有两个子元素,<transactionManager>元素和<daraSource>元素。<transactionManager>元素用于配置运行环境的事务管理器;<daraSource>元素用于配置运行环境的数据源信息。
例如:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" /><!—设置使用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>
2.6 < mappers >元素
在MyBatis的核心配置文件中,<mappers>元素用于引入MyBatis映射文件。映射文件包含了POJO对象和数据表之间的映射信息,MyBatis通过核心配置文件中的<mappers>元素找到映射文件并解析其中的映射信息。通过<mappers>元素引入映射文件的方法有4种。
- 使用类路径引入
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
- 使用本地文件路径引入
<mappers>
<mapper url="file:///D:/com/example/mapper/UserMapper.xml"/>
</mappers>
- 使用接口类引入
<mappers>
<mapper class="com.example.mapper.UserMapper"/>
</mappers>
- 使用包名引入
<mappers>
<package name="com.example.mapper"/>
</mappers>
3. MyBatis映射文件
3.1 MyBatis映射文件中的常用元素
3.2 namespace属性
有两个作用:
- 用于区分不同的mapper,全局唯一。
- 绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的全限定名查找到对应的mapper配置来执行SQL语句,因此namespace的命名必须跟接口同名。
<mapper>元素如何区别不同的XML文件?
在不同的映射文件中,<mapper>元素的子元素的id可以相同,MyBatis通过<mapper>元素的namespace属性值和子元素的id联合区分不同的Mapper.xml文件。接口中的方法与映射文件中SQL语句id应一一对应。
3.3 < select >元素
<select>元素用来映射查询语句,它可以从数据库中查询数据并返回。使用<select>元素执行查询操作非常简单,示例代码如下:
<!—查询操作 -->
<select id="findUserById" parameterType="Integer" resultType="User">
select * from users where id = #{id}
</select>
3.3.1 < select >常用属性
3.4 < insert >元素
<insert>元素用于映射插入语句,在执行完<insert>元素中定义的SQL语句后,会返回插入记录的数量。使用<insert>元素执行插入操作非常简单,示例代码如下:
<!—插入操作 -->
<insert id="addUser" parameterType="User">
insert into users values(#{uid},#{uname},#{uage})
</insert>
很多时候,执行插入操作后,需要获取插入成功的数据生成的主键值,不同类型数据库获取主键值的方式不同,主要有对支持主键自动增长的数据库获取主键值和不支持主键自动增长的数据库获取主键值的方式。
- 使用支持主键自动增长的数据库获取主键值
如果使用的数据库支持主键自动增长(如MySQL和SQL Server),那么可以通过keyProperty属性指定POJO类的某个属性接收主键返回值(通常会设置到id属性上),然后将useGeneratedKeys的属性值设置为true。
<insert id="addUser" parameterType="User" keyProperty="uid" useGeneratedKeys="true" >
insert into users values(#{uid},#{uname},#{uage})
</insert>
- 使用不支持主键自动增长的数据库获取主键值
使用MyBatis提供的<selectKey>元素来自定义主键。
3.5 < update >元素
<update>元素用于映射更新语句,它可以更新数据库中的数据。在执行完元素中定义的SQL语句后,会返回更新的记录数量。使用<update>元素执行更新操作非常简单,示例代码如下:
<!—更新操作 -->
<update id="updateUser" parameterType="User">
update users set uname=#{uname}, uage=#{uage} where uid=#{uid}
</update>
3.6 < delete >元素
<delete>元素用于映射删除语句,在执行完<delete>元素中的SQL语句之后,会返回删除的记录数量。使用<delete>元素执行删除操作非常简单,示例代码如下所示:
<!-- 删除操作 -->
<delete id="deleteUser" parameterType="Integer">
delete from users where uid=#{uid}
</delete>
3.6.1 < delete >元素的属性
3.7 < sql >元素
<sql>元素的作用是定义可重用的SQL代码片段,它可以被包含在其他语句中。<sql>元素可以被静态地(在加载参数时)参数化,<sql>元素不同的属性值通过包含的对象发生变化。
<sql id="whereClause">
<if test="id != null">
AND id = #{id}
</if>
<if test="address != null and address !='' ">
AND address LIKE concat('%',#{keyword},'%')
</if>
</sql>
<select id="selectByConditions" parameterType="map" resultMap="orderMap">
SELECT *
FROM _order
WHERE 1=1
<include refid="whereClause" />
</select>
3.8 < resultMap >元素
<resultMap>元素表示结果映射集,是MyBatis中最重要也是功能最强大的元素。<resultMap>元素主要作用是定义映射规则、更新级联以及定义类型转化器等。
<resultMap type="Order" id="orderMap">
<id property="id" column="id"/>
<result property="orderCode" column="orderCode"/>
<result property="address" column="address"/>
<result property="post" column="post"/>
<result property="receiver" column="receiver"/>
<result property="mobile" column="mobile"/>
<result property="userMessage" column="userMessage"/>
<result property="createDate" column="createDate"/>
<result property="payDate" column="payDate"/>
<result property="deliveryDate" column="deliveryDate"/>
<result property="confirmDate" column="confirmDate"/>
<result property="status" column="status"/>
<association property="user" column="uid" javaType="User"
select="edu.fzu.tmall.mapper.UserMapper.getUserById"/>
<collection property="orderItems" column="id" ofType="OrderItem"
select="edu.fzu.tmall.mapper.OrderItemMapper.selectOrderItems"/>
</resultMap>
<sql id="whereClause">
<if test="id != null">
AND id = #{id}
</if>
<if test="address != null and address !='' ">
AND address LIKE concat('%',#{keyword},'%')
</if>
</sql>
<select id="selectByConditions" parameterType="map" resultMap="orderMap">
SELECT *
FROM _order
WHERE 1=1
<include refid="whereClause" />
</select>
第3章 动态SQL
1. 常用元素
2. < if >元素
可以理解为满足test中的条件,才会执行<if>里面的SQL语句
<if test="id != null">
AND id = #{id}
</if>
3. < choose >、< when >、< otherwise >元素
可以理解为switch(),只执行子情况的其中一种。
<!-- 只展示三个组合元素的部分-->
<choose>
<when test="username !=null and username !=''">
and username like concat('%',#{username}, '%')
</when>
<when test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</when>
<otherwise>
and phone is not null
</otherwise>
</choose>
4. < where > 元素
为了防止出现 WHERE AND 的SQL语句错误出现。<where>元素会自动判断由组合条件拼装的SQL语句,只有<where>元素内的某一个或多个条件成立时,才会在拼接SQL中加入where关键字,否则将不会添加;即使where之后的内容有多余的“AND”或“OR”,<where>元素也会自动将他们去除。
<select id="findCustomerByNameAndJobs" parameterType="Customer" resultType="Customer">
select * from t_customer
<where>
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}</if>
</where>
</select>
5. < trim >元素
<trim>元素用于删除多余的关键字,它可以直接实现<where>元素的功能。<trim>元素包含4个属性。
<select id="findCustomerByNameAndJobs" parameterType="Customer" resultType="Customer">
select * from t_customer
<trim prefix="where" prefixOverrides="and" >
<if test="username !=null and username !=''">
and username like concat('%',#{username}, '%')
</if>
<if test="jobs !=null and jobs !=''">
and jobs= #{jobs}
</if>
</trim>
</select>
6. < set >元素
在映射文件中使用<set>元素和<if>元素组合进行update语句动态SQL组装时,如果<set>元素内包含的内容都为空,则会出现SQL语法错误。因此,在使用<set>元素进行字段信息更新时,要确保传入的更新字段不能都为空。
当在<update>中使用<if>时,如果前面的<if>没有执行,则或导致逗号多余错误。使用<set>可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。
<update id="updateCustomerBySet" parameterType="Customer">
update t_customer
<set>
<if test="username !=null and username !=''">
username=#{username},
</if>
<if test="jobs !=null and jobs !=''">
jobs=#{jobs},
</if>
<if test="phone !=null and phone !=''">
phone=#{phone},
</if>
</set>
where id=#{id}
</update>
7. < foreach > 元素
collection属性的取值:
- List类型,若入参为单参数且参数类型是一个List,collection属性值为list。
- 数组类型,若入参为单参数且参数类型是一个数组,collection属性值为array。
- Map类型,若传入参数为多参数,就需要把参数封装为一个Map进行处理,collection属性值为Map。
<select id="findByArray" parameterType="java.util.Arrays" resultType="Customer">
select * from t_customer where id in
<foreach item="id" index="index" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</select>
第4章 MyBatis的关联映射和缓存机制
1. Java对象如何描述事物之间的关系
数据表之间的关系实质上描述的是数据之间的关系,除了数据表,在Java中,还可以通过对象来描述数据之间的关系。通过Java对象描述数据之间的关系,其实就是使对象的属性与另一个对象的属性相互关联。
2. 一对一查询
在MyBatis中,通过<association>元素来处理一对一关联关系。<association>元素提供了一系列属性用于维护数据表之间的关系。
2.1 < association >元素
<association>元素是<resultMap>元素的子元素,它有两种配置方式,嵌套查询方式和嵌套结果方式。
- 嵌套查询方式
嵌套查询是指通过执行另外一条SQL映射语句来返回预期的复杂类型。
<association property="card" column="cid" javaType="IdCard"
select="com.example.mapper.IdCardMapper.findCodeById" />
- 嵌套结果方式
嵌套结果是使用嵌套结果映射来处理重复的联合结果的子集。
<association property="card" javaType="IdCard">
<id property="id" column="cid" />
<result property="code" column="code" />
</association>
3. 一对多查询
在MyBatis中,通过<collection>元素来处理一对多关联关系。<collection>元素的属性大部分与<association>元素相同,但其还包含一个特殊属性一ofType。ofType属性与javaType属性对应,它用于指定实体类对象中集合类属性所包含的元素的类型。
<collection>元素是<resultMap>元素的子元素,<collection>元素有嵌套查询和嵌套结果两种配置方式。
- 嵌套查询方式
<collection property="ordersList" column="id" ofType="Orders"
select="com.example.mapper.OrdersMapper.selectOrders"/>
- 嵌套结果方式
<collection property="ordersList" ofType="Orders">
<id property="id" column="oid" />
<result property="number" column="number" />
</collection>
4. 多对多查询
拆分为两次一对多,按照一对多的思路写。
5. MyBatis缓存机制
5.1 一级缓存
MyBatis的一级缓存是SqlSession级别的缓存。如果同一个SqlSession对象多次执行完全相同的SQL语句时,在第一次执行完成后,MyBatis会将查询结果写入到一级缓存中,此后,如果程序没有执行插入、更新、删除操作,当第二次执行相同的查询语句时,MyBatis会直接读取一级缓存中的数据,而不用再去数据库查询,从而提高了数据库的查询效率。
当程序对数据库执行了插入、更新、删除操作,MyBatis会清空一级缓存中的内容以防止程序误读。
5.2 二级缓存
相同的Mapper类,相同的SQL语句,如果SqlSession不同,则两个SqlSession查询数据库时,会查询数据库两次,这样也会降低数据库的查询效率。为了解决这个问题,就需要用到MyBatis的二级缓存。MyBatis的二级缓存是Mapper级别的缓存,与一级缓存相比,二级缓存的范围更大,多个SqlSession可以共用二级缓存,并且二级缓存可以自定义缓存资源。
在MyBatis中,一个Mapper.xml文件通常称为一个Mapper,MyBatis以namespace区分Mapper,如果多个SqlSession对象使用同一个Mapper的相同查询语句去操作数据库,在第一个SqlSession对象执行完后,MyBatis会将查询结果写入二级缓存,此后,如果程序没有执行插入、更新、删除操作,当第二个SqlSession对象执行相同的查询语句时,MyBatis会直接读取二级缓存中的数据。
与MyBatis的一级缓存不同的是,MyBatis的二级缓存需要手动开启,开启二级缓存通常要完成以下两个步骤。
- 使用二级缓存前,需要在MyBatis的核心配置mybatis-config.xml文件中通过<settings>元素开启二级缓存的全局配置。
<settings>
<setting name="cacheEnabled" value="true" />
</settings>
- 开启当前Mapper的namespace下的二级缓存,可以通过MyBatis映射文件中的元素来完成。
<!-- 开启二级缓存 -->
<cache></cache>
我们可以看到 mapper.xml 文件中就这么一个空标签<cache></cache>,其实这里可以配置<cache type=“org.apache.ibatis.cache.impl.PerpetualCache”/>,PerpetualCache这个类是mybatis默认实现缓存功能的类。我们不写type就使用mybatis默认的缓存,也可以去实现 Cache 接口来自定义缓存。
第5章 MyBatis的注解开发
1. 基于注解的单表增删改查
1.1 @Select注解
public interface WorkerMapper {
@Select("select * from tb_worker where id = #{id}")
Worker selectWorker(int id);
}
在核心配置文件mybatis-config.xml中的元素下引入WorkerMapper接口,将WorkerMapper.java接口加载到核心配置文件中。
<mapper class="com.example.dao.WorkerMapper"/>
1.2 @Insert注解
@Insert("insert into tb_worker values(#{name},#{age},#{sex},#{worker_id})")
int insertWorker(Worker worker);
1.3 @Update注解
@Update("update tb_worker set name = #{name},age = #{age} where id = #{id}")
int updateWorker(Worker worker);
1.4 @Delete注解
@Delete("delete from tb_worker where id = #{id}")
int deleteWorker(int id);
1.5 @Param注解
@Select("select * from tb_worker where id = #{param01} and name = #{param02}")
Worker selectWorkerByIdAndName(@Param("param01") int id, @Param("param02") String name);
2. 基于注解的关联查询
2.1 一对一查询
public interface PersonMapper {
@Select("select * from tb_person where id=#{id}")
@Results({@Result(column="cid",property="card",
one=@One(select="com.example.dao.IdCardMapper.selectIdCardById"))})
Person selectPersonById(int id);
}
- property属性用来指定关联属性,这里为card。
- column属性用来指定关联的数据库表中的字段,这里为cid。
- one属性用来指定数据表之间属于哪种关联关系,通过@One注解表明数据表之间是一对一关联关系。
2.2 一对多查询
public interface UsersMapper {
@Select("select * from tb_user where id=#{id} ")
@Results({@Result(id = true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "id",property = "ordersList",
many = @Many(select = "com.example.dao.OrdersMapper.selectOrdersByUserId"))})
Users selectUserById(int id);
}
2.3 多对多查询
拆分为两次一对多,按照一对多的思路写。