Mybatis笔记

1、JDBC:

(1)概念:

​ java DataBase Connectivity(java数据库连接、java语言操作数据库)

(2)JDBC本质:

​ 官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们只需要使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类

(3)JDBC使用步骤:

a:导入驱动jar包(其他厂商提供):

b:注册驱动:

Class.forName("com.mysql.jdbc.Driver")

c:获取数据库连接对象:

Connection conn = DriverManager.getConnection( url等参数 )

d:定义sql:

String sql = "update account set balance = 500 where id = 1"

e:获取执行SQL的对象:

Statement stmt = conn.createStatement()

f:执行SQL:

int count = stmt.executeUpdate(sql)

g:处理结果:

h:释放资源:

stmt.close()
conn.close()

(4)为什么高版本(5以后)的mysql不需要再注册驱动:

	5以后,在mysql的jar包的 META-INF/services/java.sql.Driver文件中有 com.mysql.cj.jdbc.Driver 全限类名。
	在DriverManger被加载的时候会执行其中的静态代码块,在静态代码块中会读取这个文件并加载类

2、连接池:

(1)DataSource(连接池标准接口):

	sun公司提供了DataSource标准接口,由各大厂商提供实现类

​	阿里巴巴的Druid、通过工厂DruidDataSourceFactory获得连接池对象
		|- 导入jar包
		|- 在资源目录配置properties文件(DataSource四大参数、最大连接数等)
		|- 使用DruidDataSourceFactory.createDataSource()得到DataSource
		|- 使用DataSource.getConnection()获取数据库连接

3、JdbcTemplate(Spring对JDBC的封装):

(1)JdbcTemplate类在Spring-jdbc-jar包中
(2)new JdbcTemplate(DataSource数据源对象)

--------------------------------------------------mybatis------------------------------------------------------

1、Mybatis执行流程:

在这里插入图片描述

2、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>
    <!-- 和spring整合后 environments配置将废除-->
    <environments default="development">
        <!-- 可以配置多个environment -->
        <environment id="development">
            <!-- 使用jdbc事务管理-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/shopdb" />
                <property name="username" value="root" />
                <property name="password" value="123" />
            </dataSource>
        </environment>
    </environments>
</configuration>

3、#{}与${}的区别:

#{}是预编译处理,${}是字符串替换
Mybatis在处理#{}时,会将SQL中的#{}替换为?号,调用PreparedStatement的set方法来赋值
Mybatis在处理${}时,就是把${}替换成变量的值
${}表示一个拼接符号,会出现SQL注入的问题使用#{}可以有效的防止sql注入

4、Mybatis核心对象:

(1)SqlSessionFactoryBuilder:

	作用:SqlSessionFactoryBuilder用于创建SqlSessionFactory
	使用:SqlSessionFactory build = new SqlSessionFactoryBuilder().build( mybatis配置文件的输入流对象 )
      	 这个对象的只是用来创建SqlSessionFactory对象,创建以后就没有用了

(2)SqlSessionFactory:

	作用:SqlSessionFactory是一个接口,接口定义了openSession的不同重载方法,用来获得SqlSession对象
	注意:这个对象创建以后可以重复使用,通常以单例管理

(3)SqlSession:

	作用:SqlSession是一个接口,其中定义了数据库操作,默认使用DefaultSqlSession实现类(此对象操作数据库本质上是通过Executor执行器完成)
    注意:每个线程都应该拥有自己的SqlSession,不能共享。Sqlsession是一个资源,用完需要关闭

a:getMapper()方法:

  核心方法:getMapper(Class clazz) 底层会使用jdk动态代理技术(ProxyInvocationHandler)得到传入的Class/接口的代理类对象

5、Mybatis配置文件可配置内容:

注意:不能颠倒配置顺序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sctr9Ir8-1690421318465)(assets/image-20230724155814489.png)]

6、全局settings配置:

全局参数将会影响mybatis的运行行为

