小工具      在线工具  汉语词典  css  js  c++  java

Mybatis轻量级ORM框架

# MyBatis,mybatis,orm 额外说明

收录于:101天前

简介

Mybatis是一个轻量级的ORM框架,具有定制的SQL,它消除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。 MyBatis 可以通过简单的 XML 或注释来配置和映射原始类型、接口和 Java POJO(普通旧 Java 对象)到数据库中的记录。大大简化了持久层的操作。

Mybatis使用

要使用MyBatis,只需将mybatis-x.x.x.jar 文件放在类路径中即可。 POM 或构建路径。

在这里插入图片描述
基于XML文件创建SqlSessionFactory对象:

<--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>
    <properties resource="mybatis.properties"></properties>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>
# mybatis.properties:
driver=
url=
username=
password=

properties注解用于读取properties文件,mybatis支持表达式变量${},#{}直接赋值,当然可以直接再xml中写入。

代码构建SqlSessionlFactory

String resource="mybatis-config.xml";
InputStream inputStream= Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactory是应用级的,而SqlSession是线程级的即每产生一个操作数据库的线程都要构造一个SqlSession。

<?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="bolen.example.dao.UserMapper">
    <select id="selectAll" resultType="bolen.example.pojo.User">
        select * from user
    </select>


</mapper>

基于SqlSession创建查询对象:

SqlSession sqlSession=sqlSessionFactory.openSession();
List<User> list=sqlSession.selectList("bolen.example.dao.UserMapper.selectAll");
System.out.println(list);

SqlSession对象方法的参数基于mapper配置文件的namespace属性和id属性唯一确定。

映射器代理开发

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 resource="mybatis.properties"></properties>
    
    <!--设置-->
    <settings>
        <setting name="" value=""/>
    </settings>
    
    <!--类型别名,用于简写类的全限定名-->
    <typeAliases></typeAliases>
    
    <!--类型处理器-->
    <typeHandlers></typeHandlers>
    
    <!--顺序工厂-->
    <objectFactory type=""></objectFactory>
    
    <!--插件-->
    <plugins>
        <plugin interceptor=""></plugin>
    </plugins>
    
    <!--数据源环境-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <!--数据厂商标识-->
    <databaseIdProvider type=""></databaseIdProvider>
    
    <!--映射器-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

订单无法更改。

类型别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

<typeAliases>
  <typeAlias alias="Author" type="domain.blog.Author"/>
  <typeAlias alias="Blog" type="domain.blog.Blog"/>
  <typeAlias alias="Comment" type="domain.blog.Comment"/>
  <typeAlias alias="Post" type="domain.blog.Post"/>
  <typeAlias alias="Section" type="domain.blog.Section"/>
  <typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>

当以这种方式配置时,博客可以在使用domain.blog.Blog的任何地方使用。

还可以指定包名,MyBatis会在包名下搜索所需的Java Bean,例如:

<typeAliases>
  <package name="domain.blog"/>
</typeAliases>

包domain.blog中的每个Java Bean,如果没有注释,将使用该bean的非限定类名,并以该bean的首字母小写作为其别名。例如domain.blog.Author的别名是author;如果有注释,别名就是它的注释值。请参阅下面的示例:

@Alias("author")
public class Author {
    
    ...
}

制图员
MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。

