一 SQL映射文件
1.什么是SQL映射文件
SQL映射文件是一种用于将 SQL 查询语句与数据库访问框架(如MyBatis)中的数据访问对象(DAO)方法进行映射的文件。它通常使用XML格式编写,也可以使用注解或其他形式来定义。
SQL映射文件包含了一组 SQL 查询语句,以及与之相关的参数映射和结果集映射规则。它定义了如何将应用程序中的数据操作请求转化为对数据库的实际操作。
在SQL映射文件中,我们可以定义各种类型的SQL语句,例如插入、更新、删除和查询等。这些SQL语句可以包含占位符,用于接收动态生成的参数值。通过参数映射规则,我们可以将Java对象的属性值映射到SQL语句中的参数上。
同时,SQL映射文件还定义了如何将查询结果映射到Java对象或集合中。通过结果集映射规则,我们可以指定每个查询字段与Java对象的哪个属性进行关联,从而实现查询结果的自动映射。
通过使用SQL映射文件,我们可以将数据库操作与Java代码分离,提高代码的可读性和可维护性。它使得数据访问层的开发更加灵活和高效,并且可以通过简单的配置实现复杂的数据库操作。
2.使用SQL映射文件的好处
-
解耦和可维护性:通过SQL映射文件,我们可以将数据库操作与Java代码解耦。这使得代码更加清晰、易于理解和维护。当需要修改SQL语句时,只需修改SQL映射文件而不需要改动Java代码。
-
灵活性和可扩展性:SQL映射文件提供了灵活性和可扩展性,它允许我们编写自定义的SQL查询语句,并可以使用条件判断、循环等逻辑来构建动态SQL。这样可以根据不同的需求和场景执行灵活的数据库操作。
-
灵活性和可扩展性:SQL映射文件提供了灵活性和可扩展性,它允许我们编写自定义的SQL查询语句,并可以使用条件判断、循环等逻辑来构建动态SQL。这样可以根据不同的需求和场景执行灵活的数据库操作。
-
易于测试和调试:使用SQL映射文件,我们可以轻松地编写单元测试,验证SQL语句的正确性和业务逻辑的准确性。同时,由于SQL语句是独立于Java代码的,我们可以方便地进行调试和排查问题。
-
可重用性:SQL映射文件中定义的SQL语句和参数映射规则可以在不同的DAO方法中被重用。这样可以减少代码冗余,提高代码的复用性和维护性。
总之,使用SQL映射文件可以将数据库操作与Java代码分离,提高代码的可读性、可维护性和扩展性。它使得数据访问层的开发更加灵活和高效,并且可以优化查询性能和方便测试调试。
3.SQL映射文件的顶级元素
-
<mapper>
:<mapper>
是SQL映射文件的根元素,它用于定义一个Mapper接口对应的映射关系。每个SQL映射文件通常只有一个<mapper>
元素。 -
<resultMap>
:<resultMap>
用于定义如何将查询结果映射到Java对象或集合中。它可以指定各种属性和字段之间的映射规则,例如属性名与数据库列名的对应关系、关联关系等。 -
<select>
:<select>
用于定义一个查询操作。它包含一个或多个SQL语句,可以使用参数映射和结果集映射来指定参数与结果的处理方式。 -
<insert>
、<update>
、<delete>
:分别用于定义插入、更新和删除操作的SQL语句。 -
<sql>
:<sql>
用于定义可重用的SQL代码片段,在需要的地方可以通过<include>
引入和复用这些SQL片段。 -
<parameterMap>
:<parameterMap>
用于定义输入参数的映射规则,指定参数类型和对应的属性。 -
<cache>
:<cache>
用于配置缓存机制,提高查询性能。
这些顶级元素组成了SQL映射文件的主要结构,通过它们可以定义具体的SQL语句、参数映射和结果集映射,并进行相关的配置和优化。
二 MyBatis框架的条件查询
1.实现单一条件的查询
- 创建Mapper接口
- 创建Mapper XML文件
- 配置MyBatis
在MyBatis的配置文件中,添加对Mapper XML文件的引用: - 使用MyBatis进行查询
2.将查询条件封装成Java对象作为入参来进行多表连接查询
- 创建一个Java对象来表示查询条件,例如:
- 修改Mapper接口,将查询条件作为参数传入方法中:
- 修改Mapper XML文件,使用动态SQL来拼接查询条件:
- 使用MyBatis进行多表连接查询:
3.使用@Param注解实现多参数入参的多表连接查询
- 修改Mapper接口方法,使用@Param注解给参数起别名
- 修改Mapper XML文件,使用@Param注解中的别名来引用参数:
- 使用MyBatis进行多表连接查询:
三 MyBatis框架的增,删,改操作
1.执行insert语句
- 在SysUserMapper接口中增加添加用户的方法
/* * 新增用户信息 * */ public int insertSysUser(SysUser sysUser);
- 修改SysUserMapper.xml文件
<insert id="insertSysUser" parameterType="SysUser"> insert into `cvs_db`.`t_sysuser`(`account`,`realName`,`password`,`sex`,`birthday`,`phone`,`address`,`roleId`,`createdUserId`,`createdTime`,`updatedUserId`,`updatedTime`) values(#{account},#{realName},#{password},#{sex},#{birthday},#{phone},#{address},#{roleId},#{createdUserId},#{createdTime},#{updatedUserId},#{updatedTime}) </insert>
- 在测试类构建测试方法
@Test public void insertSysUser() throws IOException, ParseException { String time="2006-07-08"; Date date=null; SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd"); date=format.parse(time); SysUser sysUser=new SysUser(); sysUser.setAccount("12345"); sysUser.setAccount("张炎"); sysUser.setPassword("21212112121"); sysUser.setSex(2); sysUser.setBirthday(date); sysUser.setPhone("312213"); sysUser.setAddress(null); sysUser.setRoleId(1); sysUser.setCreatedUserId(1); sysUser.setCreatedTime(null); sysUser.setUpdatedUserId(null); sysUser.setUpdatedTime(null); SqlSession sqlSession = getSqlSession(); int i = sqlSession.getMapper(SysUserMapper.class).insertSysUser(sysUser); sqlSession.commit(); System.out.println(i); }
2.执行update语句
- 在SysUserMapper接口中增加修改用户的方法
/* * 修改用户的真实姓名 * */ public int updateSysUser(SysUser sysUser);
- 修改SysUserMapper.xml文件
<!-- 根据id修改用户的真实姓名 --> <update id="updateSysUser" parameterType="SysUser"> update t_sysuser set realName=#{realName} where id=#{id} </update>
- 在测试类构建测试方法
@Test public void updateSysUser() throws IOException { SysUser sysUser=new SysUser(); sysUser.setId(4); sysUser.setRealName("小勇"); SqlSession sqlSession = getSqlSession(); int i = sqlSession.getMapper(SysUserMapper.class).updateSysUser(sysUser); sqlSession.commit(); System.out.println(i); }
3.执行delete语句
-
在SysUserMapper接口中增加修改用户的方法
/* *根据id删除用户的所有信息 * */ public int delSysUser(String id);
-
修改SysUserMapper.xml文件
<!-- 根据id删除用户的所有信息 --> <delete id="delSysUser" parameterType="java.lang.String"> delete from t_sysuser where id=#{id} </delete>
-
在测试类构建测试方法
@Test public void delSysUser() throws IOException { SqlSession sqlSession = getSqlSession(); int i = sqlSession.getMapper(SysUserMapper.class).delSysUser("26"); sqlSession.commit(); System.out.println(i); }
四 MyBatis 框架的缓存
1.MyBatis 框架的缓存分类
1.一级缓存
MyBatis中的一级缓存是指在同一个SqlSession中,当执行相同的查询操作时,会将查询结果缓存起来,下次再执行相同的查询操作时,直接从缓存中获取结果,而不需要再次访问数据库。
一级缓存是默认开启的,它的作用范围是SqlSession级别的,即同一个SqlSession内部有效。当执行查询操作时,MyBatis会将查询结果以键值对的形式存储在一个HashMap中,其中键为查询语句和参数的组合,值为查询结果。如果下次执行相同的查询语句和参数组合,MyBatis会直接从缓存中取出结果,避免了再次访问数据库。
一级缓存的好处是可以提高查询性能,减少与数据库的交互次数,提升系统的响应速度。但是需要注意的是,一级缓存是基于SqlSession的,因此它的生命周期比较短暂,一旦SqlSession被关闭或提交了事务,缓存就会被清空。
如果想要在同一个SqlSession之间共享缓存,可以使用二级缓存。二级缓存是跨SqlSession级别的缓存,它可以将缓存数据保存在一个可共享的地方,比如说内存或者分布式缓存中,使得多个SqlSession之间可以共享缓存数据。
2.二级缓存
MyBatis是一种流行的Java持久层框架,它提供了对关系型数据库的访问和操作支持。在MyBatis中,二级缓存是一种用于提高数据库访问性能的机制。
二级缓存是指在MyBatis的SessionFactory级别缓存查询结果的机制。它位于Mapper层与数据库之间,可以共享数据,并减少对数据库的频繁访问。二级缓存的作用范围是一个Session(SqlSession)的生命周期。
当多个相同的查询请求到达MyBatis时,如果开启了二级缓存并且符合二级缓存的配置条件,MyBatis会首先检查是否有相应的缓存数据可供使用。如果有,则直接返回缓存的结果,避免了再次执行SQL查询;如果没有,则执行实际的SQL查询,并将查询结果缓存在二级缓存中,以便下次使用。
二级缓存在多个Session之间是共享的,因此可以有效地减少数据库的访问压力,提高系统性能。但需要注意的是,由于二级缓存是共享的,可能存在脏数据的问题。当数据库中的数据发生改变时,为了保证数据的一致性,MyBatis会自动将缓存数据进行失效处理。
要启用二级缓存,需要在MyBatis的配置文件中进行相应的配置,例如在<mapper>
元素中添加<cache>
元素,并指定相应的缓存实现类。
总而言之,MyBatis的二级缓存是一种提高数据库访问性能的机制,可以减少对数据库的频繁访问,提高系统性能。但需要注意缓存的失效问题和数据一致性的考虑。
2.二级缓存的使用方法
- 在MyBatis的配置文件(通常是
mybatis-config.xml
)中,启用二级缓存。在<configuration>
标签内添加以下配置:<settings> <setting name="cacheEnabled" value="true"/> </settings>
- 在需要启用二级缓存的Mapper接口或Mapper XML文件中,添加
<cache>
元素来配置二级缓存的相关属性。例如:<!-- 在Mapper XML文件中配置 --> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> <!-- 在Mapper接口中配置 --> @CacheNamespace(eviction = FifoCache.class, flushInterval = 60000, size = 512, readOnly = true) public interface UserDao { // ... }
以上配置示例中,
eviction
属性指定了缓存淘汰策略,默认为最近最少使用算法(Least Recently Used,LRU),flushInterval
属性指定了缓存刷新时间间隔(单位为毫秒),size
属性指定了缓存最大容量,readOnly
属性指定了缓存是否只读。 - 在需要进行二级缓存的查询方法上添加
@Cacheable
注解,或者在对应的Mapper XML文件中添加<cache-ref>
元素。这样,MyBatis将会自动将查询结果缓存起来。// 在Mapper接口方法上添加@Cacheable注解 @Cacheable User findUserById(int id);
<!-- 在Mapper XML文件中添加<cache-ref>元素 --> <resultMap id="userResultMap" type="User"> <!-- ... --> </resultMap> <select id="findUserById" resultMap="userResultMap"> SELECT * FROM users WHERE id = #{id} </select> <cache-ref namespace="com.example.UserDao"/>
需要注意的是,二级缓存只对可序列化的结果有效。因此,被缓存的对象必须实现
Serializable
接口。另外,二级缓存在默认情况下是全局共享的,如果需要对某个Mapper进行独立的二级缓存配置,可以使用
<cache-ref>
元素指定其他Mapper的缓存。这样可以避免不同Mapper之间的数据干扰。总结来说,启用MyBatis的二级缓存需要在配置文件中开启缓存,并在相应的Mapper接口或Mapper XML文件中进行缓存配置。然后,通过注解或XML配置将需要缓存的查询方法标记为可缓存的。这样,MyBatis会自动将查询结果缓存起来,提高系统性能。