目录
2.1什么是ORM?(Object Relational Mapper 对象关系映射)
第三步:测试是否连接到数据库(以下步骤是MyBatis的核心,掌握)
第五步.便写DAO层-SQL映射文件(mapper.xml)
2.5.2 模糊查询(模糊查询比较推荐第二种,第一种可能会出现SQL注入问题。 )
一,框架的概念,以及为什么使用框架?
1.框架的进程
SSH(最早)Struts(JSP MVC) 能够简化JSP开发 Spring Hibernate (全自动化ORM框架 , 并发量小,不用太过于关注SQL,自动生成sql语句)
|
SSH2 :Struts2
|
SSM :Spring SpringMVC Mybatis(半自动化ORM框架,需要用户自己写sql语句)
2.为什么使用框架:
3.框架的概念:
- 框架技术:
是一个应用程序的半成品
提供可从用的公共结构
按一定规则组织一组组件
4.使用框架的优势分析
- 重用代码大大增加,软件生产效率和质量也得到了提高;
- 代码结构的规范化,降低程序员之间沟通以及日后维护的成本;
- 知识的积累,可以让那些经验丰富的人员去设计框架和领域构件,而不必限于低层编程;
- 软件设计人员要专注于对领域的了解,使需求分析更充分;
- 允许采用快速原型技术;有利于在一个项目内多人协同工作;
- 大粒度的重用使得平均开发费用降低,开发速度加快,开发人员减少,维护费用降低,而参数化框架使得适应性、灵活性增强。
二,MyBatis框架 (半自动化ORM框架)
2.1什么是ORM?(Object Relational Mapper 对象关系映射)
了解ORM之前,先了解一下什么是持久化!
持久化:是程序数据在瞬时状态和持久状态间的转化的过程。
比如我们程序在新建一个对象后,这个对象存储在内存当中,当我们电脑关机后,这个对象数据便不会存在,我们称之为瞬时状态。当我们将这个对象存储到U盘,本地文件下,我们称之为持久状态,永久的存储在某种介质当中。这个过程称之为持久化。
ORM:比如下图内存中有个对象,通过JDBC将对象存储在数据库当中,这个过程称之为持久化。但是数据库中的表字段必须与内存中对象的字段逐个对应,否则存不进来。也就是对象里的字段和表里的字段一一映射,对象与表一一映射。这个状态称之为ORM
ORM:
- 编写程序时,以面向对象方式处理数据。
- 保存数据时,却以关系型数据库的方式存储。
ORM解决方案包含下面四个部分
- 在持久化对象上执行基本的增,删,改,查操作。
- 对持久化对象提供一种查询语言或者API
- 对象关系映射工具
- 提供与事务对象交互,执行检查,延迟加载以及其他优化功能
2.2MyBatis概念及优点特性
2.2.1MyBatis简介
2.2.2MyBatis特性
2.3MyBatis的环境搭建及核心API建立(不容易)
MyBatis中文网https://mybatis.net.cn/
第一步:下载MyBatis jar包并导入工程
第二步:编写MyBatis核心配置文件
第三步:测试是否连接到数据库(以下步骤是MyBatis的核心,掌握)
- 读取核心配置文件mybatis-config.xml
- 创建SqlSessionFactory对象,读取配置文件
- 创建SqlSession对象
- 调用mapper文件进行数据操作
第四步.创建实体类
@Data / @get / @set / @toString
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
编写domain类
第五步.便写DAO层-SQL映射文件(mapper.xml)
映射文件
加载映射文件
如果不添加映射文件,将会报如下错误
### Error querying database. Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.csi.smbms.domain.User.findByCount
### Cause: java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.csi.smbms.domain.User.findByCount
抽取工具类:
package com.csi.smbms.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisUtils {
private static SqlSessionFactory factory ;
//本地线程,归属于当前用户,为了避免线程共享问题,担心出现数据污染
private static ThreadLocal<SqlSession> tl = new ThreadLocal<>() ;
static {
InputStream is = null;
try {
is = Resources.getResourceAsStream("mybatis-config.xml");
} catch (IOException e) {
e.printStackTrace();
}
factory = new SqlSessionFactoryBuilder().build(is) ;
}
/**
* 创建SqlSession对象
*/
public static SqlSession getSqlSession(){
SqlSession sqlSession = tl.get() ;
if (sqlSession == null ){
System.out.println("创建了SqlSession对象");
sqlSession = factory.openSession();
tl.set(sqlSession) ;
}
return sqlSession ;
}
/**
* 资源关闭
*/
public static void close(){
SqlSession sqlSession = tl.get();
if (sqlSession!=null){
System.out.println("关闭了SqlSession对象");
sqlSession.close();
tl.set(null);
}
}
}
2.4理解核心类的作用域与生命周期
SqlSessionFactoryBuilder
- 用过即丢,其生命周期只存在于方法体内
- 可重用其来创建多个 SqlSessionFactory 实例
- 负责构建SqlSessionFactory,并提供多个build方法的重载
SqlSessionFactory (**最重要**)
- SqlSessionFactory是每个MyBatis应用的核心
- 作用:创建SqlSession实例
- 在创建SqlSession的同时,能够将事务设置为手动的或者是自动的
- autoCommit:
- true|false
- 作用域: Application
- 生命周期与应用的生命周期相同
- 单例
存在于整个应用运行时,并且同时只存在一个对象实例,所以在抽象工具类的时候,用到了ThreadLocal.
SqlSession
- 包含了执行SQL所需的所有方法
- 对应一次数据库会话,会话结束必须关闭
- 线程级别,不能共享
2.5 SELECT(查询)
2.5.1 基本查询
- List: SelectList 查询所有(namespace+id,参数内容)
- SelectOne:查询一个,SelectOne(namespace+id,参数内容) ;
2.5.2 模糊查询(模糊查询比较推荐第二种,第一种可能会出现SQL注入问题。 )
解决方案
- 使用字符串拼接形式 '%${变量名称}%'
- 使用concat方式 concat('%',#{变量名称},'%') (推荐)
$与#之间的区别(**) 面试题
#{} 是预编译处理, ${} 是字符串替换。Mybatis 在处理 #{} 时,会将 sql 中的 #{} 替换为 ? 号,调用 PreparedStatement 的 set 方法来赋值;Mybatis 在处理 ${} 时,就是把 ${} 替换成变量的值。使用 #{} 可以有效的防止 SQL 注入,提高系统安全性。
2.5.3 多个参数查询
解决方案
- 使用封装对象的形式传输内容(参数是同一个对象里的,将参数封装一个对象即可)
- 通过map来进行封装传值(不同对象)
User findByMap(Map<String,Object> map) ;
映射文件中的SQL语句和对象查一致
2.5.4 对象查询 VS map查询
2.6 增删改
CUD:都需要使用commit提交,否则就会发生回滚情况,除非是,在初始化SqlSession对象时修改事物的提交方式。
//例子
/**
* 删除
*/
@Test
public void testDeleteById(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
try {
int i = userMapper.deleteById(16L);
System.out.println(i);
sqlSession.commit();
} catch (Exception e) {
sqlSession.rollback();
e.printStackTrace();
} finally {
MyBatisUtils.close();
}
}
2.7 MyBatis 的分页查询
2.8 主键值回填 。
<!-- 添加用户获取主键值 [ 自增 ]--><insert id = "insertUsersGetKey" useGeneratedKeys = "true" keyProperty = "userid" >insert into users values(default,#{username},#{usersex})</insert>
<settings><setting name = "useGeneratedKeys" value = "true" /></settings><insertid = "insertUsersGetKey" keyProperty = "userid" >insert into users values(default,#{username},#{usersex})</insert>
void insertUsersGetKey ( Usersusers );usersMapper . insertUsersGetKey ( users );sqlSession . commit ();System . out . println ( users . getUserid ());
2.9 自动映射级别(autoMappingBehavior)
<settings><setting name="autoMappingBehavior" value="FULL"/></settings>
<resultMap id="userinfoList" type="userinfo"><!--代表主键property: 代表类中的字段column: 代表数据库查询回来字段--><id property="id" column="id" /><result property="userCode" column="userCode" /><result property="userName" column="userName" /><result property="gender" column="gender" /><result property="phone" column="phone" /><result property="address" column="address" /><result property="roleName" column="roleName" /><!--多对一,以及一对一--><association property="product" javaType="Product" select="com.csi.easybuy.mapper.ProductMapper.selectById2" column="pid" /<!--一对多--> <collection property="product" ofType="Product" select="com.csi.easybuy.mapper.ProductMapper.selectById2" column="pid" />
</resultMap><select id="list" resultMap="userinfoList">SELECTsu.*,roleName FROMsmbms_user su,smbms_role srWHEREsu.userRole = sr.id</select>
三:动态SQL
3.1 if
SELECT * FROM dept where 1 = 1< if test = "dname != null" >dname = # { dname },</ if >< if test = "loc != null" >and loc = # { loc }</ if >
3.2 trim(where,set)
SELECT * FROM dept< where >< if test = "dname != null" >dname = # { dname }</ if >< if test = "loc != null" >and loc = # { loc }</ if ></ where >
update dept< set >< if test = "dname != null" >dname = # { dname },</ if >< if test = "loc != null" >loc = # { loc },</ if ></ set >< where >deptno = # { deptNO }</ where >
update dept< trim prefix = "set" suffixOverrides = "," >< if test = "dname != null" >dname = # { dname },</ if >< if test = "loc != null" >loc = # { loc },</ if ></ trim >< where >deptno = # { deptNO }</ where >
3.3 choose (when, otherwise)
3.4 foreach
collection: 集合item: 集合中的选项值open :开合的标识close :关闭的表示separator :分隔符DELETE FROM emp< where >empno in< foreach collection = "list" item = "item" open = "(" close = ")" separator = "," ># { item }</ foreach ></ where >
四:Mybatis缓存(了解)
4.1 一级缓存
4.2 二级缓存
五: PageHelper分页插件(真分页)
- 添加依赖:
- 配置插件
- 分页查询API
- pageHelper使用方式: