依赖安装
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
配置mybatis-config.xml
- configuration:配置读取的根节点,用于构造SqlSessionFactory回话工厂。
- properties:用于加载外部属性配置或动态替换proerty元素。可集中管理相关属性。
- environments:配置mybatis运行环境,可以配置多种环境,但是SqlSessionFactory实例只能选择一种环境,默认使用(id=development)环境;
- transactionManager:运行环境中事务管理器的配置,type="JDBC|MANAGED";如果使用 Spring + MyBatis,则没有必要配置事务管理器,因为 Spring 模块会使用自带的管理器来覆盖前面的配置;
- dataSource:运行环境中数据库源的配置;如果需要连接多个数据库,就需要创建多个 SqlSessionFactory实例,每个数据库对应一个,可以动态传入properties来指定数据库的信息。
- dataSource的type="POOLED|UNPOOLED|JNDI":
UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源。
- mappers:映射器。需要制定映射文件,可以使用相对路径/绝对路径/类名/包名。
<?xml version="1.0" encoding="UTF-8" ?>
<!--xml头部声明,验证XML文档的正确性-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- mybatis配置文件 -->
<!-- mybatis从configuration节点开始读取配置 -->
<configuration>
<!-- 读取相关属性 -->
<properties resource="jdbc.properties" />
<!-- 配置mybatis运行环境 -->
<environments default="development">
<!--默认使用环境development-->
<environment id="development">
<!-- 事务管理器JDBC -->
<transactionManager type="JDBC"/>
<!-- 数据库连接实例的数据源配置 -->
<dataSource type="POOLED">
<!--数据库驱动-->
<property name="driver" value="${driver}"/>
<!--数据库连接URL-->
<property name="url" value="${url}"/>
<!--数据库用户-->
<property name="username" value="${username}"/>
<!--数据库密码-->
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 对应的映射器列表mapper,需要放入配置中 -->
<mappers>
<!-- 使用相对路径 -->
<mapper resource="mapper/StuScoreMapper.xml" />
</mappers>
</configuration>
可以在mybatis-config.xml中配置properties属性,使用resource加载属性资源文件如jdbc.properties,将属性key-value集中管理。
踩坑:注意属性书写使用key=value,后面不用带";",否则会算入vlaue一部分倒置程序报错如下。MyBatis异常 java.sql.SQLException: Error setting driver on UnpooledDataSource
添加Java实体对象
创建存放实体的package包edward.com.entity,创建StuScore.java实体类来接受数据返回。
package edward.com.entity;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.math.BigDecimal;
@Data
@Getter
@Setter
public class StuScore {
private Long id;
private String name;
private BigDecimal score;
private String subject;
}
使用XML文件配置mapper映射器
在resource下面新建mapper文件夹,再新增StuScore.xml映射文件,在上面mybatis.config.xml的映射器mappers标签中配置<mapper resource="mapper/StuScoreMapper.xml" />,该映射文件就是ORM框架的核心,配置了Java 对象和数据库表之间的映射关系。
- namespace:命令空间,相当于包名,可以直接映射到在命名空间中同名的Dao接口类上。
- id: sql操作的名字,用于调用
- parameterType:传入参数的类型,传入为java类型,转化为sql类型,最后添加到sql语句上
- resultType:返回结果类型,sql结果集转化为java类型并返回。
<?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="edward.com.mapper.StuScoreMapper">
<!-- 根据id查询信息 -->
<select id="selectById" parameterType="Long" resultType="edward.com.entity.StuScore">
select * from `stu_score` where id = #{id}
</select>
</mapper>
从 XML 中构建 SqlSessionFactory
创建MybatisMain入口
package edward.com;
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 edward.com.entity.StuScore;
import java.io.IOException;
import java.io.InputStream;
public class MybatisMain {
public static void main (String[] args) throws IOException {
// 指定XML配置文件
String resource = "mybatis-config.xml";
// 读取配置文件到输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 根据配置文件构建SqlSessionFactory
SqlSessionFactory sqlsessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 通过 SqlSessionFactory 创建 SqlSession
SqlSession session = sqlsessionFactory.openSession();
// SqlSession执行映射文件中定义的SQL,并返回映射结果
// 第一个参数:StuScoreMapper.xml中的命名空间+select的id短名称,全限定名
// 第二个参数为入参
StuScore stuScore = session.selectOne("edward.com.mapper.StuScoreMapper.selectById", 1L);
// 如果短名称全局唯一,也可以使用短名称调用
// StuScore stuScore = session.selectOne("selectById", 1L);
System.out.println(stuScore);
// 提交事务
session.commit();
// 关闭 SqlSession
session.close();
}
}
Mapper映射文件里的命名空间namespace
1、用命名空间+id值全限定名的方式调用mapper中的sql语句,如果短名称id全局唯一也可以作为单独使用,不唯一就得使用全限定名的方式。
2、可用通过命令空间来映射到相同命名空间的java的Dao类上面,实现接口绑定,更加方便的调用sql语句,即Mapper的代理开发模式。
Mapper代理开发模式+Java注解配置mapper映射器
Mapper代理模式:
- Dao接口类的全限定名要和mapper映射文件的namespace相同;
- Dao接口类的方法名要和mapper映射文件中的statement的Id相同;
- Dao接口类的入参、出参也得和mapper映射文件中的statement的parameterType、resultMap一致。
注解:来映射简单语句会使代码显得更加简洁,但不适用稍微复杂一点的SQL语句。
新增edward.com.mapper的包,然后在新增StuScoreMapper接口类,通过session.getMapper();
package edward.com.mapper;
import edward.com.entity.StuScore;
import org.apache.ibatis.annotations.Select;
public interface StuScoreMapper {
@Select("select * from `stu_score` where id = #{id}")
StuScore selectById(Long id);
}
main方法中/SqlSession执行方式修改如下:
//
StuScoreMapper mapper = session.getMapper(StuScoreMapper.class);
StuScore stuScore = mapper.selectById(1L);
但是报错,信息如下:
Mapped Statements collection already contains value for edward.com.mapper.StuScoreMapper.selectById. please check mapper/StuScoreMapper.xml and edward/com/mapper/StuScoreMapper.java (best guess)
解决:
需要将mybatis-config中的mappers中的配置从指定xml方式改为加载接口类的方式,可以通过加载整个包
<mappers>
<!--<mapper resource="mapper/StuScoreMapper.xml" />-->
<package name="edward.com.mapper" />
<!--或者改为class-->
<mapper class="edward.com.mapper.StuScoreMapper" />
</mappers>