MyBatis

Posted South.return

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis相关的知识,希望对你有一定的参考价值。

目录

概述

开发步骤

1. 搭建环境

2. 编写测试代码

映射文件

增删改查

配置文件

核心配置文件深入

相应API

Dao层实现

传统开发模式

代理开发方式

注解开发

常用注解

案例实现

概述

mybatis 是一个优秀的基于 java的持久层框架,它内部封装了jdbc,使开发者只需要关注 sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建 statement等繁杂的过程。

mybatis通过 xml或注解的方式将要执行的各种 statement配置起来,并通过 java对象和 statement中 sql的动态参数进行映射生成最终执行的 sql语句。

最后 mybatis框架执行 sql并将结果映射为 java对象并返回。采用ORM思想解决了实体和数据库映射的问题,对 jdbc 进行了封装,屏蔽了 jdbc api 底层访问细节,使我们不用与 jdbc api 打交道,就可以完成对数据库的持久化操作。

开发步骤

  1. 添加MyBatis的坐标
  2. 创建user数据表
  3. 编写User实体类 
  4. 编写映射文件UserMapper.xml
  5. 编写核心文件SqlMapConfig.xml
  6. 编写测试类

1. 搭建环境

1.1 导入MyBatis的坐标和其他相关坐标

<!--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>5.1.6</version>    
    <scope>runtime</scope>
</dependency>
<!--单元测试坐标-->
<dependency>    
    <groupId>junit</groupId>    
    <artifactId>junit</artifactId>    
    <version>4.12</version>    
    <scope>test</scope>
</dependency>
<!--日志坐标-->
<dependency>    
    <groupId>log4j</groupId>    
    <artifactId>log4j</artifactId>    
    <version>1.2.12</version>
</dependency>

1.2 创建user数据表

1.3 编写User实体

public class User     
	private int id;    
	private String username;    
	private String password;
    //省略get和set方法

1.4 编写UserMapper映射文件

<?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="findAll" resultType="com.itheima.domain.User">        
		select * from User    
	</select>

</mapper>

1.5 编写jdbc.properties配置文件

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.username=root
jdbc.password=root

1.6 编写MyBatis核心文件

<?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>

    <!--通过properties标签加载外部properties文件-->
    <properties resource="jdbc.properties"></properties>

	<!--数据源环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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>

    <!--加载映射文件-->
    <mappers>
        <mapper resource="com/itheima/mapper/UserMapper.xml"></mapper>
    </mappers>
</configuration>

2. 编写测试代码

    @Test
    //查询操作
    public void test1() throws IOException 
        //获取核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得session工厂对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得session会话对象
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行操作 参数:namespace+id
        List<User> userList = sqlSession.selectList("userMapper.findAll");
        //打印数据
        System.out.println(userList);
        //释放资源
        sqlSession.close();
    

映射文件

图示:

映射文件深入<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<where>:where条件
<if>:if判断
<foreach>:循环
<sql>:sql片段抽取

<foreach>标签用于遍历集合,属性:

•collection:代表要遍历的集合元素,注意编写时不要写#
•open:代表语句的开始部分
•close:代表结束部分
•item:代表遍历集合的每个元素,生成的变量名
•sperator:代表分隔符

增删改查

插入操作注意

1. 插入语句使用insert标签
2. 在映射文件中使用parameterType属性指定要插入的数据类型
3. Sql语句中使用#实体属性名方式引用实体中的属性值
4. 插入操作使用的API是sqlSession.insert("命名空间.id",实体对象);
5. 插入操作涉及数据库数据变化,所以要使用sqlSession对象显示的提交事务,即sqlSession.commit() 

修改操作注意

1. 修改语句使用update标签
2. 修改操作使用的API是sqlSession.update("命名空间.id",实体对象);

删除操作注意

1. 删除语句使用delete标签
2. Sql语句中使用#任意字符串方式引用传递的单个参数
3. 删除操作使用的API是sqlSession.delete("命名空间.id",Object);

知识小结

配置文件

层级关系
environments标签

概述:数据源环境配置标签,支持多环境配置

 

事务管理器(transactionManager)类型有两种

JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域

MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期

(比如 JEE 应用服务器的上下文) 默认情况下它会关闭连接,然而一些容器并不希望这样

因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为

数据源(dataSource)类型有三种

UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接

POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来

JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用

容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用

mapper标签

概述:该标签的作用是加载映射配置

使用相对于类路径的资源引用,例如:
        <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>

使用完全限定资源定位符 (URL),例如:
        <mapper url="file:///var/mappers/AuthorMapper.xml"/>

使用映射器接口实现类的完全限定类名,例如:
        <mapper class="org.mybatis.builder.AuthorMapper"/>

将包内的映射器接口实现全部注册为映射器,例如:
        <package name="org.mybatis.builder"/>

Properties标签

概述:加载外部的properties文件

 

typeAliases标签

概述:设置类型别名

 

常用的类型的别名

核心配置文件深入

typeHandlers标签