您可以使用相对于类路径的资源引用,或完全限定的资源定位符(包括 file:/// 形式的 URL),或类和包名称等。

<!-- 使用相对于类路径的资源引用 -->
<mappers>
  <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
  <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
  <mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
  <mapper url="file:///var/mappers/AuthorMapper.xml"/>
  <mapper url="file:///var/mappers/BlogMapper.xml"/>
  <mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
  <mapper class="org.mybatis.builder.AuthorMapper"/>
  <mapper class="org.mybatis.builder.BlogMapper"/>
  <mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>

XML映射结构

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

插入、更新、删除

<insert id="insertAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20">

<update id="updateAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20">

<delete id="deleteAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20">

在这里插入图片描述

select查询语句是MyBatis中最常用的元素之一

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>
<!--#{}用来传递动态参数-->

选择属性

<select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">

在这里插入图片描述

动态SQL

Java API

使用XML文件是配置环境environments,如果你调用了接受 properties 实例的方法,那么 MyBatis 就会加载这些属性,并在配置中提供使用。绝大多数场合下,可以用 ${propName} 形式引用这些配置值。

String resource = "org/mybatis/builder/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);

资源工具类,该类位于org.apache.ibatis.io包中:

SqlSessionFactory的创建:

URL getResourceURL(String resource)
URL getResourceURL(ClassLoader loader, String resource)
InputStream getResourceAsStream(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)
Properties getResourceAsProperties(String resource)
Properties getResourceAsProperties(ClassLoader loader, String resource)
Reader getResourceAsReader(String resource)
Reader getResourceAsReader(ClassLoader loader, String resource)
File getResourceAsFile(String resource)
File getResourceAsFile(ClassLoader loader, String resource)
InputStream getUrlAsStream(String urlString)
Reader getUrlAsReader(String urlString)
Properties getUrlAsProperties(String urlString)
Class classForName(String className)

SqlSession创建:
SqlSessionFactory 有六个方法创建 SqlSession 实例。通常来说,当你选择其中一个方法时,你需要考虑以下几点:

  • 事务处理:是否要在会话范围内使用事务范围,或者使用自动提交或手动提交。
  • 数据库连接:MyBatis 是否帮助从配置的数据源获取连接或使用您自己提供的连接。
  • 语句执行:MyBatis 重用PreparedStatement 和/或批量更新语句。

默认的 openSession() 方法没有参数,并创建具有以下特征的 SqlSession:

  • 将启用事务范围(即不会发生自动提交)。
  • Connection对象将从当前环境中配置的DataSource实例中获取。
  • 事务隔离级别将使用驱动程序或数据源的默认设置。
  • 准备好的语句不会被重用,并且更新不会被批处理。

传参问题

按顺序传递参数


User selectUser(String name, int deptId);
<select id="selectUser" resultType="com.wyj.entity.po.User">
	select * from user where userName = #{0} and deptId = #{1}
</select>

注意:里面的数字代表你传入参数的顺序。不特别推荐使用该方法传递参数,尤其是参数较多时。

注解@Param传递参数

User selectUser(@Param("userName") String name, int @Param("deptId") id);
<select id="selectUser" resultType="com.wyj.entity.po.User">
	select * from user where userName = #{userName} and deptId = #{deptId}
</select>

使用Map集合传递参数

User selectUser(Map<String, Object> params);
<select id="selectUser" parameterType="java.util.Map" resultType="com.wyj.entity.po.User">
	select * from user where userName = #{userName} and deptId = #{deptId}
</select>

使用parameterType限定传入的参数类型,会自动按key同名赋值

使用JavaBean实体类传递参数

User selectUser(User user);
<select id="selectUser" parameterType="com.wyj.entity.po.User" resultType="com.wyj.entity.po.User">
	select * from user where userName = #{userName} and deptId = #{deptId}
</select>

传入的Java Bean是根据成员变量名自动赋值的。

XML的mapper代码开发

xml结构:

在这里插入图片描述
select语句有很多属性:
在这里插入图片描述
在这里插入图片描述

其中最主要的是:
在这里插入图片描述

resultMap结果集映射:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
最主要的是result用于映射Java对象和数据库表。property属性绑定Brand对象的成员变量,column绑定数据库表字段,其他属性用于绑定数据类型。
在这里插入图片描述

insert同样也有很多属性:
在这里插入图片描述

insert、delete、update 只返回受影响的行数,不返回 resultMap

总结:
在这里插入图片描述

动态SQL
在条件查询是常常要使用动态查询
动态SQL
mybatis中文文档

注解开发

最初设计时,MyBatis是一个XML驱动的框架。配置信息是基于XML的,而且映射语句也是定义在XML中的。而到了MyBatis3,有新的选择了:利用注解实现SQL的映射。MyBatis3构建在全面而且强大的Java 注解(Java annotation)之上。注解提供了一种便捷的方式来实现简单SQL映射语句,可以简化编写XML的过程。
http://www.mybatis.cn/archives/678.html

常用的注解分为三类:SQL语句映射、结果集映射和关系映射。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在org.apache.ibatis.annotations包下包含了mybatis所有注解。
http://www.mybatis.org/mybatis-3/zh/java-api.html

@CacheNamespace相当于cache标签和mapper是同级别的,@CacheNamespace,作用于mapper接口上面,是用来实现二级缓存的。
@Property相当于property标签,用于初始化参数。

<properties resource="config.properties">
<!--值会被config.properties中的值所覆盖 -->
  	<property name="username" value="root"/>
   	<property name="password" value="0000"/>
</properties>

@Select@Insert@Update,@Delete是sql语句映射注解,使用注解不需要再xml文件中注入sql语句。
BrandMapper.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="bolen.example.dao.BrandMapper">

</mapper>

注解映射sql语句:


public interface BrandMapper {
    
    @Select("select * from brand")
    List<Brand> selectAll();
}

依然通过${}#{}传递参数。该四个注解只用于简单的sql语句的映射。

@InsertProvider@DeleteProvider@UpdateProvider@SelectProvider,分别对应着sql中的增删改查四种操作。是前四个的升级版。

public interface UserMapper 
{
    
    @SelectProvider(type = SqlProvider.class, method = "selectUser")
    User getUser(long userId);
}

@SelectProvider注解用于生成查询用的sql语句,有别于@Select注解,@SelectProvide指定一个Class及其方法,通过调用该Class的该方法来获取sql语句。在我们的例子中,获取查询sql的方法是SqlProvider.selectUser。

@SelectProvide 中的类型参数指定的 Class 类必须通过无参数构造函数进行初始化。

@SelectProvide中的方法参数指定的方法必须是public,并且返回值必须是String。

public class SqlProvider 
{
    
    public String selectUser(long userId) 
    {
    
      return "select * from user where userId=" + userId;
    }
}

参数问题
通过注解声明的方法,在注解方法中传递参数,当有多个参数时用@Param传递参数。如果使用了@Param注解的话,那么相应sql映射方法必须接受Map<String, Object>做为参数:

public String selectUser2(Map<String, Object> para) 
{
    
    return "select * from user where userId=" + para.get("userId");
}
@SelectProvider(type = SqlProvider.class, method = "selectUser2")
public User getUser2(@Param("userId") long userId);

在超过一个参数的情况下,@SelectProvide方法必须接受Map<String, Object>做为参数。其他三个用法一致。

@Result@Results@ResultMap是结果集映射的三大注解。

持久层通常遇到的问题是Java Bean和数据库之间的字段或数据类不一致,比如Bean中的brandId,字段是brand_id。结果三大注释有效的解决了这些问题。

结果集映射关系声明代码:

@Select({
    "select id, name, class_id from student"})
@Results(id="studentMap", value={
    
    @Result(column="id", property="id", jdbcType=JdbcType.INTEGER, id=true),
    @Result(column="name", property="name", jdbcType=JdbcType.VARCHAR),
    @Result(column="class_id ", property="classId", jdbcType=JdbcType.INTEGER)
})
List<Student> selectAll();

引用结果集代码:

@Select({
    "select id, name, class_id from student where id = #{id}"})
@ResultMap(value="studentMap")
Student selectById(integer id);

@Results各个属性的含义,id为当前结果集声明唯一标识,value值为结果集映射关系。
@Result代表一个字段的映射关系,column指定数据库字段的名称,property指定实体类属性的名称,jdbcType数据库字段类型,@Result里的id值为true表明主键,默认false。
@ResultMap来引用映射结果集,其中value可省略。

当表字段与成员变量不对应时查询不到数据:
在这里插入图片描述
结果集注解实现了resultMap标签的功能:

@Select("select * from brand")
@Result(column = "brand_id",property = "id", jdbcType = JdbcType.INTEGER, id = true)
@Result(column = "brand_name",property = "brandName", jdbcType = JdbcType.VARCHAR)
@Result(column = "company_name", property = "companyName", jdbcType = JdbcType.VARCHAR)
List<Brand> selectAll();

在这里插入图片描述
@Result注解只能本次使用,之后的查询仍然要重写,使用@Results后可以直接使用@Result注解引用,其有id和value属性,value时代码块{}

@Select("slelct * from brand")
  @Results(id = "brandMapper",value = {
    
          @Result(column = "brand_id",property = "id", jdbcType = JdbcType.INTEGER, id = true),
          @Result(column = "brand_name",property = "brandName", jdbcType = JdbcType.VARCHAR),
          @Result(column = "company_name", property = "companyName", jdbcType = JdbcType.VARCHAR)
  })
  List<Brand> selectAllThree();


//之后可以直接通过@ResultMap引用
@ResultMap(value="brandMappper")

要使用@Results注解,必须使用@Result注解。用@Results注解的ip属性可以用@ResultMap注解并在其他地方引用,简化了@Result的编写。不同的是@Results实现了将数据表封装成Java Bean并且可以复用,而@Result实现了数据项(字段)到Bean成员变量的映射。

@one注解用于一对一关系映射

@Select("select * from student")  
@Results({
      
    @Result(id=true,property="id",column="id"),  
    @Result(property="name",column="name"),  
    @Result(property="age",column="age"),  
    @Result(property="address",column="address_id",one=@One(select="cn.mybatis.mydemo.mappers.AddressMapper.getAddress"))  
})  
public List<Student> getAllStudents();  

@many注解用于一对多关系映射

@Select("select * from t_class where id=#{id}")  
@Results({
      
    @Result(id=true,column="id",property="id"),  
    @Result(column="class_name",property="className"),  
    @Result(property="students", column="id", many=@Many(select="cn.mybatis.mydemo.mappers.StudentMapper.getStudentsByClassId"))  
    })  
public Class getClass(int id); 

@Options注解能够设置缓存时间,能够为对象生成自增的key。
在这里插入图片描述

@Select("select * from brand where brand_id = #{id}}")
@Options(useCache = true,flushCache = Options.FlushCachePolicy.FALSE,timeout = 10000)
@ResultMap(value = "brandMapper")
Brand selectByIdOne(@Param("id") int id);

与查询语句一起使用,主要是切换一些查询选项。例如useCache = true表示将缓存本次查询的结果,以提高下次查询的速度; lushCache = Options.FlushCachePolicy.FALSE 表示查询过程中不会刷新缓存; timeout = 10000 表示查询结果将被缓存10000秒。

@Insert({
    
        "insert into login_ticket(user_id,ticket,status,expired) ",//每句sql语句后面加一个空格
        "values(#{userId},#{ticket},#{status},#{expired})"
})
@Options(useGeneratedKeys = true, keyProperty = "id",keyColumn="brand_id")   //自动生成主键并将生成的值注入给属性id
int insertLoginTicket(LoginTicket loginTicket);

@Options属性userGenerateKeys的值为true,指定实例对象中主键的属性名keyProperty和数据库中的字段名keyColumn。这样,插入数据后,id属性就会自动赋值。

@SelectKey用于向数据库中插入一条数据,同时有希望返回该条记录的主键。http://www.mybatis.cn/archives/741.html

. . .

相关推荐

额外说明

初始进入算法(更新数组)

一,时间复杂度和空间复杂度 二,线性数据结构: 1.数组 2.栈 3.哈希 4.队列 5.链表 数组:偏向查找功能。 //Array:数组 public class MyArray { private int[] array; priva

额外说明

求最大公约数

  求两数的最大公约数的方法:   方法一: public int gcd(int a, int b) { int min=Math.min(a,b); while (min>0){ i

额外说明

超越想象!高效快速的大规模相似性搜索引擎与卓越GPU加速分析,助力您的数据发现新纪元

超越想象!高效快速的大规模相似性搜索引擎与卓越GPU加速分析,助力您的数据发现新纪元 1.什么是相似性搜索 相似性搜索就是根据某些特征,在大量的样本集中搜寻出与目标样本最相似的一个或多个样本。 相似性搜索问题无论是在学术界还是工业界,都是一个研究得比较多

额外说明

(总目录)springboot - 实现zip文件上传并对zip文件解压, 包含上传oss

全文目录,一步到位 1.本文概述 1.1 本文简介 2. 功能实现 2.1 统一文件校验 2.2 普通(多)文件上传[服务器] 2.2.1 controller层 2.2.2 service层 2.2.3 业务impl实现类 2.2.4 FileIOUt

额外说明

【JavaSE】一篇文章领悟Java运算符

前言: 作者简介:爱吃大白菜1132 人生格言:纸上得来终觉浅,绝知此事要躬行   如果文章知识点有错误的地方不吝赐教,和大家一起学习,一起进步!   如果觉得博主文章还不错的话,希望三连支持! 目录 什么是运算符  1.算数运算符  基本四则运算符:加

额外说明

【51单片机】数码管显示(样例展示以及异常分析)

-专栏【51单片机】 -喜欢的诗句:更喜岷山千里雪 三军过后尽开颜。 -音乐分享【如愿】 大一同学小吉,欢迎并且感谢大家指出我的问题- ⭐数码管 比如要显示“6”,那么下面图片中,AFEDCG=1,B=0    对应到数码管上,就是 ⭐原理    -P2

额外说明

javascript中函数,方法,对象,变量,类,函数的调用

函数:与java中的方法一样,这个函数可以被调用。 对象:定义一个函数时,系统也会创建一个对象,该对象是Funtion类的实例。 方法:定义一个函数时,该函数通常都会附加给某个对象,作为该对象的方法。 变量:在定义函数的同时,也会得到一个变量 类:在定义

额外说明

Kubernetes(一)----概述

文章目录 简介 起源 Kubernetes设计架构 Kubernetes节点 分层架构 kubelet kube-proxy Kubernetes控制面板 etcd Kubernetes API Server Scheduler Kubernetes控制

额外说明

Java——JTable表格组件的使用(将数据库的数据展现在窗口)

┏(ω)=☞ 本专栏的目录(为您提供更好的查询方式)(点这里说不定有你想要的) setRowHeight(50);//设置表格高度 准备好数据库表和数据 database类 public class database { private int i

额外说明

在启动游戏时出现找不到loopback-capture.dll文件解决办法

其实很多用户玩单机游戏或者安装软件的时候就出现过这种问题,如果是新手第一时间会认为是软件或游戏出错了,其实并不是这样,其主要原因就是你电脑系统的该dll文件丢失了或没有安装一些系统软件平台所需要的动态链接库,这时你可以下载这个loopback-captu

ads via 小工具