Mybatis学习 详细

Mybatis是一个持久层框架,简化了jdbc操作,支持自定义SQL、存储过程以及高级映射。本文详细介绍了Mybatis的入门步骤、工作原理、关键配置,如$和#的区别、缓存机制、JavaType和jdbcType对应关系,并讨论了XML配置文件的结构,包括属性、设置、类型处理器等。同时,文章强调了自动映射和缓存的使用注意事项,以及动态SQL的使用,如if、choose、foreach等。
摘要由CSDN通过智能技术生成

Mybatis 是一个持久层框架,它可以自定义sql、存储过程、高级映射。使用它,你可以免去书写jdbc、设置参数、获取结果集的操作。通过简单的xml或注解配置和映射原始类型、接口、Java POJO为数据库中的记录 。

Mybatis入门

1.添加mybatis依赖
2.用SqlSessionFactoryBuilder从xml配置文件或java代码中构建SqlSessionFactory。xml配置文件中包含了mybatis系统的核心设置,获取数据库连接实例的数据源(DataSource),决定事务作用域和控制方法的事务管理器(TransactionManager)。
3.SqlSessionFactory生产SqlSession
4.mapper.xml命名空间绑定Mapper接口
5.SqlSession获取Mapper代理类实例,调用方法

Mybatis工作原理?

Mybatis关键部分

SqlSessionFactoryBuilder
SqlSessionFactory:全局只需要一个
SqlSession:每个请求要一个,线程不安全
Mapper:映射器是绑定语句的接口
mapper.xml

$和#的区别

#{}:可以获取map中的值或者pojo对象属性的值;

: 可 以 获 取 m a p 中 的 值 或 者 p o j o 对 象 属 性 的 值 ; ​ s e l e c t ∗ f r o m t b l e m p l o y e e w h e r e i d = {}:可以获取map中的值或者pojo对象属性的值; ​ select * from tbl_employee where id= mappojoselectfromtblemployeewhereid={id} and last_name=#{lastName}
Preparing: select * from tbl_employee where id=2 and last_name=?
区别:
#{}:是以预编译的形式,将参数设置到sql语句中;PreparedStatement;防止sql注入
${}:取出的值直接拼装在sql语句中;会有安全问题;

Mybatis中javaType和jdbcType对应关系

JDBC Type            Java Type
CHAR                String
VARCHAR                String
LONGVARCHAR            String
NUMERIC                java.math.BigDecimal
DECIMAL                java.math.BigDecimal
BIT                boolean
BOOLEAN                boolean
TINYINT                byte
SMALLINT            short
INTEGER                int
BIGINT                long
REAL                float
FLOAT                double
DOUBLE                double
BINARY                byte[]
VARBINARY            byte[]
LONGVARBINARY                byte[]
DATE                java.sql.Date
TIME                java.sql.Time
TIMESTAMP            java.sql.Timestamp
CLOB                Clob
BLOB                Blob
ARRAY                Array
DISTINCT            mapping of underlying type
STRUCT                Struct
REF                            Ref
DATALINK            java.net.URL[color=red][/color]

mybatis缓存

一级缓存

默认开启一级缓存。一级缓存是对同一个sqlSession而言的。

  • 同一个sqlSession,会将sql和实参生成key,结果作为value,放入一个map中,第二次相同的sql和实参时,直接返回map中的结果
  • select标签的属性flushCache可控制是否清空缓存。
  • 不同sqlSession的缓存相互隔离
  • update、delete、insert之后清空缓存

二级缓存

默认关闭。二级缓存的作用域是namespace。二级缓存,存的是结果序列化后的,因此实体类要实现Serializable。update、delete、insert后会清空缓存。在读多写少时开启。

<mapper namespace="me.gacl.mapping.userMapper">
<!-- 开启二级缓存 -->
<cache/>

xml配置文件的结构

configuration(配置)
	properties(属性)
	settings(设置)
	typeAliases(类型别名)
	typeHandlers(类型处理器)
	objectFactory(对象工厂)
	plugins(插件)
	environments(环境配置)
		environment(环境变量)
			transactionManager(事务管理器)
			dataSource(数据源)
	databaseIdProvider(数据库厂商标识)
	mappers(映射器)

属性(properties)

属性中声明的属性值可以被当前配置文件中的其他标签使用。提高属性的复用性,同时便于我们修改。

属性的来源
  • 子标签property声明的
  • properties标签的resource属性指定的.properties文件
  • properties标签的url属性指定的.properties文件
  • 方法传入的参数

优先级:方法传入的参数 > resource/url指定的.properties文件 > 子标签property声明的。高优先级的会覆盖低优先级的同名属性