概述:无论是 MyBatis 在预处理语句 (PreparedStatement)中设置一个参数时,

还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成

Java 类型

开发步骤:

①定义转换类继承类BaseTypeHandler<T>
②覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的

回调方法getNullableResult为查询时 mysql的字符串类型转换成 java的Type类型的方法
③在MyBatis核心配置文件中进行注册

默认的类型处理器:

plugins标签

概述:MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的

复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤:

①导入通用PageHelper的坐标
②在mybatis核心配置文件中配置PageHelper插件
③测试分页数据获取

相应API

SqlSession工厂构建器

SqlSessionFactoryBuilder

SqlSession工厂对象

SqlSessionFactory

SqlSession会话对象
操作事务的方法void commit() 提交事务
void rollback() 回滚事务

Dao层实现

传统开发模式

  1. 编写UserDao接口
  2. 编写UserDaoImpl实现
  3. 测试传统方式

代理开发方式

概述:Mapper 接口开发方法只需要程序员编写Mapper 接口 (相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper 接口开发需要遵循以下规范:

  • Mapper.xml文件中的namespace与mapper接口的全限定名相同
  • Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  • Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
  • Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

编写UserMapper接口:

具体实现

UserMapper接口:

public interface UserMapper 
    //根据id查询用户信息
    public User findById(int id);

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="com.itheima.dao.UserMapper">

    <!--根据id进行查询-->
    <select id="findById" parameterType="int" resultType="user">
        select * from user where id=#id
    </select>

</mapper>

sqlMapConfig.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>

    <!--通过properties标签加载外部properties文件-->
    <properties resource="jdbc.properties"></properties>

    <!--自定义别名-->
    <typeAliases>
        <typeAlias type="com.User" alias="user"></typeAlias>
    </typeAliases>

    <!--数据源环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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>

    <!--加载映射文件-->
    <mappers>
        <mapper resource="com.itheima.mapper\\UserMapper.xml"></mapper>
    </mappers>

</configuration>

测试代码:

    public static void main(String[] args) throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = mapper.findById(1);
        System.out.println(user);
    

注解开发

概述:Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件。

常用注解

  • @Insert:实现新增
  • @Update:实现更新
  • @Delete:实现删除
  • @Select:实现查询
  • @Result:实现结果集封装
  • @Results:可以与@Result 一起使用,封装多个结果集
  • @One:实现一对一结果集封装
  • @Many:实现一对多结果集封装
复杂映射开发

案例实现

注意:此处省略了环境搭建、数据库的设计展示、连接数据库文件的编写等操作。

1. 创建实体

//实体User类
public class User     
	private int id;    
	private String username;    
	private String password;
    //描述当前用户具有的订单
    private List<Order> orderList;

    //省略get和set方法
//实体Order类
public class Order 
    private int id;
    private Date ordertime;
    private double total;
    //当前订单属于哪一个用户
    private User user;

    //省略get和set方法

2. 编写sqlMapConfig.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>

    <!--通过properties标签加载外部properties文件-->
    <properties resource="jdbc.properties"></properties>

    <!--自定义别名-->
    <typeAliases>
        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>
    </typeAliases>

    <!--注册类型处理器-->
    <typeHandlers>
        <typeHandler handler="com.itheima.handler.DateTypeHandler"></typeHandler>
    </typeHandlers>

    <!--数据源环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <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>

    <!--加载映射关系-->
    <mappers>
        <!--指定接口所在的包-->
        <package name="com.itheima.mapper"/>
    </mappers>

</configuration>

3. 接口实现

//User接口
public interface UserMapper 

    @Select("select * from user where id=#id")
    public User findById(int id);
//Order接口
public interface OrderMapper 

    @Select("select * from orders")
    @Results(
            @Result(column = "id", property = "id"),
            @Result(column = "ordertime", property = "ordertime"),
            @Result(column = "total", property = "total"),
            @Result(
                    property = "user", //要封装的属性名称
                    column = "uid", //根据哪个字段去查询user表的数据
                    javaType = User.class, //要封装的实体类型
                    //select属性 代表查询哪个接口的方法获得数据
                    one = @One(select = "com.itheima.mapper.UserMapper.findById")
            )
    )
    public List<Order> findAll();

4. 测试类

public class MyBatisTest 

    private OrderMapper mapper;

    @Before
    public void before() throws IOException 
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        mapper = sqlSession.getMapper(OrderMapper.class);
    

    @Test
    public void testFindAll() 
        List<Order> all = mapper.findAll();
        for (Order order : all)
            System.out.println(order);
        
    
文件层级关系


以上是关于MyBatis的主要内容,如果未能解决你的问题,请参考以下文章

MyBatis1:MyBatis入门

MyBatis源码分析二MyBatis回顾

MyBatis1:MyBatis入门

MyBatis源码分析二MyBatis回顾

Mybatis 一级缓存,Mybatis 二级缓存,Mybatis 缓存失效

Mybatis-Plus:快速开始(SpringBoot + Mybatis + Mybatis)