1、MyBatis出现的历史背景
1、之前与数据库交互得得做到:编写sql -> 预编译 -> 设置参数 -> 执行sql -> 封装结果,功能简单,sql语句编写子java代码里面,这种硬编码,高耦合的方式,不推荐所以就出来一个框架Hibernate
2、Hibernate:全自动全映射的ORM(Object Relation Mapping)对象关系映射框架:旨在消除sql,从javaBean映射到DbRecoreds中间加上jdbc编写预编译等黑箱操作的中间过程,开发人员即使不懂sql也能够进行开发 缺点: ①因为sql是黑箱操作sql语句已经编写好了,这不好优化,除非用HQL定制sql ②全映射,javaBean有100个字段,数据库就会有100列与之对应,如果只要一个字段,是没办法的,一查就是100个字段全部映射了所以就出来了ibatis
3、MyBatis半自动的,将核心业务交了出来,MyBatis3之前的版本2…现在都叫做ibatis,原来时apche下的项目转给google了,转的时候正值ibatis3.0的发布所以改名了就叫MyBatis,我们所说的MyBatis就是ibatis3.0之后的版本希望sql语句交给开发人员编写,不失去灵活性,所以mybatis就出来了,他把编写sql这个命脉从黑箱中提取出来了
2、使用框架
用户发起请求-> 界面层controller -> 业务逻辑层service()-> 包含service的实现类 -> 持久层dao层数据库的mapper操作层-> 数据库mysql 优点 ①结构清晰,耦合度低,各层分工明确 ②可维护性高,可扩展性高 ③有利于标准化,实现技术的整合 ④开发人员可以只关注整个结构中的其中某一层的功能实现 ⑤有利于各层逻辑的复用,提高开发效率,降低难度 每一层对应着一个框架 界面层:Spring MVC:接受用户的请求,调用service,显示请求的处理结果,包含jsp、html、servlet等对象,对应controller 业务层:Spring:处理业务逻辑,使用算法处理数据的,把数据返回给界面层,对应的是service包以及实现类 持久层:MyBatis:访问数据库,或者读取文件,访问网络,获取数据,对应的包是dao。
3、MyBatis入门
mapper的配置文件,项目中一个表对应一个mapper,主配置mapper设置数据库连接信息以及可以读取到哪些mapper ①主配置mapper
<?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>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<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://localhost:3306/mybatis?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/byue/dao/StudentDao.xml"/>
</mappers>
</configuration>
②每个表也就是dao层对应的mapper 照理说因该先写一个接口,通过接口映射到xml文件执行sql,但是他的原理是通过SqlSessionFactor实现的,所以这个接口不要都行
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.byue.dao.StudentDao">
<insert id="insertStudent" parameterType="com.byue.domain.Student">
insert into student values (#{id},#{name},#{email},#{age})
</insert>
<select id="selectStudentById" resultType="com.byue.domain.Student">
select id from student where id =#{studentId}
</select>
</mapper>
③测试函数入口
public class MyTest {
@Test
public void testSelctStudentById() throws IOException {
String config="mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
String sqlId="com.byue.dao.StudentDao"+"."+"selectStudentById";
Student student = session.selectOne(sqlId,2);
System.out.println("使用mybatis来查询一个学生"+student);
session.commit();
session.close();
}
@Test
public void insertStudent() throws IOException {
String config="mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(config);
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
String sqlId="com.byue.dao.StudentDao"+"."+"insertStudent";
Student s1 = new Student();
s1.setAge(34);
s1.setId(7);
s1.setName("王五");
int rows = session.insert(sqlId,s1);
System.out.println("使用mubatis来新增一个学生影响的行数为"+rows);
session.close();
}
遇到的2个错误,第一个编译文件找不到,在maven中的pom配置文件中加上一个配置,让他可以将项目中的文件编译进去,第二个classNotFound,我明明以及引入了maven中的mysql,并且classpath已经设置好了,还是不想,最后通过给该项目引入mysql的jar包才解决的
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
已经配好了环境变量但是还是没有用
将对应执行的sql已经他的生命周期打印在控制台中的设置如下
4、MyBatis的重要对象
①Resource:mybatis框架中的对象信息,就一个作用,读取主配置信息 InputStream inputStream = Resources.getResourceAsStream(config); ②SqlSessionFactoryBuilder:负责创建SqlSessionFactory对象 SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream); ③SqlSessionFactory:重量级对象,创建此对象需要更多的资源和时间,创建此对象,费时又费力(Connection),保证重量级对象有一个就可以了,创建比较费劲。 SqlSessionFactory实际上是一个接口:作用是SqlSession的工厂,就是创建SqlSession对象,ctrl+h可以看到他们的继承关系,找到sqlSessionFactory的实现类 public class DefaultSqlSessionFactory implements SqlSessionFactory{} ④SqlSessionFactory接口中的方法 openSession():获得一个SqlSession的对象,默认是需要手工提交事务的 openSession(boolean):boolean参数表示是否自动提交事务,true创建一个自动提交事务的SqlSession,false:等同于没有参数的openSession ⑤SqlSession对象是通过SqlSwssionFactory获取的,SqlSession本身是一个接口,他的作用是提供了大量的执行sql语句的方法 public class DefaultSqlSession implements SqlSession {} selectOne:执行sql语句,最多得到一行记录,多余1行是错误的 selectList:执行sql语句返回多行语句 selectMap:执行sql语句,得到一个map结果 insert、update、delete、commit、rollback方法 注意SqlSession对象不是线程安全的,所以他的使用步骤如下 ①在方法的内部,执行sql语句之前,先获取sqlsession对象 ②调用sqlsession的方法,执行sql语句 ③关闭sqlsession对象,执行sqlsession.close()
5、MyBatis的dao代理
mybatis提供代理:mybatis创建dao接口的实现类对象,完成sql语句的执行。mybatis创建一个对象代替程序员手动写dao的实现类 要求 ①mapper文件中的namespace:必须是dao接口的全限定名称 ②mapper文件中标签的id是dao接口中的方法名称(一模一样才行) mybatis的实现方式 使用SqlSession对象的方法getMapper(dao.class) 例如:现在有个StudentDao接口
SqlSession session=MyBatisUtils.getSqlSession();
StudentDao dao = session.getMapper(StudentDao.class);
Student student = dao.selectById(1001);
StudentDao dao = session.getMapper(Student.class);
dao -> com.sun.proxy.$Proxy2 相当于之前手动写的StudentDaoImpl实现类
等同于
Student dao = new StudentDaoImpl();
|