可以为占位符设置默认值,这个特性默认关闭,需要开启。
<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${username:ut_user}"/> <!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' -->
</dataSource>

这个特性默认是关闭的。要启用这个特性,需要添加一个特定的属性来开启这个特性。例如:

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 启用默认值特性 -->
</properties>
默认的分隔符可以自定义
<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 -->
</properties>

<dataSource type="POOLED">
  <!-- ... -->
  <property name="username" value="${db:username?:ut_user}"/>
</dataSource>

设置(Settings)

useGeneratedKeys

useGeneratedKeys,新增记录之后返回自增的主键ID。
全局设置useGeneratedKeys,对注解映射器生效,对xml映射器不生效。注解映射器可以通过@Options注解设置useGeneratedKeys。xml映射器需设置insert标签的属性useGeneratedKeys。

<settings>
<!-- 
允许JDBC支持自动生成主键,需要驱动兼容。 
如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 
-->
<setting name="useGeneratedKeys" value="true" />
</settings>
此时,在接口映射中添加记录之后将返回主键ID。

public interface TestMapper {
   
    // 受全局useGeneratedKeys参数控制,添加记录之后将返回主键id
    @Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
    Integer insertOneTest(Test test);
}

// 在接口映射器中设置的useGeneratedKeys参数值将会覆盖在settings元素中设置全局useGeneratedKeys参数值
@Options(useGeneratedKeys = false, keyProperty = "id", keyColumn = "id")
@Insert("insert into test(name,descr,url,create_time,update_time) values(#{name},#{descr},#{url},now(),now())")
Integer insertOneTest(Test test);
在xml映射器中配置useGeneratedKeys参数
<!-- 插入数据:返回记录的id值 -->
<insert id="insertOneTest" parameterType="org.chench.test.mybatis.model.Test" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
    insert into test(name,descr,url,create_time,update_time) 
    values(#{name},#{descr},#{url},now(),now())
</insert>
设置名 描述 默认值
mapUnderscoreToCamelCase 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 False
logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 未设置
jdbcTypeForNull 当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 OTHER
defaultExecutorType 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 SIMPLE
cacheEnabled 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 false
aggressiveLazyLoading 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 false (在 3.4.1 及之前的版本中默认为 true)
autoMappingBehavior 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。 FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 PARTIAL

mapUnderscoreToCamelCase

1.第一种使用resultMap一一对应映射

<?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.easycare.dao.CommonInfoMapper">

	<resultMap id="BaseResultMap"
		type="com.easycare.entity.CommonInfo">
		<id column="comment_id" jdbcType="VARCHAR" property="commentId" />
		<result column="prescription_order_id" jdbcType="VARCHAR"
			property="prescriptionOrderId" />
		<result column="customer_id" jdbcType="VARCHAR"
			property="customerId" />
		<result column="content" jdbcType="VARCHAR" property="content" />
		<result column="grade" jdbcType="INTEGER" property="grade" />
	</resultMap>
	
	<select id="test1" resultMap="BaseResultMap">
		select
			comment_id,
			prescription_order_id,
			customer_id,
			content,
			grade
		from
			tb_comment_info
	</select>
</mapper>

直接用resultMap作为接受类型,再把获取的数据一一对应映射到实体上

这样也可以实现将下划线转换为驼峰式命名

2.第二种 mapUnderscoreToCamelCase

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL Map Config 3.0//EN"  
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 配置mybatis自动转换为驼峰式命名 -->
	<settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

</configuration>

直接在mybatis-config.xml配置文件中添加以上代码 或者在

application.yml中配置

#mybatis配置
mybatis:
   configuration:
    map-underscore-to-camel-case: true

然后mybatis中直接使用对应的实体类(注意不能是Map)作为接受类型

<?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.easycare.dao.CommonInfoMapper">

	<select id="test3" parameterType="pd"
		resultType="com.easycare.entity.CommonInfo">
		select
			comment_id,
			prescription_order_id,
			customer_id,
			content,
			grade
		from
			tb_comment_info
		<where>
			comment_id=2
		</where>
	</select>
</mapper>

defaultExecutorType

mybatis提供三种sql执行器,分别是SIMPLE、REUSE、BATCH。
SIMPLE是默认执行器,根据对应的sql直接执行,不会做一些额外的操作。
REUSE是可重用执行器,重用对象是Statement(即该执行器会缓存同一个sql的Statement,省去Statement的重新创建,优化性能)(即会重用预处理语句)
BATCH执行器会重用预处理语句,并执行批量更新。
即executor-type有三种值,即SIMPLE、REUSE、BATCH。
执行效果:
executor-type值为SIMPLE、REUSE,可通过insert、update、delete方法的返回值判断sql是否执行成功,返回非0表示执行sql成功的条数,返回0表示sql执行失败
executor-type值为BATCH,insert、update、delete方法返回值一直会是负数-2147482646,在该模式下insert、update、delete返回值将无任何意义,不能作为判断sql执行成功的判断依据
BATCH下事务不能自动提交。

SimpleExecutor 比 ReuseExecutor 的性能要差 , 因为 SimpleExecutor 没有做 PSCache。为什么做了 PSCache 性能就会高呢 , 因为当SQL越复杂占位符越多的时候预编译的时间也就越长,创建一个PreparedStatement对象的时间也就越长。猜想中BatchExecutor比ReuseExecutor功能强大性能高,实际上并非如此,BatchExecutor是没有做PSCache的。BatchExecutor 与 SimpleExecutor 和 ReuseExecutor 还有一个区别就是 , BatchExecutor 的事务是没法自动提交的。因为 BatchExecutor 只有在调用了 SqlSession 的 commit 方法的时候,它才会去执行 executeBatch 方法。
————————————————
版权声明:本文为CSDN博主「诺浅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq32933432/article/details/104514028

在mybatis+spring中ExecutorType的使用
1、在spring配置文件中添加批量执行的SqlSessionTemplate

<!--配置一个可以进行批量执行的sqlSession  -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
    <constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>

autoMappingBehavior

自动映射
自动映射详解文章
对于咱们开发来说,自动映射确实可以帮助我们节省一些代码,不过也存在一些隐患,我们希望自己开发的系统是健壮的,建议大家写mapper xml的时候,还是花点时间将映射的配置都给写上去,这样能够杜绝一些隐患,使我们的系统更稳定。

aggressiveLazyLoading

现在可以更明确aggressiveLazyLoading的作用了:
true:
只要调用任意具有懒加载特性的对象的任意一个属性将完整加载整个对象,即触发级联效果。
false:
只加载调用的属性,不调用的属性不加载。

jdbcTypeForNull

不要依赖mybatis的jdbcTypeForNull全局设置,应该对每个#{xxx, jdbcType=}都指定jdbcType

typeAliases

类型别名可为 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>

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:

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

每一个在包 domain.blog 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。 比如 domain.blog.Author 的别名为 author;若有注解,则别名为其注解值。见下面的例子:

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

下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。


别名	映射的类型
_byte	byte
_long	long
_short	short
_int	int
_integer	int
_double	double
_float	float
_boolean	boolean
string	String
byte	Byte
long	Long
short	Short
int	Integer
integer	Integer
double	Double
float	Float
boolean	Boolean
date	Date
decimal	BigDecimal
bigdecimal	BigDecimal
object	Object
map	Map
hashmap	HashMap
list	List
arraylist	ArrayList
collection	Collection
iterator	Iterator

类型处理器(typeHandlers)

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器。

提示 从 3.4.5 开始,MyBatis 默认支持 JSR-310(日期和时间 API) 。


类型处理器	Java 类型	JDBC 类型
BooleanTypeHandler	java.lang.Boolean, boolean	数据库兼容的 BOOLEAN
ByteTypeHandler	java.lang.Byte, byte	数据库兼容的 NUMERIC 或 BYTE
ShortTypeHandler	java.lang.Short, short	数据库兼容的 NUMERIC 或 SMALLINT
IntegerTypeHandler	java.lang.Integer, int	数据库兼容的 NUMERIC 或 INTEGER
LongTypeHandler	java.lang.Long, long	数据库兼容的 NUMERIC 或 BIGINT
FloatTypeHandler	java.lang.Float, float	数据库兼容的 NUMERIC 或 FLOAT
DoubleTypeHandler	java.lang.Double, double	数据库兼容的 NUMERIC 或 DOUBLE
BigDecimalTypeHandler	java.math.BigDecimal	数据库兼容的 NUMERIC 或 DECIMAL
StringTypeHandler	java.lang.String	CHAR, VARCHAR
...

你可以重写已有的类型处理器或创建你自己的类型处理器来处理不支持的或非标准的类型。 具体做法为:实现 org.apache.ibatis.type.TypeHandler 接口, 或继承一个很便利的类 org.apache.ibatis.type.BaseTypeHandler, 并且可以(可选地)将它映射到一个 JDBC 类型。

result标签指定typeHandler

	<resultMap type="org.apache.ibatis.submitted.rounding.User" id="usermap2">
		<id column="id" property="id"/>
		<result column
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值