java框架知识总结

数据库相关

JDBC

过程
1.加载数据库驱动
Class.forName(“com.mysql.jdbc.Driver”)
2.创建connection
conn=DriverManager.getConnection(“jdbc:mysql://localhost:3306/test?characterEncoding=utf-8”,“root”,“root”)
3.准备statement
预编译防止sql注入
prepareStatement=conn.prepareStatement(sql)
4.设置参数
prepareStatement.setString(“第几个问号”,“参数是什么”)
5.返回结果集
resultSet=prepareStatement.excuteQuery()
6.资源释放
resultSet.close()
缺点
频繁开关数据库连接,影响数据库的性能
存在数据库的硬编码和sql硬编码

Mybatis

是什么
是一个用来操作数据库的持久层框架,不需要关注加载数据库驱动等操作,只需关注sql本身,通过xml或者注解的方式将java对象和statement的sql映射成最终的sql,再将结果映射成java对象返回
原理
在这里插入图片描述

	1.全局配置文件配置了数据源、事务mapper映射文件配置了sql相关操作
	2.mybatis通过读取配置文件构造sqlsessionFactory
	3.sqlSessionFactory创建sqlSession会话操作数据库
	4.sqlsession会话不能直接操作数据库,通过executor执行器接口操作数据库,两个实现类普通执行器和缓存执行器(默认)
	5.executor执行器执行的sql封装到mappedStatement对象中,包括sql、输入参数映射信息、输出结果集映射信息。输入输出的类型包括简单类型、pojo、hashMap 

怎么用
1.jar
2.sqlMapperConfig.xml+Mapper.xml
3.InputStream in=Resource.getResourceAsStream(“sqlMapperConfig.xml”)
4.sqlSessionFactory sf=New SqlSessionFactoryBuilder().build(in)
SqlSessionFactoryBuilder创建工厂后销毁,生命周期在方法内
sqlSessionFactory需要创建sqlSession所以在应用范围内
sqlSession方法体内
5.sqlSession session=sf.openSession()
6.session.update(“test.updateUser”, user)
7.session.commit()
8.session.close()

主键返回的几种类型

主键返回之MySQL自增主键 LAST_INSERT_ID()

<!-- 
		[selectKey标签]:通过select查询来生成主键
		[keyProperty]:指定存放生成主键的属性
		[resultType]:生成主键所对应的Java类型
		[order]:指定该查询主键SQL语句的执行顺序,相对于insert语句
		[last_insert_id]:MySQL的函数,要配合insert语句一起使用
-->
<insert id="insertUser" parameterType="User">
	<selectKey keyProperty="id" resultType="int" order="AFTER">
		SELECT LAST_INSERT_ID()
	</selectKey>
	INSERT INTO USER(...) VALUES (#{...})
</insert>

主键返回之MySQL函数UUID UUID()

<!-- 
	[uuid]:生成的主键是35位的字符串,所以要修改id的类型为字符类型
		1、此时order采用BEFORE,因为需要先生成出主键,再执行insert语句
		2、显式的给ID赋值
-->
<insert id="insertUser" parameterType="User">
	<selectKey keyProperty="id" resultType="string" order="BEFORE">
		SELECT UUID()
	</selectKey>
	INSERT INTO USER(...) VALUES (#{...})
</insert>

主键返回之Oracle序列返回
SELECT user_seq.nextval() FROM dual

	<insert id="insertUser" parameterType="User">
	<selectKey keyProperty="id" resultType="int" order="BEFORE">
		SELECT user_seq.nextval() FROM dual
	</selectKey>
	INSERT INTO USER(...) VALUES (#{...})
</insert>

#{}和${}的区别

#{} 这种取值是编译好SQL语句再取值,相当于预处理中的占位符?
select * from student where student_name = #{name}
预编译后,会动态解析成一个参数标记符?:
select * from student where student_name = ?
#{}可以防止SQL注入。

${} 这种是取值以后再去编译SQL语句,相当于拼接SQL串,对传入的值不做任何解释的原样输出。
select * from student where student_name = ${}

在动态解析时候,会传入参数字符串
select * from student where student_name = lyrics
不加引号所以会出现sql注入风险
传入‘user’; delete user;
一般用于传入数据库对象,例如传入表名.
当接受简单类型的参数时, 只能是 v a l u e , {}只能是value, 只能是value{value}
select * from user where username like '%${value}%
select * from user where username like ‘%王%’

自定义别名

	<typeAliases>
<!-- 单个定义别名 -->
		<typeAlias type="cn.yaorange.mybatis.po.User" alias="user"/>
<!-- 批量定义别名(推荐) -->
<!-- [name]:指定批量定义别名的类包,别名为类名(首字母大小写都可)
		<package name="cn.yaorange.mybatis.po"/>
	</typeAliases>

resource/url/class

	使用相对于类路径的资源 resource
		如:<mapper resource="sqlmap/User.xml" />
	使用完全限定路径 url
		如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
	使用mapper接口的全限定名 class
		如:<mapper class="cn.yaorange.mybatis.mapper.UserMapper"/>

表字段与实体类名称不同时

	<resultMap type="最终映射的pojo对象" id="userResultMap">
	<id column="表字段名称" property="pojo对象属性名"/>
	<result column="..." property="..."/>
</resultMap>
	<select id="接口方法名" parameterType="参数类型" resultMap="上面定义的resultMap的id"  如果返回相同则是resultType=“实体的别名”

关系映射配置resultMap
one To one(Person-Card) association +javatype

	<resultMap type="domain.Person" id="OrdersUserRstMap">
		<id column="id" property="id" />
		<result column="user_id" property="userId" />
		<association property="card-Person对象的Card属性名称" javaType="domain.Card">
			<id column="user_id" property="id" />
		</association>
	</resultMap>

one To many(Student-Classes) collection +ofType

<resultMap type="domain.Classes" id="resultClasses">
		<collection property="stus" ofType="domain.Student">
			<id column="stu_id" property="id" />
			<result column="items_id" property="itemsId" />
		</collection>
	</resultMap>

Many To Many(Student-Course) collection+ofType

	<resultMap type="domain.Student" id="resultClass">
		<id ... />
		<result.../>
		<collection property="course" ofType="domain.Course">
			<id column="id" property="id" />
		</collection>
	</resultMap>

特殊标签比对

resultType:
作用:
将查询结果按照sql列名pojo属性名一致性映射到pojo中。
resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊的映射要求)。

association:
作用:
将关联查询信息映射到一个pojo对象中。
collection:
作用:
将关联查询信息映射到一个list集合中。

javatype:
和association一起使用,指定的是映射对象的类型(例如一对一中domain.Card),
oftype:
和collection一起使用,指定的是映射到list集合属性中pojo的类型(List 中的domain.Student)

延迟加载

在mybatis中使用association和collection有延迟加载
在做关联查询是会先加载主信息,做需要关联信息再加载关联信息
默认是不开启
怎么开启 lazyLoadingEnabled

		sqlMapperConfig.xml配置
<settings>
	<setting name="lazyLoadingEnabled" value="true"> 
</settings>
	使用association延迟加载
		<resultMap type="pojo.Orders" id="OrdersUserLazyLoadingRstMap">
	<id column="id" property="id" />
	<result column="user_id" property="userId" />
	<!-- select:指定延迟加载需要执行的statement的id(是根据user_id查询用户信息的statement)
		我们使用UserMapper.xml中的findUserById完成根据用户ID(user_id)查询用户信息
		如果findUserById不在本mapper中,前边需要加namespace-->
	<!-- column:主信息表中需要关联查询的列,此处是user_id -->
	<association property="user" select="mapper.UserMapper.findUserById" column="user_id"></association>
</resultMap>	

查询缓存

一级缓存是SqlSession级别的缓存。默认支持一级缓存
sqlSession对象中有一个数据结构(HashMap)用于存储缓存数据。
原理
第一次查询用户id为1的用户信息,sqlsession查询没有则取数据库查询,有则直接拿出
如果添加、修改、删除了用户信息则清空sqlsessino避免脏读

二级缓存是mapper级别的缓存,多个SqlSession可共用同一个Mapper的sql语句

在这里插入图片描述
原理
第一次调用mapper下的SQL去查询用户信息。查询到的信息会存到该mapper对应的二级缓存区域内。
第二次调用相同mapper相同的SQL去查询会去对应的二级缓存内取结果
如果调用相同mapper中的增删改SQL,并执行了commit操作。此时会清空该二级缓存。

hibernate

是一个持久层的orm对象关系映射框架,用面向对象的思想来操作数据库
rom 对象、关系(表数据),映射xml配置文件![在这里插入图片描述](https://img-blog.csdnimg.cn/cd9cbeb3e7f64ba393935308735eac21.png在这里插入图片描述

1、Configuration 接口:负责配置并启动 Hibernate
2、SessionFactory 接口:负责初始化 Hibernate
3、Session 接口:负责持久化对象的 CRUD 操作
4、Transaction 接口:负责事务
5、Query 接口和 Criteria 接口:负责执行各种数据库查询
Configuration 实例是一个启动期间的对象,一旦 SessionFactory 创建完成它就被丢弃了

怎么使用

1、配置数据源、方言等
2.new Configuration().configure(“hibernate.cfg.xml").buildSessionFactory().openSession()
增删改需要提交事务
session.beginTransaction()
session.commit()
session.close()
保存:session.save(对象)
删除 delete(obj)
修改对象 update(obj)
保存或者修改(如果没有数据,保存数据。如果有,修改数据)saveOrUpdate(obj)
通过id得到对象get(Class,id)
HQL 语句的查询的方式createQuery()
返回一行一列数据session.creatQuery().uniqueResult()
分页
query.setFirstResult(benginRow)
query.setMaxResults(pageSize)
query.list()

为什么使用

数据库操作简单,提升开发效率
缺点 表中关系复杂,表之间的关系很多不建议使用效率变慢

重点概念

持久化类 javabean+映射文件
类与表建立了映射关系就可以成为是持久化类
规则
1.必有构造函数()反射
2.唯一标识的主键
3.地址->对象 oid->记录
4.set,get(public)
5.基本数据的包装类(会有默认值)

主键

自然主键
主键本身是对象的一种属性,并且会用于业务当中。并非简单的标识作用,比如身份证
代理主键
不是对象本身的属性,是用来做标识而衍生出来的(常用)本身的存在与否不会影响到业务的执行
主键的生成策略
格式

<id name="id" column="id">
<generator class="....."/>
</id>

策略分类
自动生成:

  1. 适用于 char,varchar 类型的作为主键

    uuid 随机的字符串作为主键

  2. 适用于 short,int,long 作为主键

1.increment
Hibernate 中提供的一种自动增长机制.先进行查询 :select max(id) from user;
再进行插入 :获得最大值+1 作为新的记录的主键.并发访问不可使用
2.identity
有自动增长数据库中,数据库提供的自动增长机制,Orcale没有自动递增,故无法使用
3.sequence
序列的增长方式。Oracle 数据库底层没有自动增长,想自动增长需要使用序列来实现自增
4.native自适应,根据不同的数据库选择不同的生成策略
底层使用的 MySQL 数据库=identity。
底层使用 Oracle 数据库= sequence。
手动生成:
assigned 主键的生成不用 Hibernate 管理了,也不用数据库管理.必须手动设置主键

持久化对象的状态转换

瞬时状态:Transient Object 简称 TO
	没有持久化标识 OID(手动方式除外)
	 没有被纳入到 Session 对象的管理
持久化状态:Persistent Object 简称 P0
	自动同步数据库数据
	有持久化标识 OID
	已经被纳入到 Session 对象的管理(操作).
脱管状态:Detached Object 简称 DO
	有持久化标识 OID
	没有被纳入到 Session 对象的管理(已经被管理过,此时session已经关闭)
状态转换图:

在这里插入图片描述

hibernate缓存

一级缓存session
实现:map存放缓存数据,对象数组存放数据库拿出的对比数据
不同则更新
使用:

		存入 
			get
			load
			saveOrUpdate
			save
		取用
			get
			load
		清除
			clear-- 清空缓存
			close
			evict -- 从一级缓存中清除指定的实体对象。
		flush
			等待提交(立即执行sql,提交后数据库才改变)
	使用的原因
		可以提升查询效率

二级缓存sessionFactory
在这里插入图片描述

sessionFactory级别缓存,用于跨session共享数据。
	只对oid检索方式有效
			 
查询缓存
	基于二级缓存,将hql查询出来的数据存入二级缓存
	hibernate.cfg.xml
		use_query_cache
			<property name="cache.use_query_cache">true</property>
	session.createQuery().setCacheable(true).list()

事务

逻辑上的一组sql操作,要么全成功,要么全失败
特性
	原子性:最小单位,不能被分割
	一致性:前后数据要保持一致(A少了多少B就多了多少)
	隔离性:事务执行途中不受其他事无干扰
	持久性:从内存写到硬盘
	不考虑隔离性:
		读
			1脏读:没有提交的数据被其他事务读取
			2.不可重复读:读到已提交的UPDATE操作的事务,多次的读取结果不同
			3.虚读:读到已提交的INSERT操作的事务,多次的读取结果不同
			解决办法:设置隔离级别
				配置文件:
					hibernate.cfg.xml
						connection.isolation
							1—Read uncommitted isolation
							2—Read committed isolation
							4—Repeatable read isolation
							8—Serializable isolation
					例如:hibernate.connection.isolation = 4 
				1未提交读
				2读已提交:解决脏读
				4可重复读:解决脏读,不可重复读
				8串行化
					都可以解决
		写
			更新丢失
				两个事务同时对某一条记录做修改
				如果 A 事务修改完成后,提交了事务B 事务修改完成后,不管是提交还是回滚,如果不做处理,都会对数据产生影响
			解决办法:锁机制
				悲观锁:数据库锁机制,SQL 语句的后面for update
				只有当 A 事务提交后,锁释放了,其他事务才能操作该条记录
				乐观锁:hibernate锁机制   version
					entity
						private Integer version;
						get  set
					hbm.xml
						<version name="version"/>
				谁先提交谁成功
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值