配置选项描述可选值默认值
cacheEnabled全局启用或禁用任何Mapper中配置的缓存true|falsetrue
lazyLoadingEnabled全局启用或禁用延迟加载。当启用后,所有的关系都将被延迟加载。可以通过使用特定关系上的fetchType属性来取代该值。true|falsefalse
aggressiveLazyLoading当启用时,具有惰性加载属性的对象将完全在调用任何惰性属性时加载。否则,每个属性都将按需加载。true|falsetrue
multipleResultSetsEnabled允许或不允许从单个语句返回多个结果集(需要兼容的驱动程序)true|falsetrue
useColumnLabe使用列标签,而不是列名称。不同的驱动程序在这方面的行为也有所不同。请参考驱动程序文档,或测试这两种模式,以确定驱动程序的行为方式。true|falsetrue
useGeneratedKeys允许JDBC支持已生成的密钥。这时需要一个兼容的驱动程序。这个设置强制生成的键在设置为true时使用,因为一些驱动程序拒绝兼容性但仍然可以工作(例如Derby)。true|falsefalse
autoMappingBehavior指定MyBatis是否以及如何自动将列映射到字段/属性。NONE禁用自动映射。PARTIAL只自动映射简单,非嵌套的结果集。FULL将自动映射任何复杂度的结果集(包含嵌套或非嵌套的)。NONE, PARTIAL, FULLPARTIAL
defaultExecutorType配置默认的执行器(Executor):
SIMPLE: 简单执行器
REUSE:重用prepared statement的执行器
BATCH:重用statement并且执行批量更新的执行器
SIMPLE REUSE BATCHSIMPLE
defaultStatementTimeout设置数据库超时时间(单位:秒)任何正数Not Set (null)
safeRowBoundsEnabled允许在嵌套语句上使用行边界。true|falsefalse
mapUnderscoreToCamelCase是否开启, 数据库列:A_COLUMN自动映射为属性:aColumntrue|falsefalse
localCacheScopeMyBatis使用本地缓存来提高查询效率,本地缓存默认Scope是:SESSION, 在同一次SESSION期间执行的所有查询都将被缓存.
localCacheScope=STATEME:本地会话将仅用于stateme的执行,对同一Sql会话的两个不同调用之间将不共享任何数据
SESSION|STATEMENTSESSION
jdbcTypeForNull指定空值的JDBC类型,当没有为参数提供特定的JDBC类型时。一些驱动程序需要指定列JDBC类型,常用的值:NULL,VARCHAR,OTHERJdbcType enumeration.Most common are: NULL,VARCHAR and OTHEROTHER
lazyLoadTriggerMethods指定哪个对象的方法会触发延迟加载方法名列表,多个方法名之间使用逗号分割equlas,
clone,
hashCode,
toString
defaultScriptingLanguage指定动态SQL生成时默认使用的语言。一个类型的别名或完全限定的类名。
callSettersOnNulls指定在检索到的值为空时,是否会调用设置器或映射的put方法。当您依赖于Map.keySet()或空值初始化时,它很有用。请注意原语,如(int、布尔值等)。将不会被设置为null。true|falsefalse
logPrefix指定MyBatis将添加到日志记录器名称中的前缀字符串。任何字符串未设置
logImpl指定MyBatis应该使用哪些日志记录实现类。如果此设置日志记录类不存在,则将自动发现日志记录实现。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING为设置
proxyFactory代理工厂指定MyBatis将用于创建能够实现延迟加载功能的对象的代理工具。CGLIB|JAVASSISTCGLIB

7、Mybatis支持的别名:

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal

8、Mappers映射器配置:

Mapper配置的几种方法:

  • <mapper resource=" " />

使用相对于类路径的资源

如:<mapper resource="sqlmap/User.xml" />

  • <mapper url=" " />

使用完全限定路径

如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />

  • <mapper class=" " />

使用mapper接口类路径

如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

  • <package name=""/>

注册指定包下的所有mapper接口

如:<package name="org.csmf.mybatis.dao"/>

注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

9、ResultMap

(1)匹配属性名与字段名:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8Tgl0Yy0-1690421318466)(assets/image-20230724171430321.png)]

(2)一对一查询:

<!-- 定义一个包含用户信息的Order的ResultMap -->
	<resultMap type="Order" id="orderMap">
		<id column="id" property="id"/>
		<result column="createTime" property="createTime"/>
		<result column="state" property="state"/>
		<!-- 配置关联属性User的信息  -->
		<!-- association:用于映射关联单个对象信息 
			property:关联的属性名,就是将用户对象关联到Order的那个属性
			javaType: 属性的类型
		-->
		<association property="user" javaType="User">
			<id column="id" property="id"></id>
			<result column="username" property="name"/>
			<result column="sex" property="sex"/>
			<result column="password" property="password"/>
			<result column="address" property="address"/>
			<result column="brithday" property="brithday"/>
		</association>
	</resultMap>

(3)一对多查询:

