当你看到这里的时候我想我不必再次强调这是一个框架了;
那咱们就来简单的说一下这个Mybatis框架:
首先呢,先提一下前文ORM,为什么要提它,看官您接着往下看:
ORM概述
在使用JDBC 的时候,我们通常将数据直接返回,但现在也会将数据封装到实体类对象中,由对象携带数据。这样操作的时候,可以通过操作对象的方式操作数据。但是手写这类代码通常是繁琐的、重复的,如果有自动完成这些功能的程序就好了。
ORM
(Object-Relational-Mapping):是对象关系映射的意思,它是一种思想,是指将数据库中的每一行数据用对象的形式表现出来。可以将 ORM 简单理解为上面我们提出的,可以自动将对象与数据进行映射的技术。
常见ORM框架
Hibernate 完全ORM映射框架
优点
简化了整个jdbc操作过程
对于开发者来说不需要关心sql了,只需要去操作对象就可以了,hibernate可以帮我们自动生成所需要的sql
代码移植性比较好,通过hibernate操作db都是通过操作对象来进行的,而hibernate会根据我们的操作和db的类型生成符合各种db要求的sql,如果我们需要切换db的类型,hibernate会自动适应,对于开发者业务代码来说不需要做任何业务代码上的调整
开发效率比较高
即使开发人员不知道sql,也能使用Hibernate来完成数据的CRUD的操作
缺点
sql优化比较艰难,各种操作最终发给db的sql是由hibernate自动生成的,对于开发者来说如果想干预最终需要执行的sql,相对来说比较困难
hibernate入门比较容易,但是想成为高手学习成本比较高
对于复杂的动态sql,代码中也需要写很多判断进行组装,动态sql这块的支持比较欠缺
如果做一些简单的系统,开发周期也比较紧急,对sql的优化要求也不是很高,可以使用hibernate。
JdbcTemplate
jdbctemplate是在spring框架的基础上开发的一个jdbc框架,所以对spring是有依赖的,它对jdbc做了封装,隐藏了各种重复的操作,使用时只需传入:需要执行的sql、参数以及对于结果如何解析的程序就可以了,使用起来还是很方便的,但是面对与动态sql,它也是无能为力了。整体上来说,jdbctemplate相对于纯jdbc隐藏了很多重复性的操作,对于sql的写法和结果的组装上完全交给了开发者自己去控制,在系统中使用也可以帮助我们节约很多时间,而且学习相当简单.
mybatis 是一个半自动的orm框架
MyBatis
MyBatis简介
MyBatis是一个半自动化的orm框架,为什么说是半自动化的呢,因为他需要我们自己去写sql,而他做的更好的地方就是动态sql
的支持上面,而上面说的各种技术,面对与动态sql只能自己写很多判断去组装sql,而这些判断和组装在mybatis中实现起来就非常简单了,完全由mybatis去帮我们实现了。mybatis将sql交由开发者去控制,所以在sql的优化方面,开发者可以随心所欲,也就是说mybatis将重复性的工作优化到了极致:操作db的过程、动态sql的拼装、结果和对象的映射
,这些mybatis都帮我们实现的很好,而让我们将更多的经历花在sql的写法和优化上面,所以毫无疑问mybatis使用人数和公司也是最多的。
MyBatis 优缺点
-
优点
- 简单易学,容易上手(相比于 Hibernate ) : 基于SQL编程 - 消除了JDBC大量冗余的代码,不需要手动开关连接 - 很好的与各种数据库兼容(因为 MyBatis 使用JDBC来连接数据库,所以只要JDBC 支持的数据库 MyBatis 都支持,而JDB提 供了可扩展性,所以只要这个数据库有针对Java的jar包就可以就可以与 MyBatis 兼容),开发人员不需要考虑数据库的差异性。 - 提供了很多第三方插件(分页插件 / 逆向工程) - 能够与Spring很好的集成 - 如果‘使用映射文件’的话,可以让代码和配置文件完全分离。只要方法的定义没有改变,那么只需要修改配置文件就可以达到修改的目的。
-
缺点
- SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。 - SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
Mybatis的工作原理
两者相比较:
通过刚才咱们的介绍,可以简单的看出各自的优劣,那我就简单的说一下两者的主要区别还是在于SQL语句,一个需要写SQL语句一个不需要写SQL语句;
对于Hibernate 的完全封装而言,不可以对SQL语句进行修改,这从而会导致我们无法对于SQL进行优化,所以Mybatis解决了这一现象,也导致Mybatis比Hibernate 常用。
我们之前在没学矿建,对于数据库的连接都是在使用JDBC,那Mybatis相较于JDBC有那些优化改进或者是优点呢?
Mybatis与传统JDBC的比较(简单说一些让大家看看,有个简单的认识):
减少了60%的代码量
最简单的持久化框架
架构级性能增强
SQL代码从程序代码中彻底分离,可重用
增强了项目中的分工
增强了移植性
Mybatis的工作原理图
首先呢,通过这个图,咱们可以大致的简单了解一下Mybatis的整体工作流程:
它是有一个核心的配置文件(也叫全局配置文件),通过new 一个SqlSessionFactory工厂读取配置文件,获取SqlSession进行增删改查操作,它是通过executor底层执行器,最终是对数据库DB的操作;
光说不练假把式,接下来我就给各位看官快速的写一个流程操作,看清楚了,是快速哦!
首先是配置文件,咱们是最终对数据库的操作,肯定是要连接数据库的,不然还操作干嘛呀,这不就是白干了吗,对吧?
所以咱们得在核心配置文件mybatis.xml中配置连接数据库的操作
<configuration>
<properties resource="jdbc.properties"></properties>
<environments default="jsp">
<environment id="jsp">
<!-- 使用jdbc的事务,mybatis进行管理 -->
<transactionManager type="JDBC"/>
<!-- 使用jdbc的连接池连接数据库 -->
<!-- 如果配置了<properties resource="db.properties"/> -->
<!-- value可以使用value="mybatis"的形式进行书写 /> -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件的配置-->
<mappers>
<package name="mapper"/>
</mappers>
</configuration>
environments这个标签是代表咱们可能在开发中遇到很多数据库,比如:测试、运行等等时要用到的数据库;
default代表是默认连接的数据库,它一定要与你所要使用的id相同,大家可以看到我取的名字是jsp,但不一定非得是这个名字,随便取,但前提是你得记住且不要连错了;
mappers是咱们的映射配置,后面再说
我这里是引用了我自己写的一个jdbc的配置文件jdbc.properties,大家也可以直接把properties这个标签去掉,下面的value写上对应的值。
刚才说到配置核心文件下面就是SqlSessionFactory工厂,这是我自己写的一个类,读取咱们刚刚配置的配置文件,一会我们可以通过调用这个类的方法直接调用这个工厂方法
public class MyBatisUtil {
private MyBatisUtil() {
}
private static SqlSessionFactory sqlSessionFactory;
static {
try {
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(Resources.getResourceAsStream("mybatis.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSessionFactory getSqlSessionFactory() {
return sqlSessionFactory;
}
}
有人可能会问:为什么要单独写一个类呢,直接写不行吗?
我的回答是:当然可以,但是你有没有想过,咱们每一次都要写吗?这样是不是会造成代码的冗余呢?咱们程序员本身就是要减少一些不必要的操作,所以这次写一个类,到时候想用下次直接调用即可!
前面我也说了,简单快速的写一下,主要是让大家知道mybatis的执行流程,所以后续的我会通过注解和单元测试来快速进行,如果大家还不理解注解和单元测试的话,可以自行了解,过程中我也会简述一下!
因为咱们要将数据库中的数据打印出来,所以我们也要创建相应的实体类
下面就是我创建的一个实体类
import lombok.Data;
@Data
public class User {
private int uid;
private String username;
private String password;
private String phone;
}
大家看到了,我没有写构造方法,但是我们获取数据是需要有构造方法的,这是因为我引入了注解的功能,可以看到public上方有一个@Data,这就是注解的功能之一,我们不必自行构造方法,像set、get、toString他都帮我们创建了,大家导包一定要看清楚我导的包,引入的是lombok;
然后我们获取,肯定不是我们直接从数据库中粗暴的获取、拿来的吧,我们得通过一些方法,委婉一点,温柔一点,所以我们可以通过接口,接口中我们自己书写的方法来获取
首先我们先来进行查询操作,这是咱们在接口中书写的方法
//查询指定id的数据
@Select ("select * from user where uid=#{uid}")
User selectAll(int uid);
这同样也是通过注解的方式,这样我们可以很清晰直白明了的看到SQL语句,而不是去mapper.xml中书写,然后在来回跳转,这样显得十分麻烦和繁琐
在这之前呢,咱们先把工具都准备好,因为已经做好了工厂,下一步就是获取sqlsession,再进行curd操作,那怎样获取呢,请看
SqlSessionFactory sqlSessionFactory ;
@Before
public void start(){
sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
}
创建一个类,不必写main函数,刚才说到单独创建一个类用来获取工厂,所以现在直接可以用MyBatisUtil点方法来获取工厂。@Before表示无论运行那个代码他都会被运行,而且是指其之前运行
@Test
public void selectAll(){
//构建SqlSession对象
try (SqlSession session = sqlSessionFactory.openSession(true)) {
//执行sql
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectAll(1);
System.out.println(user);
}
}
@Test指的就是单元测试,可以单独运行,不必靠main方法
查询的结果如下:
DEBUG [main] - ==> Preparing: select * from user where uid=?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
User(uid=1, username=zhangsan, password=123456, phone=138468885889)
这里就可以看到咱们的SQL语句以及传入的参数1,然后进行查询;
咱们看一下数据表:
就是咱们所要查询的uid为1的数据
一通则百通,接下来就是增加、修改和删除,咱们就一块来看一下吧!
首先是他们接口中书写的方法以及他们的SQL语句:
//增加数据
@Insert("insert into user values (#{uid},#{username},#{password},#{phone})")
void insertStudent(User user);
//修改数据
@Update("update user set username=#{username},password=#{password},phone=#{phone} where uid=#{uid}")
void updateStudent(User user);
//删除指定id的数据
@Delete("delete from user where uid=#{uid}")
void deleteStudent(int uid);
他们的结果分别是:
增加:
DEBUG [main] - ==> Preparing: insert into user values (?,?,?,?)
DEBUG [main] - ==> Parameters: 3(Integer), lili(String), 15453(String), 123456(String)
DEBUG [main] - <== Updates: 1
其中的#{}转变为了占位符,update是影响条数,咱们就增加了一条,所以也就为1;
看一下表是否有变化呢
修改:
DEBUG [main] - ==> Preparing: update user set username=?,password=?,phone=? where uid=?
DEBUG [main] - ==> Parameters: wing(String), 123456(String), 152003026548(String), 3(Integer)
DEBUG [main] - <== Updates: 1
修改条数也是为1;
同样看一下表
删除:
DEBUG [main] - ==> Preparing: delete from user where uid=?
DEBUG [main] - ==> Parameters: 3(Integer)
DEBUG [main] - <== Updates: 1
同样如此,证明咱们并没有报错
写的过于繁多,可能会导致观感,所以就先说这么多,让大家对于mybatis有个简单的认识,后续会继续改进,共勉!