Mybatis 学习笔记
框架:
框架(Framework)它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题
使用框架的好处,框架封装了很多细节,使开发者可以使用极简的方式实现功能大大提高开发效率,
简而言之,框架就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统。简单地说
就是使用别人搭好的舞台,你来作表演,而且,框架一般是成熟的,不断升级的软件。
三层架构:
表现层:
用于展示数据
业务逻辑层:
处理业务需求
持久层:
与数据库交互
CRUD是指在做计算处理时的增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)
几个单词的首字母简写。crud主要被用在描述软件系统中数据库或者持久层的基本操作功能
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
ORM(Object Relational Mappging 对象关系映射)思想实现结果集的封装
MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,
将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录
https://github.com/mybatis/mybatis-3
https://github.com/mybatis/mybatis-3/releases/tag/mybatis-3.5.6
maven仓库 里面导入
org.mybatis mybatis 3.4.6我们把Mybatis的功能架构分为三层:
(1)API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。
接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
(2)数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。
它主要的目的是根据调用的请求完成一次数据库操作。
(3)基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,
这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
为什么需要Mybatis?
帮助程序员将数据存入到数据库中
方便
传统的JDBC代码太复杂,简化。框架。自动化
不用也行。更容易上手 技术没有高低之分。
步骤!!!## 标题
新建Maven项目 把src文件删除 (little tips)在pom.xml资源文件下导入依赖
依赖: mysql驱动 mybatis junit
<dependencies>
<!--mysql驱动-->
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--junit-->
<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
新建一个模块
在resource文件下编写mybatis核心配置文件
<environments default="development">
<environment id="development">
<!--连接数据库-->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
编写工具类(加载资源 创建一个能执行SQL的对象)
在com xxx utils下
package com.xxx.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;
//工具类
// SqlSessionFactory—>SqlSession
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//使用Mybatis获取 SqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
// 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
// SqlSession 提供了在数据库执行 SQL 命令所需的
// 所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();//获取SqlSesssion实例
}
}
DAO 模式
DAO (DataAccessobjects 数据存取对象)是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。
通俗来讲,就是将数据库操作都封装起来。
编写代码
实体类 com .xxx.pojo.User
Dao接口 com.xxx.dao.UserDao ( 等价于Mapper)
public interface UserDao {
List getUserList();
}
接口实现类 com.xxx.dao.UserMapper.xml (现在的接口实现类是一个xml配置文件)
<?xml version="1.0" encoding="UTF-8" ?>
select *from mybatis.user1
测试:junit
找到test 下的java(绿色)包新建com.xxx.dao.UserDaoTest(标准化 一 一对应)
public class UserDaoTest {
@Test
public void Test(){
//获得 SqlSession对象
SqlSession sqlSession= MyBatisUtils.getSqlSession();
// 执行SQL
UserDao userDao= sqlSession.getMapper(UserDao.class);
List userList=userDao.getUserList();
for(User user:userList){
System.out.println(user);
}
//关闭 SqlSession
sqlSession.close();
}
}
所以的maven项目先配置:
pom.xml中加上:
src/main/java
/*.properties
/.xml
false
src/main/resources
**/.properties
**/*.xml
false
UserMapper.xml中namespqce中的包名要和dao/UserMapper接口的包名一致
select
选择查询语句
id 对应的namespace 接口中的方法名
resulttype sql语句执行的返回值
parametertype 参数类型
搭好框架后:
编写接口 UserMapper (相当于以前的UserDao)
//增加用户
int addUser(User user);
编写UserMapper.xml中的sql语句
<!-- //增加用户-->
<insert id="addUser" parameterType="com.kuang.pojo.User" >
insert into mybatis.user1(id,name,pwd) values (#{id},#{name},#{pwd});
</insert>
测试
@Test
public void addUser(){
SqlSession sqlSession=MyBatisUtils.getSqlSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.addUser(new User(6,"哈哈6","123456"));
//提交事务!!!!!!!!!!相当于更新
sqlSession.commit();
sqlSession.close();
}
********标签不要匹配错
********resource 绑定mapper,需要使用路径 也就是com/xxx/dao 这种形式 以 / 隔开的
********程序配置文件(核心配置文件)必须符合规范
万能Map
实体类或数据表中的字段、参数过多,考虑用Map(key,value)(野路子)
Map传递参数,直接在sql中取出Key即可
对象传递参数,直接在sql中取出对象的属性即可
多个参数用Map,或者注解!!!
===========================================
模糊查询!!!:
java代码执行的时候,传递通配符%
select from mybatis.user where name like ‘%xxx%’;
mysql> select from user1 where name like ‘%张%’;
±—±-------±-------+
| id | name | pwd |
±—±-------±-------+
| 1 | 张三 | 123456 |
±—±-------±-------+
1 row in set (0.00 sec)
在sql拼接中使用通配符!!!(防止sql注入)
select *from mybatis.user where name like ”%“#{value}”%“;
核心配置文件
mybatis-config.xml
MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。
配置文档的顶层结构如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
!!!刷新一下maven目录 不然会报错(软件鸡肋)!!!
Mybatis默认事务管理器: JDBC 连接池: POOLED
属性:
通过properties属性来实现引用配置文件
这些属性可以在外部进行配置,并可以进行动态替换。
你既可以在典型的 Java 属性文件中配置这些属性,
也可以在 properties 元素的子元素中设置
编写数据库配置文件
db.properties
driver=com.mysql.cj.jdbc.Driver
//没有分号!!!
url=jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8
username=root
password=123456
在核心配置文件中引入
properties 要放在最上面
properties >setting>typeAliases
优先使用外部配置文件
类型别名(typeAliases)
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写
1:
select *from mybatis.user1;
2:
建议用user小写
select *from mybatis.user1;
实体类少 用第一种
多 用第二种
第一张可以自定义别名 第二种不行:如果要改 要在实体类增加注解 @Alias(“hello”)
其他配置
mybatis-plus等等
映射器
mappers
方式一:
方式二:
方式三:使用扫描包 于方式二注意点一样
public class User {
private int id;
private String name;
private String password;
±—±-------±-------+
| id | name | pwd |
±—±-------±-------+
| 1 | 张三 | 123456 |
±—±-------±-------+
解决字段不符的问题(password 与 pwd不符)
F:\Java\jdk1.8.0_152\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 “-javaagent:E:\learing softwares\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar=60883:E:\learing softwares\IntelliJ IDEA 2019.3.3\bin” -Dfile.encoding=UTF-8 -classpath “E:\learing softwares\IntelliJ IDEA 2019.3.3\lib\idea_rt.jar;E:\learing softwares\IntelliJ IDEA 2019.3.3\plugins\junit\lib\junit5-rt.jar;E:\learing softwares\IntelliJ IDEA 2019.3.3\plugins\junit\lib\junit-rt.jar;F:\Java\jdk1.8.0_152\jre\lib\charsets.jar;F:\Java\jdk1.8.0_152\jre\lib\deploy.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\access-bridge-64.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\cldrdata.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\dnsns.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\jaccess.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\jfxrt.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\localedata.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\nashorn.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\sunec.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\sunjce_provider.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\sunmscapi.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\sunpkcs11.jar;F:\Java\jdk1.8.0_152\jre\lib\ext\zipfs.jar;F:\Java\jdk1.8.0_152\jre\lib\javaws.jar;F:\Java\jdk1.8.0_152\jre\lib\jce.jar;F:\Java\jdk1.8.0_152\jre\lib\jfr.jar;F:\Java\jdk1.8.0_152\jre\lib\jfxswt.jar;F:\Java\jdk1.8.0_152\jre\lib\jsse.jar;F:\Java\jdk1.8.0_152\jre\lib\management-agent.jar;F:\Java\jdk1.8.0_152\jre\lib\plugin.jar;F:\Java\jdk1.8.0_152\jre\lib\resources.jar;F:\Java\jdk1.8.0_152\jre\lib\rt.jar;D:\IDEA project\Mbatis-Study\mybatis-04\target\test-classes;D:\IDEA project\Mbatis-Study\mybatis-04\target\classes;C:\Users\LY.m2\repository\mysql\mysql-connector-java\6.0.6\mysql-connector-java-6.0.6.jar;C:\Users\LY.m2\repository\org\mybatis\mybatis\3.4.6\mybatis-3.4.6.jar;C:\Users\LY.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\LY.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar” com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 com.kuang.dao.UserDaoTest
User{id=1, name=‘张三’, password=‘null’}
进程已结束,退出代码 0
解决:
1、类型处理器 简单
select id,name,pwd as password from mybatis.user1 where id = #{id};
(as起别名)
2、resultMap 结果集映射
select *from mybatis.user1 where id=#{id};
</select>
日志:
键:logImpl 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
值:SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGIN
配置日志:
select *from mybatis.user1 limit #{startIndex},#{pageSize}
public interface UserMapper {
// 注解 自动在接口上实现
@Select(“select* from user1”)
List getUsers();
}
!!!需要在配置文件中绑定接口!!!
!–绑定接口–>
本质:反射机制实现
底层:动态代理!
工具类里面
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession(true);(true 为自动提交事务 不需要在设置 commit())
}
取注解的值
@Delete(“delete from user1 where id=${uid}”)
int Delete(@Param(“uid”) int id);
@Param注解:
基本类型的参数或者String类型,需要加上
引用类型不需要加
如果只有一个基本类型可以忽略 但是建议加上
我们在SQL中引用的就是这里的@param()中设定的属性名
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,
攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,
在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询
,从而进一步得到相应的数据信息
mybatis 使用xml 或注解 来配置原生接口 和pojo
Project Lombok
Project Lombok is a java library that automatically plugs into
your editor and build tools, spicing up your java.
Never write another getter or equals method again,
with one annotation your class has a fully featured builder,
Automate your logging variables, and much more.
lombok: (插件)
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@Data 方法全部出来!!
偷懒插件
步骤:
IDEA中安装插件
项目中 pom.xml中导入jar包
org.projectlombok
lombok
1.18.10
在实体类注解即可
//有参构造
@AllArgsConstructor
//无参构造
@NoArgsConstructor
//getter setter toString ...........
@Data
!!!!!!!!!!!!但是最好不要使用!!!!!!!!!!!!
外键约束
create table student(id int(10) not null primary key,name varchar(30) default null,tid int(10) default null,key fktid (tid),constraint fktid foreign key(tid) references teacher(id)) ENGINE=InnoDB AUTO_INCREMENT=288 DEFAULT CHARSET=utf8;
拼接代码 不要加分号!!!!!!!!!!!!!!!! select *from mybatis.blog where 1=1;
这就叫动态sql
select *from mybatis.blog where
and title = #{title}
and author = #{author}
//智能的把and去掉 智能拼接 防止出错
select *from mybatis.blog
title = #{title}
and author = #{author}
</select>
where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为
“AND” 或 “OR”,where 元素也会将它们去除。
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select *from mybatis.blog
<where>
<choose>
<when test="title!=null">
title=#{title}
</when>
<when test="author!=null">
and autho=#{autho}
</when>
<otherwise>
and views=#{views}
</otherwise>
</choose>
</where>
</select>
!!!相当于 switch case
sql片段:】
<sql id="if-title-author" >
<if test="title != null">
title = #{title}
</if>
<if test="author != null">
and author = #{author}
</if>
</sql>
<select id="queryBlogIf" parameterType="map" resultType="blog">
select *from mybatis.blog
<where>
<include refid="if-title-author"></include>
</where>
</select>
需要时 直接引用
动态 SQL
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,
你应该能理解根据不同条件拼接 SQL 语句有多痛苦,例如拼接时要确保不能忘记添加必要的空格,
还要注意去掉列表最后一个列名的逗号。利用动态 SQL,可以彻底摆脱这种痛苦。
先保证sql正确 再去拼接!!!