<!-- 定义一个包含Order信息的User的ResultMap -->
	<resultMap type="User" id="userOrderMap">
		<id column="id" property="id"></id>
			<result column="username" property="name"/>
			<result column="sex" property="sex"/>
			<result column="password" property="password"/>
			<result column="address" property="address"/>
			<result column="brithday" property="brithday"/>
		<!-- 订单信息 -->
		<!-- 
			collection:对关联查询到的多条记录映射到集合对象中
			property:将查询到的多条记录映射到User类的那个属性中
			ofType: 指明集合中的元素的类型
		 -->
		<collection property="orders" ofType="Order">
			<id column="oid" property="id"></id>
			<result column="createTime" property="createTime"/>
			<result column="state" property="state"/>
		</collection>
	</resultMap>

(4)多对多查询:

<!-- 定义一个包含Order信息以及OrderDetail信息的User的ResultMap -->
	<resultMap type="User" id="userOrderOrderDetailMap">
		<id column="id" property="id"></id>
			<result column="username" property="name"/>
			<result column="sex" property="sex"/>
			<result column="password" property="password"/>
			<result column="address" property="address"/>
			<result column="brithday" property="brithday"/>
		<!-- 订单信息 -->
		<!-- 
			collection:对关联查询到的多条记录映射到集合对象中
			property:将查询到的多条记录映射到User类的那个属性中
			ofType: 指明集合中的元素的类型
		 -->
		<collection property="orders" ofType="Order">
			<id column="oid" property="id"></id>
			<result column="createTime" property="createTime"/>
			<result column="state" property="state"/>
			<!-- 订单详情信息 -->
			<collection property="orderDetails" ofType="OrderDetail">
				<id column="orderDetailId" property="id"></id>
				<result column="price" property="price"/>
				<result column="num" property="num"/>
			</collection>
		</collection>
	</resultMap>

10、缓存:

先查二级缓存,再找一级缓存

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cyNOKPxn-1690421318467)(assets/image-20230724161748431.png)]

(1)一级缓存:

	Mybatis一级缓存的作用域是同一个SqlSession,在同一个SqlSession中两次执行相同的SQL语句,第一次执行完毕会将数据库中查询的数据写到缓存,第二次会先从缓存中拿数据,如果没有才会从数据库中查询,查询以后将数据写入缓存
	Mybatis内部使用了一个HashMap作为缓存区域,key为hashCode+sqlId+Sql语句
	注意:在分布式的情况下,一级缓存会出现脏读的情况

(2)二级缓存:

	概念:二级缓存区域是根据mapper的namespace划分的,相同namespace的mapper查询数据会放在同一个区域。缓存数据存储在SqlSessionFactory中,也是一个HashMap集合
	开启二级缓存:mybatis的setting中默认是开启二级缓存的,但是要还需要在Mapper映射文件中添加一行: `<cache /> `,表示此mapper开启二级缓存。并要求实体类实现序列化接口
	注意:二级缓存在多表操作的时候会出现脏读情况,因为多表查询的结果只会存入一个命名空间缓存中,但是更新等操作不一定会清除该命名空间的缓存。
	可以设置为共有一个二级缓存空间

(3)禁用二级缓存:

​ 在statement中设置useCache=false可以禁用当前select语句的二级缓存,即每次查询都会发出sql去查询,默认情况是true,即该sql使用二级缓存。

<select id="findOrderListResultMap" resultMap="ordersUserMap" useCache="false">

11、Mybatis执行器(Executor):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GNxpdfUr-1690421318468)(assets/image-20230724170408394.png)]

CachingExecutor: 执行二级缓存

Mybatis的二级缓存: 数据存在: TransactionalCacheManager的 transactionalCaches属性(HashMap)

BaseExecutor: 执行一级缓存 localCache(一级缓存名称)

SimpleExecutor: 操作数据库

SqlSession: 接口
实现类:  DefaultSqlSession

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JperwLN2-1690421318469)(assets/image-20230724170820136.png)]

--------------------------------------------------细节问题---------------------------------------------------

1、mapper.xml文件的拷贝:

如果配置文件没有位于src/main/resources目录下, maven默认不会拷贝这个配置文件

如果想让maven拷贝非src/main/resources目录下的配置文件, 在pom.xml文件中进行配置

	<build>
        <resources>
            <resource>
                <!--拷贝src/main/java目录下
                  ** 后代目录的/*.xml  任意xml文件
                -->
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>true</filtering>
            </resource>

            <resource>
                <!--拷贝src/main/java目录下
                  ** 后代目录的/*.xml  任意xml文件
                -->
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

2、表的字段名与属性名不一样:

​ 解决方案:字段名:a_b 属性名:aB小驼峰

​ 解决方案:可以给字段名取别名

​ 解决方案:使用进行映射

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值