文章目录
- 【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术
- 1.mybatis快速入门
- 1.1创建步骤
- 1.2mapper代理开发模式
- 2.mybatis增删改查
- 2.1查询所有数据
- 2.2 id查询数据
- 2.3插入数据
- 2.4修改数据
- 2.5删除数据
- 2.6 mybatis多条件查询
- 2.7 mybatis动态条件查询
- 3.MyBatis - 映射文件标签
- 3.1映射文件的顶级元素
- 3.2 select 标签的属性信息
- 3.3 resultMap 标签的属性信息
- 3.4 insert 标签的属性信息
- 3.5重用 sql 标签和完全限定名使用别名替代
- 4. 常见问题
【MyBatis精讲】从入门到精通的详细指南:简化Java持久层操作的艺术
什么是mybatis
MyBatis是一个优秀的Java持久层框架,它使用ORM实现了结果集的封装,它通过XML或注解的方式,将SQL语句和Java代码进行映射,以实现数据库操作。MyBatis提供了强大的SQL映射能力和灵活的查询功能,可以方便地进行数据持久化操作。
ORM是Object Relational Mapping 对象关系映射。简单来说,就是把数据库表和实体类及实体类的属性对应起来,让开发者操作实体类就实现操作数据库表,它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等复杂过程。
ORM:Object-Relation-Mapping,也就是对象关系映射,是一种程序设计思想,mybatis就是ORM的一种实现方式,简单来说就是将数据库中查询出的数据映射到对应的实体中。
数据库层框架
- com.zhaoli.servlet或者com.zhaoli.controller--------控制层 springmvc
- com.zhaoli.service—业务逻辑层
- com.zhaoli.dao----数据库访问层 hibernate或者mybatis、jpa
- 数据库连接相关配置
- 编写sql语句 jdbc 查询操作 单独取出每个值 在赋值给我们对象
mybatis、springmvc、springboot
使用mybatis orm java中 对象与数据库中表中 字段 对应
底层通过反射机制自动赋值
sql语句 自动形式得出对象
前提 orm映射
1.mybatis快速入门
数据库表结构
CREATE TABLE `dome01_users` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`age` int DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=33 DEFAULT CHARSET=utf8mb3;
1.1创建步骤
- 引入mybatis相关依赖
mybatis-config.xml
(该配置文件名称是可以改) 存放就是我们数据库相关连接信息- 定义mapper ----编写我们mybatis 相关 sql语句,每个表对应一个mapper
- 定义java对象–需要注意下类中的成员属性与数据库表中字段需要做映射,默认类中的成员属性数据库表中字段名称对应的。
- 使用 mybatis api开始执行该 sql语句即可 得到结果
maven依赖
<dependencies>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql 驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.18</version>
</dependency>
</dependencies>
定义xml配置文件
在D:\java\MyJavaMybatis_01\MybatisDome01\src\main\resources
下创建mybatis-config.xml
存放数据库连接信息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 default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/数据库名?serverTimezone=GMT%2B8"/>
<property name="username" value="mysql账号"/>
<property name="password" value="mysql密码"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/userMaaper.xml"/>
</mappers>
</configuration>
Maaper文件
在D:\java\MyJavaMybatis_01\MybatisDome01\src\main\resources
下创建一个 mapper
包
mapper
中是编写我们mybatis
相关 sql
语句,每个表对应一个mapper
之后在在mapper
包下创建一个 userMapper.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="userMapper">
<select id="getByUsers" resultType="com.zhaoli.entity.UsersEntity">
select * from dome01_users
</select>
</mapper>
测试代码
import com.zhaoli.entity.UsersEntity;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test01 {
public static void main(String[] args) throws IOException {
String resource="mybatis-config.xml";
//解析 mybatis-config.xml 得到数据库相关的配置信息
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建得到一个 sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取到 sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
List<UsersEntity> usersEntityList = sqlSession.selectList("getByUsersAll", UsersEntity.class);
System.out.printf(usersEntityList.toString());
sqlSession.close();
}
}
1.2mapper代理开发模式
- mapper接口方式开发整合就必须是对应的mapper接口的全限定类名
- 接口中的方法与映射文件中的SQL语句的ID
- 需要在
mybatis-config.xml
新增 加载该userMaaper
<mappers>
<mapper resource="mybatis/userMapper.xml"/>
</mappers>
- 定义mapper 接口 需要考虑方法的名称与userMapper.xml的 sql id名称保持一致。
import com.zhaoli.entity.UserEntity;
import java.util.List;
public interface UserMapper {
/**
* 调用到 userMapper.getByUsers 方法时 自动查找 userMapper.xml 中的 getByUsers 方法 执行 sql 语句
* sql 语句的 id 值与接口的方法名称对应
*/
List<UserEntity> getByUsers();
}
- 相关代码
import com.zhaoli.entity.UserEntity;
import com.zhaoli.mapper.UserMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Test02 {
//面向接口编程的方式
public static void main(String[] args) throws IOException {
String resource = "mybatis-config.xml";
//解析 mybatis-config.xml 得到数据库相关的配置信息
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建得到一个 sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取到 sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<UserEntity> userEntityList = userMapper.getByUsers();
System.out.println(userEntityList);
sqlSession.close();
}
}
userMapper.xml
的变化 namespace=”接口的完整路径地址”
<?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="com.zhaoli.mapper.UserMapper">
<!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
<select id="getByUsers" resultType="com.zhaoli.entity.UserEntity">
SElECT * FROM dome01_users;
</select>
</mapper>
2.mybatis增删改查
数据库
CREATE TABLE `mayikt_flight` (
`id` int NOT NULL AUTO_INCREMENT COMMENT 'id列',
`flight_id` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '航号',
`company` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '航空公司',
`departure_airport` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '出发机场',
`arrive_airport` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '达到机场',
`departure_time` datetime DEFAULT NULL COMMENT '出发时间',
`arrive_time` datetime DEFAULT NULL COMMENT '到达时间',
`model` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '机型',
`is_delete` int DEFAULT NULL COMMENT '是否隐藏0显示 1隐藏',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8mb3;
2.1查询所有数据
com/zhaoli/entity/FlightEntity.java
package com.zhaoli.entity;
import java.util.Date;
public class FlightEntity {
private Integer id;//id列
private String flightId;//航号
private String company;//航空公司
private String departureAirport;//出发机场
private String arriveAirport;//达到机场
private Date departureTime;//出发时间
private Date arriveTime;//到达时间
private String model;//机型
private Integer isDelete;//是否隐藏0显示 1隐藏
public FlightEntity() {
}
public FlightEntity(Integer id, String flightId, String company, String departureAirport, String arriveAirport, Date departureTime, Date arriveTime, String model, Integer isDelete) {
this.id = id;
this.flightId = flightId;
this.company = company;
this.departureAirport = departureAirport;
this.arriveAirport = arriveAirport;
this.departureTime = departureTime;
this.arriveTime = arriveTime;
this.model = model;
this.isDelete = isDelete;
}
//此处省略get()和set()
@Override
public String toString() {
return "FlightEntity{" +
"id=" + id +
", flightId='" + flightId + '\'' +
", company='" + company + '\'' +
", departureAirport='" + departureAirport + '\'' +
", arriveAirport='" + arriveAirport + '\'' +
", departureTime=" + departureTime +
", arriveTime=" + arriveTime +
", model='" + model + '\'' +
", isDelete=" + isDelete +
'}';
}
}
com/zhaoli/mapper/FlightMapper.java
package com.zhaoli.mapper;
import com.zhaoli.entity.FlightEntity;
import java.util.List;
public interface FlightMapper {
/**
* 查询
* 1.查询所有
* 2.根据条件查询
* 3.动态查询方式
*/
List<FlightEntity> getByFlightAll();
}
com/zhaoli/service/FlightService.java
package com.zhaoli.service;
import com.zhaoli.entity.FlightEntity;
import com.zhaoli.mapper.FlightMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class FlightService {
private FlightMapper flightMapper;
/**
* 通过无参构造方法 初始化 mybatis 得到 flightMapper
*/
public FlightService() throws IOException {
String resource = "mybatis-config.xml";
//解析 mybatis-config.xml 得到数据库相关的配置信息
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建得到一个 sqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取到 sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
flightMapper = sqlSession.getMapper(FlightMapper.class);
// sqlSession.close();
}
public List<FlightEntity> getByFlightAll(){
return flightMapper.getByFlightAll();
}
}
com/zhaoli/test/Test01.java
package com.zhaoli.test;
import com.zhaoli.entity.FlightEntity;
import com.zhaoli.service.FlightService;
import java.io.IOException;
import java.util.List;
public class Test01 {
/**
* 查询所有航班信息
*/
public static void main(String[] args) throws IOException {
FlightService flightService = new FlightService();
List<FlightEntity> flightEntityList = flightService.getByFlightAll();
System.out.println(flightEntityList);
}
}
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 default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis_01?serverTimezone=GMT%2B8&useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="20020806"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/flightMapper.xml"/>
</mappers>
</configuration>
mybatis/flightMapper.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="com.zhaoli.mapper.FlightMapper">
<!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
<select id="getByFlightAll" resultType="com.zhaoli.entity.FlightEntity">
SElECT * FROM dome02_flight;
</select>
</mapper>
解决数据库与类中成员属性不一致性
方式1:
使用 sql语句 as的方法,代码会非常重复。
<?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="com.zhaoli.mapper.FlightMapper">
<!-- namespace+id(全局唯一不允许重复) userMapper.getByUsers -->
<select id="getByFlightAll" resultType="com.zhaoli.entity.FlightEntity">
SElECT id as id
, flight_id as flightId
, company as company
, departure_airport as departureAirport
, arrive_airport as arriveAirport
, departure_time as departureTime
, arrive_time as arriveTime
, model as model
, is_delete as isDelete
FROM dome02_flight;
</select>
</mapper>
方式2:
resultMap
定义数据库表中字段名称与类中成员属性名称 关联映射
数据库字段:例如flight_id
----类中成员名称 flightId
mybatis/flightMapper.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="com.zhaoli.mapper.FlightMapper">
<!-- 定义数据库中字段名与我们类中的成员属性值关联映射 -->
<resultMap id="flightEntityMap" type="com.zhaoli.entity.FlightEntity">
<!-- column="" 数据库中字段名称 property="" FlightEntity 类中的成员属性名称 -->
<id column="id" property="id"></id><!-- id 唯一性 -->
<result column="flight_id" property="flightId"></result><!-- result 与id相比,对应普通属性 -->
<result column="departure_airport" property="departureAirport"></result>
<result column="arrive_airport" property="arriveAirport"></result>
<result column="departure_time" property="departureTime"></result>
<result column="arrive_time" property="arriveTime"></result>
<result column="is_delete" property="isDelete"></result>
</resultMap>
<select id="getByFlightAll2" resultMap="flightEntityMap">
SELECT * FROM dome02_flight;
</select>
</mapper>
2.2 id查询数据
com/zhaoli/mapper/FlightMapper.java
/**
* 根据主键 id 查找航班信息
*/
FlightEntity getByIdFlight(Integer id);
com/zhaoli/service/FlightService.java
/**
* 根据主键 id 查找航班信息
*/
public FlightEntity getByIdFlight(Integer id) {
return flightMapper.getByIdFlight(id);
}
mybatis/flightMapper.xml
<!-- 根据主键 id 查找航班信息 parameterType="" 传递参数的类型 -->
<select id="getByIdFlight" parameterType="int" resultMap="flightEntityMap">
SELECT * FROM dome02_flight WHERE id=#{id};
</select>
com/zhaoli/test/Test01.java
//根据主键 id 查找航班信息
FlightEntity flightEntity = flightService.getByIdFlight(2);
System.out.println(flightEntity)
2.3插入数据
com/zhaoli/mapper/FlightMapper.java
/**
* 添加航班信息
*/
int insertFlight(FlightEntity flightEntity);
com/zhaoli/service/FlightService.java
/**
* 添加航班信息
*/
public int insertFlight(FlightEntity flightEntity) {
int result = flightMapper.insertFlight(flightEntity);
//insert 需要手动提交事务
sqlSession.commit();//提交事务
return result;
}
mybatis/flightMapper.xml
<!-- 添加航班信息 -->
<insert id="insertFlight" parameterType="com.zhaoli.entity.FlightEntity">
INSERT INTO dome02_flight VALUES (null,#{flightId},#{company},#{departureAirport},#{arriveAirport},#{departureTime},#{arriveTime},#{model},#{isDelete});
</insert>
com/zhaoli/test/Test01.java
//添加航班信息
FlightEntity flightEntity = new FlightEntity();
flightEntity.setFlightId("setFlightId");
flightEntity.setCompany("setCompany");
flightEntity.setDepartureAirport("setDepartureAirport");
flightEntity.setArriveAirport("setCompany");
flightEntity.setDepartureTime(new Date());
flightEntity.setArriveTime(new Date());
flightEntity.setModel("setModel");
flightEntity.setIsDelete(0);
int result = flightService.insertFlight(flightEntity);
System.out.println(result);
2.4修改数据
com/zhaoli/mapper/FlightMapper.java
/**
* 根据主键 id 修改航班信息
*/
int updateFlight(FlightEntity flightEntity);
com/zhaoli/service/FlightService.java
/**
- 根据主键 id 修改航班信息
*/
public int updateFlight(FlightEntity flightEntity) {
int result = flightMapper.updateFlight(flightEntity);
//update 需要手动提交事务
sqlSession.commit();//提交事务
return result;
}
mybatis/flightMapper.xml
<!-- 根据主键 id 修改航班信息 -->
<update id="updateFlight" parameterType="com.zhaoli.entity.FlightEntity">
UPDATE dome02_flight
SET id=#{id},
flight_id=#{flightId},
company=#{company},
departure_airport=#{departureAirport},
arrive_airport=#{arriveAirport},
departure_time=#{departureTime},
arrive_time=#{arriveTime},
model=#{model},
is_delete=#{isDelete}
WHERE (id = #{id});
</update>
com/zhaoli/test/Test01.java
//根据主键 id 修改航班信息
FlightEntity flightEntity = new FlightEntity();
flightEntity.setId(19);
flightEntity.setFlightId("setFlightId0");
flightEntity.setCompany("setCompany0");
flightEntity.setDepartureAirport("setDepartureAirport0");
flightEntity.setArriveAirport("setCompany0");
flightEntity.setDepartureTime(new Date());
flightEntity.setArriveTime(new Date());
flightEntity.setModel("setModel0");
flightEntity.setIsDelete(1);
int result = flightService.updateFlight(flightEntity);
System.out.println(result);
2.5删除数据
com/zhaoli/mapper/FlightMapper.java
/**
* 逻辑删除 本质是将 is_delete 值用 update 语句改为 1
*/
int updateDeleteFlight(Integer id);
com/zhaoli/service/FlightService.java
/**
* 逻辑删除 本质是将 is_delete 值用 update 语句改为 1
*/
public int updateDeleteFlight(Integer id) {
int result = flightMapper.updateDeleteFlight(id);
//update 需要手动提交事务
sqlSession.commit();//提交事务
return result;
}
mybatis/flightMapper.xml
<!-- 逻辑删除航班信息 -->
<update id="updateDeleteFlight" parameterType="int">
UPDATE dome02_flight SET is_delete=1 WHERE id=#{id};
</update>
com/zhaoli/test/Test01.java
//逻辑删除
int result = flightService.updateDeleteFlight(10);
System.out.println(result);
2.6 mybatis多条件查询
第一种方法 传递map 型;
第二种方法:多个参数如果不封装成Map
参数值需要通过,多个参数的时候要使用 @Param
给指定参数,否则会出现找不到参数的错误
List<FlightEntity> getByIdFlightParameter(@Param("company") String company
@Param("departureAirport") String departureAirport,
@Param("arriveAirport") String arriveAirport);
第三种方法:传递pojo
; 非常多参数 sql语句中获取参数值名称 与对象成员属性名称需要保持一致(用的较多)
<select id="getByIdFlightPoJo" parameterType="com.zhaoli.entity.FlightEntity"
resultMap="flightEntityMap">
SELECT * from mayikt_flight where company=#{company}
and departure_airport=#{departureAirport} and arrive_airport=#{arriveAirport};
2.7 mybatis动态条件查询
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
使用动态 SQL 并非一件易事,但借助可用于任何 SQL 映射语句中的强大的动态 SQL 语言,MyBatis 显著地提升了这一特性的易用性。
如果你之前用过 JSTL 或任何基于类 XML 语言的文本处理器,你对动态 SQL 元素可能会感觉似曾相识。在 MyBatis 之前的版本中,需要花时间了解大量的元素。借助功能强大的基于 OGNL 的表达式,MyBatis 3 替换了之前的大部分元素,大大精简了元素种类,现在要学习的元素种类比原来的一半还要少。
● if
● choose (when, otherwise)
● trim (where, set)
● foreach
mysql 加上输出日志(会输出sql 语句)
在 mybatis-config.xml 中加入
<settings>
<!-- 打印sql日志 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<if test="逻辑判断"></if>
<select id="getByIdFlightDynamicParameter"
parameterType="com.mayikt.entity.FlightEntity" resultMap="flightEntityMap">
SELECT * from mayikt_flight where
<if test="company!=null and company!=''">
company=#{company}
</if>
<if test="departureAirport!=null and departureAirport!=''">
and departure_airport=#{departureAirport}
</if>
<if test="arriveAirport!=null and arriveAirport!=''">
and arrive_airport=#{arriveAirport};
</if>
</select>
缺陷 如果没有传递company 导致sql报错 改进如下
<select id="getByIdFlightDynamicParameter" parameterType="com.mayikt.entity.FlightEntity"
resultMap="flightEntityMap">
SELECT * from mayikt_flight where
1=1
<if test="company!=null and company!=''">
and company=#{company}
</if>
<if test="departureAirport!=null and departureAirport!=''">
and departure_airport=#{departureAirport}
</if>
<if test="arriveAirport!=null and arriveAirport!=''">
and arrive_airport=#{arriveAirport};
</if>
</select>
可以使用<where></where> 用的最多
<select id="getByIdFlightDynamicParameter"
parameterType="com.mayikt.entity.FlightEntity" resultMap="flightEntityMap">
SELECT * from mayikt_flight
<where>
<if test="company!=null and company!=''">
and company=#{company}
</if>
<if test="departureAirport!=null and departureAirport!=''">
and departure_airport=#{departureAirport}
</if>
<if test="arriveAirport!=null and arriveAirport!=''">
and arrive_airport=#{arriveAirport};
</if>
</where>
</select>
3.MyBatis - 映射文件标签
3.1映射文件的顶级元素
顶级元素 | 描述 |
---|---|
select | 映射查询语句。 |
insert | 映射插入语句。 |
update | 映射更新语句。 |
delete | 映射删除语句。 |
sql | 可以重用的 SQL 代码块。 |
resultMap | 用来描述如何从数据库结果集中加载对象,是最复杂且强大的元素。 |
cache | 配置给定命名空间的缓存。 |
cache-ref | 从其他命名空间引用缓存配置。 |
3.2 select 标签的属性信息
<select
<!--
1. id(必须配置)
id是命名空间中的唯一标识符,可被用来代表这条语句
一个命名空间(namespace)对应一个dao接口
这个id也应该对应dao里面的某个方法(sql相当于方法的实现),因此id应该与方法名一致
-->
id="selectUser"
<!--
2. parapeterType(可选配置,默认由mybatis自动选择处理)
将要传入语句的参数的完全限定名或别名,如果不配置,mybatis会通过ParamterHandler根据参数类型默认选择合适的typeHandler进行处理
paramterType 主要指定参数类型,可以是int, short, long, string等类型,也可以是复杂类型(如对象)
-->
parapeterType="int"
<!--
3. resultType(resultType 与 resultMap 二选一配置)
用来指定返回类型,指定的类型可以是基本类型,也可以是java容器,也可以是javabean
-->
resultType="hashmap"
<!--
4. resultMap(resultType 与 resultMap 二选一配置)
用于引用我们通过 resultMap 标签定义的映射类型,这也是mybatis组件高级复杂映射的关键
-->
resultMap="USER_RESULT_MAP"
<!--
5. flushCache(可选配置)
将其设置为true,任何时候语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false
-->
flushCache="false"
<!--
6. useCache(可选配置)
将其设置为true,会导致本条语句的结果被二级缓存,默认值:对select元素为true
-->
useCache="true"
<!--
7. timeout(可选配置)
这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数,默认值为:unset(依赖驱动)
-->
timeout="10000"
<!--
8. fetchSize(可选配置)
这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为:unset(依赖驱动)
-->
fetchSize="256"
<!--
9. statementType(可选配置)
STATEMENT, PREPARED或CALLABLE的一种,这会让MyBatis使用选择Statement, PrearedStatement或CallableStatement,默认值:PREPARED
-->
statementType="PREPARED"
<!--
10. resultSetType(可选配置)
FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为:unset(依赖驱动)
-->
resultSetType="FORWORD_ONLY"
></select>
3.3 resultMap 标签的属性信息
<!--
1. type 对应的返回类型,可以是javabean, 也可以是其它
2. id 必须唯一, 用于标示这个resultMap的唯一性,在使用resultMap的时候,就是通过id引用
3. extends 继承其他resultMap标签
-->
<resultMap type="" id="" extends="">
<!--
1. id 唯一性,注意啦,这个id用于标示这个javabean对象的唯一性, 不一定会是数据库的主键(不要把它理解为数据库对应表的主键)
2. property 属性对应javabean的属性名
3. column 对应数据库表的列名
(这样,当javabean的属性与数据库对应表的列名不一致的时候,就能通过指定这个保持正常映射了)
-->
<id property="" column=""/>
<!--
result 与id相比,对应普通属性
-->
<result property="" column=""/>
<!--
constructor 对应javabean中的构造方法
-->
<constructor>
<!-- idArg 对应构造方法中的id参数 -->
<idArg column=""/>
<!-- arg 对应构造方法中的普通参数 -->
<arg column=""/>
</constructor>
<!--
collection 为关联关系,是实现一对多的关键
1. property 为javabean中容器对应字段名
2. ofType 指定集合中元素的对象类型
3. select 使用另一个查询封装的结果
4. column 为数据库中的列名,与select配合使用
-->
<collection property="" column="" ofType="" select="">
<!--
当使用select属性时,无需下面的配置
-->
<id property="" column=""/>
<result property="" column=""/>
</collection>
<!--
association 为关联关系,是实现一对一的关键
1. property 为javabean中容器对应字段名
2. javaType 指定关联的类型,当使用select属性时,无需指定关联的类型
3. select 使用另一个select查询封装的结果
4. column 为数据库中的列名,与select配合使用
-->
<association property="" column="" javaType="" select="">
<!--
使用select属性时,无需下面的配置
-->
<id property="" column=""/>
<result property="" column=""/>
</association>
</resultMap>
3.4 insert 标签的属性信息
<insert
<!--
同 select 标签
-->
id="insertProject"
<!--
同 select 标签
-->
paramterType="projectInfo"
<!--
1. useGeneratedKeys(可选配置,与 keyProperty 相配合)
设置为true,并将 keyProperty 属性设为数据库主键对应的实体对象的属性名称
-->
useGeneratedKeys="true"
<!--
2. keyProperty(可选配置,与 useGeneratedKeys 相配合)
用于获取数据库自动生成的主键
-->
keyProperty="projectId"
>
3.5重用 sql 标签和完全限定名使用别名替代
重用 sql 标签
<sql id="userColumns">id,username,password</sql>
完全限定名使用别名替代
每个 sql 映射文件的要元素中,都需要指定一个名称空间,用以确保每个映射语句的 id 属性不会重复。如<mapper namespace="com.mayikt.mapper.UserMapper">
在 Java 代码中引用某个 sql 映射时,使用的亦是含有名称空间的全路径。如
session.update("com.mayikt.mapper.UserMapper.udpateUser", user);
4. 常见问题
常见问题1
alt+enter 选择第一个
常见问题2
Mapped Statements collection does not contain value for getByUsersAll
没有找到该getByUsersAll
对应sql
语句 没有将Mapped
交给mybatis
扫描到
常见问题3
Could not find resource mybatis/userMapper2.xml
clean
清除 编译class
常见问题4
Cause: org.apache.ibatis.builder.BuilderException: Error parsing Mapper XML. Cause: java.lang.IllegalArgumentException: Mapped Statements collection already contains value for userMapper.getByUsers
getByUsers
查找sql
语句 发现 有两个?