- 页内目录
一,MyBatis的介绍二,MyBatis的相关详细配置
maven依赖
核心配置文件
映射配置文件
log4j2的配置
三,MyBatis的简单使用
简单实用代理模式
日志展示
映射传参
四,MyBatis的结果映射
结果映射----resultType
结果映射一对多----resultMap
结果映射多对一----resultMap
表连接查询----inner join
五,MyBatis的重要机制
加载机制 懒加载
缓存机制 一级缓存 二级缓存
六,MyBatis的动态SQL
where/if标签
choose/when/otherwise标签
set标签
trim标签
foreach标签
七,MyBatis注解使用说明
MyBatis常用注解
基于注解的单表查询语句
基于动态SQL的注解
基于注解的一对多查询
一,MyBatis的介绍(MyBatis官网)
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息;
- 持久化:将瞬时状态的数据转换为持久状态数据的过程称为持久化过程,持久化是将程序数据在持久状态和瞬时状态间转换的机制。如:文件IO,JDBC,ORM框架;
- ORM框架:对象关系映射,通过 Java 对象与数据库关系表的映射实现数据的持久化,在操作
数据库时需要使用 SQL 语句并对结果进行封装,而 ORM 框架要达到的效果是简化数
据库的开发,让数据库操作的过程更加自动化,例如:Hibernate,MyBatis - Hibernate:一个完全的ORM框架,在Hibernate中可以不编写任何sql语句实现对数据库的操作,但是优化sql比较麻烦,学习成本较高,目前的使用集中在需求变化不大的场景;
- MyBatis:不完全的ORM框架,需要自己编写SQL语句来实现数据库的操作,因此对于sql的优化就变得简单了许多,适合于需求变化较大的应用场景,并且学习成本不高,易上手;
二,MyBatis的相关详细配置
- 首先建立可设置Maven依赖的项目;
- 这里Maven依赖需要自己配置本地maven库,教程:maven本地库搭建流程,并配置setting.xml文件;(就是为了可以引入maven依赖)
- 在pom.xml文件的
<dependencies>标签种引入四种maven依赖;(Maven官网)
<!--连接数据库的maven依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency><!--mybaits的核心配置的maven依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency><!--log4j2日志的maven依赖-->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.14.1</version>
</dependency><!-- 用于单元测试的maven依赖 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>- 建立如下目录
- mybatis-config.xml的配置(直接拿走,可用!!!)
<?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:配置myBatis的开发环境,可以配置多个具体环境,每个环境对应一个数据库-->
<environments default="development">
<!--environment:配置具体的mybatis环境-->
<environment id="development">
<!--transactionManager:指定当前配置所使用的事务管理器-->
<transactionManager type="JDBC"/>
<!--dataSource:配置数据源
POOLED:指定使用数据库连接池
UNPOOLED:不使用数据库连接池
JNDI:使用外部数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<!--这里的 myshopping 是我要使用的数据库-->
<property name="url" value="jdbc:mysql://localhost:3306/myshopping"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--配置SQL映射文件-->
<mappers>
<!--配置映射文件地址-->
<mapper resource="mapper/需要映射的对应的xml文件"/><!--根据查询的方式不同,写入文件不同-->
</mappers>
</configuration>- userMapper.xml和ordersMapper.xml的配置(直接拿走,可用!!!)
<?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="接口的包地址"><!--根据查询的接口不同,写入文件不同-->
<!--内部写如下标签:
<resultMap></resultMap>用于映射结果集
<select></select>查询语句标签
<update></update>更新语句标签
<insert></insert>添加语句标签
<delete></delete>删除语句标签
-->
</mapper>- log4j2的配置(后面sql语句和详细信息,配置该日志会得到详细显示)(直接拿走,可用!!!,当然也可以用自带的日志,下面讲配置)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders><!--配置日志内容输出的位置及格式-->
<!--conlose:控制台输出,name="Console":该配置的唯一标识,target="SYSTEM_OUT":所使用的输出语句-->
<Console name="Console" target="SYSTEM_OUT">
<!--配置日志数据格式:%d{HH:mm:ss.SSS}:日期时间格式[%t]:执行的线程%-5level:所属日志级别%logger{36}:当前日志的输出位置(哪个方法输出该日志)%msg:日志消息%n:换行-->
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!--文件输出-->
<!-- <File name="syslogFile" fileName="d:/log01.log">-->
<!-- <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>-->
<!-- </File>-->
</Appenders>
<!--配置需要日志输出的包-->
<Loggers>
<!--additivity="false":配置存在重复输出的日志只输出一次(不会重复输出),level:指定当前日志包的输出级别-->
<Logger name="com.mybatis.mapper" level="trace" additivity="false">
<AppenderRef ref="Console"/><!--配置当前当前中日志输出位置,ref的值是Appenders配置中的一个name的值-->
</Logger>
<Root level="debug">
<AppenderRef ref="Console"/><!--ref指向Appenders标签中的输出位置ref:为其中的name-->
</Root>
<!--
root:配置日志系统的根级别,根级别为统一输出级别,如果未单独设置日志级别,则按照该级别的配置输出日志
log4j2的日志分为以下几种(从低到高):
1.trace:跟踪级
2.debug:调试级
:消息级
4.Warn警告级
5.error:错误级
5.Fatal:致命级
在配置级别时,输出的日志级别为所配置级别以及该级别以上的日志信息
-->
</Loggers>
</Configuration>不用log4j2日志也可以,默认的日志在mybatis-config.xml文件中全局配置
<!--默认日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>三,MyBatis的简单使用
使用说明
- 建立数据库,在myshopping数据库下建tbl_user(主键:user_id)和tbl_orders(主键:orders_id)表,两个表的外键user_id(很重要!后面的一对多,多对一映射需要,还有表连接)
- 在dao包下的User和Orders实体类的属性分别为下,getter,setter,toString方法自己生成
private Integer userId;//User实体类
private String userName;
private String userPassword;
private String userEmail;
private Date userBirthday;
private String userHobbys;
private Integer userSex;
private String userAddress;private String orderId;//Orders实体类
private String orderToName;
private String orderToAddress;
private String orderToPhone;
private Date orderTime;
private Integer orderStatus;
private Double orderTotalPrice;
private Integer userId;- 在UserMapper接口下写方法;(注意:不实现,MyBatis内有很多方法帮我们实现,我们要做的就是配置路径)
List<User> queryAllUser();- 譬如:这个方法queryAllUser,那么你的userMapper.xml文件下的mapper标签的属性namespace=“com.mybatis.mapper.UserMapper”,注意这里是接口的包地址
<mapper namespace="com.mybatis.mapper.UserMapper">
</mapper>- 此时:你的mybatis-config.xml文件下的mappers标签下的mapper标签的 属性resource=“mapper/userMapper.xml”,这里是根地址
<mapper resource="mapper/userMapper.xml"/>- 然后在userMapper.xml文件下的mapper标签内写入select标签,注意id属性名为方法名resultType="com.mybatis.model.User"是返回的实体类
<mapper namespace="com.mybatis.mapper.UserMapper"><!--用到修改-->
<select id="queryAllUser" resultType="com.mybatis.model.User">
select * from tbl_user
</select>
</mapper>- 使用mapper代理对象的前提条件:
- 第一点:userMapper.xml文件中的 namespace 必须为 GoodsMapper 接口的完整路
径,
第二点:UserMapper 接口中的方法名必须和 goodsMapper.xml 中 SQL 操作标签的 id 名对应一致 - 然后直接进入测试中
public class Test {
public static void main(String[] args) throws IOException {
//读取MyBatis的核心配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件获得一个SqlSessionFactoryBuilder
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory获得SqlSession对象
//SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.queryAllUser();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
}日志输出
得到结果:(这就是日志输出的强大,打印很耗资源,日志输出减少资源消耗,并且,,可以记录操作(涉及到文件输出,文件内我写了,但是注释了,想用的小伙伴可以尝试一下))

单元测试
- 建立此UserTest类
- 方法体不变,添加
@Test注解(必须要有maven依赖,上面添加过了)
结果与上面正常测试一致(别杠没用,当你方法多的时候,挨个调用显得很麻烦)
映射传参
- 当在UserMapper接口下的我的方法有参数时,需要用
@Param注解
void updateGoods(@Param("userName") String name, @Param("userId")int id);- 在对应的userMapper.xml中添加update标签(update不需要返回类型,所以不用设置resultType)
<update id="updateGoods">
update tbl_goods set userName=#{userName} where userId=#{userId}
</update>- 映射传参,就需要采用注解的方式(达到一一对应的效果)
- #{}:生成的是带有问号占位符的 SQL 语句
- ${}:生成的是使用连接字符串拼接而成的 SQL 语句
(因此可能会产生sql注入,两者都是在日志中的生成方式的区别勤奋的小伙伴自己测试一下) - 此时执行单元测试(注意修改数据库的语句要进行手动提交,即
sqlSession.commit();,否则数据达不到我们的想要效果)
@Test
public void queryUser() throws IOException {
//读取MyBatis的核心配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件获得一个SqlSessionFactoryBuilder
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory获得SqlSession对象
//SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateGoods("小白",96);
sqlSession.commit();//手动提交
sqlSession.close();
}
四,MyBatis的结果映射
即为返回类型在增删改查的标签中使用例:
<select id="queryAllUser" resultType="com.mybatis.model.User">
select * from tbl_user
</select>resultType:可以指定基本类型,如 int,double,string 等也可以指定为自定义对象类型,但要求自定义对象中的属性和数据库查询的列名一致
resultMap:属于高级映射,当 Java 对象中的属性名和数据库中的列名不一致时,就需要使用 resultMap 来将数据库中的列映射到 Java 对象中的属性resultMap 可以继承 resultMap(继承配置),当对象中的属性和表中的字段名一致时可以使用 autoMapping=“true”实现自动映射,分为一对多,多对一,等
结果映射resultType
- 举例查询userId的数量
int count();//<select id="count" resultType="int">
SELECT COUNT(userId) FROM tbl_user
</select>
resultMap结果映射一对多
描述:一对多:(一个用户对应多个订单,建立在两个表之间存在外键的情况)通过用户查询用户的所有订单- 在model包下的实体类User中添加Orders的List集合(即在一方添加多方)
List<Orders> ordersList;
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}- 在接口中写入方法
User queryUserAndOrder(int id);- 在userMapper.xml文件中写入如下查询和映射,通过id关联
<resultMap id="userOrderMap" type="com.mybatis.model.User" autoMapping="true">
<!--
配置一对多
property:对象中的属性名(新加的);
column:关系模型中的外键列
ofType:指定关联对象的实体类
select:调用关联对象所使用的sql
fetchType:lazy:设置使用懒加载机制获取对象(例:当你不调用orders的信息时,不会查询orders,(日志不显示)调用了才显示)
-->
<collection property="ordersList"
column="userId"
ofType="com.mybatis.model.Orders"
select="com.mybatis.mapper.OrdersMapper.queryOrdersByUser"
fetchType="lazy">
</collection>
</resultMap>
<select id="queryUserAndOrderByUser" resultMap="userOrderMap">
select * from tbl_user where userid=#{userid}
</select>- 再配置它的orderMapper.xml文件(namespace,select标签)根据上面的resultMap标签下collection标签的select属性的地址直接调用sql语句,无需方法(测试过了)
<mapper namespace="com.mybatis.mapper.OrdersMapper"><!--用到修改-->
<select id="queryOrdersByUser" resultType="com.mybatis.model.Orders">
select * from tbl_order where userid=#{userid}
</select>
</mapper>- 别忘记在核心配置类mybatis-config.xml中mappers标签中添加配置SQL映射文件
<mapper resource="mapper/ordersMapper.xml"/>- 从而达到用户查询订单信息的目的,即为一对多!(懒加载可以实现调用才查询,自己测试在resultMap标签内可配置)
resultMap结果映射多对一
描述:多对一:(多个订单对一个用户,建立在两个表之间存在外键的情况)通过订单查询用户信息- 在model包下的实体类Orders中添加User对象(即在多方添加一方)
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}- 在接口中写入方法
Orders queryUserAndOrdersByOrders(String id);- 在ordersMapper.xml文件中写入如下查询和映射,通过id关联
<resultMap id="orderUserMap" type="com.mybatis.model.Orders" autoMapping="true">
<!--
property:配置对象中的属性名
column:关系模型中的外键列
select:查询关联对象的SQL(接口名.方法)
-->
<association property="user"
column="userId"
select="com.mybatis.mapper.UserMapper.queryUserAndOrderByOrders"></association>
</resultMap>
<select id="queryUserAndOrdersByOrders" resultMap="orderUserMap">
select * from tbl_order where orderId=#{orderId}
</select>- 再配置它的userMapper.xml文件(namespace,select标签)根据上面的resultMap标签下association标签的select属性的地址直接调用sql语句,同样无需方法(测试过了)
<select id="queryUserAndOrderByOrders" resultType="com.mybatis.model.User">
select * from tbl_user where userid=#{userid}
</select>- 单元测试
@Test
public void queryUser() throws IOException {
//读取MyBatis的核心配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//根据配置文件获得一个SqlSessionFactoryBuilder
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过SqlSessionFactory获得SqlSession对象
//SqlSession中封装了针对数据库的所有操作(insert,update,delete,select,connection)
SqlSession sqlSession = sqlSessionFactory.openSession();
OrdersMapper mapper = sqlSession.getMapper(OrdersMapper.class);
Orders orders = mapper.queryUserAndOrdersByOrders("20210420222728240");
sqlSession.commit();//手动提交
sqlSession.close();
}- 从而达到用户查询订单信息的目的,即为多对一!(懒加载可以实现调用才查询,自己测试在resultMap标签内可配置)
表连接查询
描述:表连接建立在两个表之间存在外键的情况,通过orderid查询user信息- 在OrdersMapper接口下写入方法
Orders queryOrderById(String id);- 在ordersMapper.xml文件下写入
<resultMap id="orderUserConnMap" type="com.mybatis.model.Orders" autoMapping="true">
<!--
property:配置对象中的属性名
column:配置关系模型中的外键列
autoMapping:自动映射(要设置)
-->
<association property="user" column="userId" autoMapping="true">
</association>
</resultMap>
<select id="queryOrderById" resultMap="orderUserConnMap">
SELECT
u.*,o.*
FROM
tbl_user u
INNER JOIN
tbl_order o
ON
u.userId=o.userId
WHERE
o.orderId=#{orderId}
</select>- 调用相关方法实现表连接查询
五,MyBatis的重要机制
MyBatis的加载机制
MyBatis的加载机制分为:
- 立即加载:通过一对多可以看出,当没有设置懒加载的情况,SQL语句中的查询内容都会在日志中显示出来,这便是立即加载不设置fetchtype属性默认为立即加载eager
- 预先抓取:使用表连接查询对象及其关联对象的方式,将虚表内容全部加载(小编感觉可以归为立即加载)
- 延迟加载:(懒加载)是一种按需加载方式,即调用才加载,不调用不加载,懒加载需要设置fetchtype属性为 lazy
延迟加载(lazy load)是(也称为懒加载)延迟加载机制是为了避免一些无谓的性能开销而提出来的,所谓延迟加载就是当在真正需要数据的时候,才真正执行数据加载操作,以达到减少数据库压力的作用。
懒加载的全局设置
<!--懒加载-->
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>MyBatis的缓存机制
在 MyBatis 中为提高查询效率,降低数据库的负担,MyBatis 提供缓存机制(内部是map集合,map(com.mybatis.model.Orders#查询的数据,查询的结果)),通过缓存机制降低与数据库的交互次数,从而缓解数据库压力,达到提高性能的作用
MyBatis 的缓存有两种:
- 一级缓存(sqlSession 级缓存):在同一个 sqlSession 中起作用,sqlSession 一旦关闭,一级缓存消失;
- 二级缓存(mapper 级缓存):在同一个 mapper 中多个 sqlSession 可以共享的缓存,需要配置和序列化
当查询一个对象时,会先在二级缓存中查找(该对象允许存入到二级缓存中),如果找到则直接返回,如果找不到则在到一级缓存中查找,如果找到则返回,如果找不到会向数据库发送查询请求,并查询相应的数据,将该数据存入到一级缓存和二级缓存(该对象允许存入到二级缓存中),以备使用
一级缓存:(MyBatis默认开启一级缓存,一个sqlSession的生命周期,close就完了,所以又叫sqlSession 级缓存)
描述:用上面的表连接进行测试,
操作:当我对一个信息查询两次的时候,
第一次查询从一级缓存找,没有,然后查数据库
而第二次,从一级缓存找,找到了,直接用这便是一级缓存一级缓存测试:

一级缓存结果:

手动清理一级缓存:

手动清理一级缓存结果:

二级缓存:(存到了SqlSessionFactory里)
>>官方提示:
二级缓存是事务性的。这意味着,当 SqlSession 完成并提交时,或是完成并回滚,
但没有执行 flushCache=true 的 insert/delete/update 语句时,缓存会获得更新。
>>官方解释:
映射语句文件中的所有 select 语句的结果将会被缓存。
映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
缓存不会定时进行刷新(也就是说,没有刷新间隔)。
缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改- 全局设置(默认情况下二级缓存是开启但是具体的开启需要自己去配置,所以这里可以不配置)
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>- 当前映射文件配置该实体类使用二级缓存,在对应的mapper文件下添加cache标签
eviction属性:
LRU – 最近最少使用:移除最长时间不被使用的对象。
FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK – 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRUflushInterval(刷新间隔)属性:
属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。readOnly(只读)属性:属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。size(引用数目)属性:
属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。 - 当前操作对应的sql语句查询内容存入二级缓存,true开启
二级缓存测试:
在相应的xml文件下写入cache标签,(标签可以不设属性和值)
在单元测试进行测试(普通测试类也可以,还是那句话,单元测试是为了让你不用去main方法内挨个调用)

所以:实现二级缓存的实体类必须实现序列化Serializable,因为我的表连接设计User和Orders所以需要两个都实现序列化接口


得到结果:

说明二级缓存成功
六,MyBatis的动态SQL
MyBatis 的强大特性之一便是它的动态 SQL,通过 MyBatis 的动态 SQL 可以对SQL 语句进行灵活拼接操作
where,if标签
<!--Where 标签:如果标签体中的内容存在自动添加where关键字,如果where后面第一个关键字是 and 或 or 则自动去掉
if 标签:使用 if 标签根据条件动态拼接 SQL
test属性:写入if条件-->
<select id="queryGoods" resultType="goods">
select * from tbl_goods
<where>
<if test="g_name!=null and g_name!=''">
g_name like concat('%',#{g_name},'%')
</if>
<if test="g_start_price!=null">
and g_price ">>=#{g_start_price}
</if>
<if test="g_end_price!=null">
and g_price <=#{g_end_price}
</if>
<if test="g_start_date">
and g_date ">>=#{g_start_date}
</if>
<if test="g_end_date">
and g_date <=#{g_end_date}
</if>
</where>
</select>choose、when、otherwise标签
<!--choose、when、otherwise 标签:
这三个标签搭配使用,类似 java 中的 switch 语句,表示在多个条件中只需要其中一个-->
<select id="queryTwoChoseOne" resultType="goods">
select * from tbl_goods
<where>
<choose>
<when test="g_start_price!=null">
g_price ">>=#{g_start_price}
</when>
<otherwise>
g_price between 0 and 100
</otherwise>
</choose>
</where>set标签
<!--set标签:动态更新标签,如果需要根据内容动态更新时使用该标签,该标签会自动在
SQL 语句中加上 set 关键字并去掉多余的逗号-->
<update id="updateGoods">
update tbl_goods
<set>
<if test="g_name!=null and g_name!=''">
g_name=#{g_name},
</if>
<if test="g_price!=null">
g_price=#{g_price},
</if>
<if test="g_date!=null">
g_date=#{g_date}
</if>
</set>
<where>
g_id=#{g_id}
</where>
</update>trim标签
<!--trim标签:自定义标签,该标签可以实现 where 标签和 set 标签的功能,主要用于在
前缀、后缀增加内容及删除前缀或后缀的内容(自动的)
prefix属性:自动添加前缀
prefixOverrides属性:设置前缀要移除的内容
suffix属性::设置后缀要追加的内容
suffixOverrides:设置后缀要移除的内容-->
<update id="updateGoods1">
update tbl_goods
<trim prefix="set" suffixOverrides=",">
<if test="g_name!=null and g_name!=''">
g_name=#{g_name},
</if>
<if test="g_price != null">
g_price=#{g_price},
</if>
<if test="g_date != null">
g_date=#{g_date},
</if>
</trim>
<trim prefix="where">
g_id=#{g_id}
</trim>
</update>foreach标签
<!--foreach 标签:遍历标签,
collection:指定要遍历的集合
item:将集合中的元素赋值给 item 指定的变量
open:前缀添加内容
close:后缀添加内容
separator:每次循环分割内容-->
<delete id="delGoods">
<if test="g_ids.length!=0">
delete from tbl_goods
<where>
g_id in
<foreach collection="g_ids" open="(" close=")" separator="," item="g_id">
#{g_id}
</foreach>
</where>
</if>
</delete>SQL 复用标签
<!--SQL 复用片段:为达到 SQL 语句复用的效果,MyBatis 提供 SQL 片段,SQL片段定义好后可以被多次调用
通过include 标签的refid属性调用-->
<sql id="publicSql">
<if test="g_name!=null and g_id!=null">
select * from tbl_goods wherer g_name=#{g_name} where g_id=#{g_id}
</if>
</sql>
<select id="selectTest">
<include refid="publicSql"></include>
</select>七,MyBatis注解使用
常用注解
@Insert:SQL 语句–插入
@Update:SQL 语句–更新
@Delete: SQL 语句–删除
@Select:SQL 语句–查询
@Results:–定义结果映射
@Result:–用于映射属性
@ResultMap:用于引用 Results 定义的结果映射
@one:等同于,用于多对一关联中映射单个对象
@Many: 等同于,用于一对多关联中映射多方
基于注解的单表查询语句
- 注解的使用省去了在类似于UserMapper.xml和OrdersMapper.xml文件中配置大量的标签
- 实现的方式变成在mybatis-config.xml文件下的mappers标签中配置SQL映射,name属性:SQL语句注解所存在的包地址(该包下的所有接口都可以映射SQL注解)
<!--配置SQL映射文件-->
<mappers>
<package name="com.mybatis.mapper"/><!--用sql注解时使用-->
</mappers>- 在mapper下新建NewUserMapper接口,并写方法queryById,添加注解
public interface NewUserMapper {
@Select("select * from tbl_user where userId=#{userId}")
User queryByIdNote(int userId);
}- 测试
- 结果


基于动态SQL的注解(官方的)
@Update({"<script>",
"update Author",
" <set>",
" <if test='username != null'>username=#{username},</if>",
" <if test='password != null'>password=#{password},</if>",
" <if test='email != null'>email=#{email},</if>",
" <if test='bio != null'>bio=#{bio}</if>",
" </set>",
"where id=#{id}",
"</script>"})
void updateAuthorValues(Author author);基于注解的带返回值的查询语句(新版一对多)
- 在NewUserMapper接口下写如下方法注解
@Results(id = "user",value = {
@Result(property = "ordersList",column = "userId",
many = @Many(select ="com.mybatis.mapper.NewOrdersMapper.queryUserAndOrdersByIdNoteSon"))
})
@Select("select * from tbl_user where userId=#{userId}")
User queryUserAndOrdersByIdNote(int userId);- 在NewOrdersMapper接口写
@Select(value = "select * from tbl_order where userId=#{userId}")
List<Orders> queryUserAndOrdersByIdNoteSon(int userId);- 测试
- 结果
















