一、Mybatis是什么?
- Mybatis是一种持久层框架
- Mybatis是一种ORM框架
- Mybatis是增强版的JDBC
在对上面的进行一个解释:
持久层的目的就是,完成对象数据和关系数据的转换
也就是哪个类对应哪个表,哪个属性对应哪个列。
JDBC 就是官方定义的一套操作数据库的规范(API)
MyBatis 是一个基于 Java 的持久层框架。MyBatis 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO),它消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。
MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。
MyBatis 是一个半自动映射的框架,因为 MyBatis 需要手动匹配 POJO、SQL 和映射关系。
二、Mybatis主配置文件:
<?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>
<environments default="development">
<!-- 配置数据源 -->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///pc"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件路径 -->
<mappers>
<mapper resource="org/example/dao/mapper.xml"/>
</mappers>
</configuration>
三、 Mybatis如何实现与数据库的数据交换
SqlSession是MyBatis的关键对象,似于JDBC中的Connection.它是应用程序与持久层之间执行交互操作的一个单线程对象,也是MyBatis执行持久化操作的关键对象。
因此,要实现Mybatis和数据库之间的数据操作,获取SqlSession对象
是必不可少的一部分。
对于SqlSession对象的获取:
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();//SqlSessionFactoryBuilder对象可直接new
InputStream inputstream=Resources.getResourceAsStream(String resource);//将映射文件转化为InputStream输出流,该方法会的调用过程中会抛出异常
SqlSessionFactory factory=builder.build(InputStream inputstream);//SqlSessionFactoryBuilder对象的build(InputStream)方法,调用InputStream输出流生成SqlSessionFactory
SqlSession session=factory.openSession();//SqlSessionFactory对象的openSession()方法,生成SqlSession对象。
考虑到SqlSession是一个单线程的,即每次会话都需要创建一个。而每一个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心.同时SqlSessionFactory也是线程安全的,SqlSessionFactory一旦被创建,应该在应用执行期间都存在.或者是从资源利用方面来说,SqlSession都不宜每次都创建。因此较好的一个方法是:创建一个工具类,在该类中建议使用单例模式.或静态代码块的方式来获取SqlSessio对象。.
工具类创建如下:
package org.example.config;
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 Utils {
public static SqlSessionFactory factory=null;
public static SqlSession getsession() throws IOException {
InputStream stream=Resources.getResourceAsStream("mybatis.xml");
if(factory == null)
{
factory=new SqlSessionFactoryBuilder().build(stream);
}
return factory.openSession();
}
}
获取到SqlSession对象后,以下两种方式均可对数据库数据进行操作(以插入一个元组举例):
四、现在以往数据库插入数据为例:
一、利用接口实现类:
1.在dao层里创建持久层接口( 映射器接口 ):
package org.example.dao;
import org.example.pojo.Student;
import java.io.IOException;
public interface StudentDao {
public void insertdao(Student st) ;
}
2.在dao层里的接口实现类中写相关的实现方法:
package org.example.dao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.example.config.Utils;
import org.example.pojo.Student;
import java.io.IOException;
public class StudentDaoImple implements StudentDao {
@Override
public void insertdao(Student st) {
SqlSession session= null;//将SqlSession对象声明为全局变量
try { //try{ }catch{ }解决异常
session = Utils.getsession();
} catch (IOException e) {
e.printStackTrace();
}
session.insert("insertdao",st);
session.commit(); //将更改结果保存到数据库中
}
3.映射器(即 mapper.xml )中添加SQL语句(即mapper.xml ):
MyBatis也支持使用注解来配置映射语句。当我们使用基于注解的映射器接口时,我们不再需要在XML配置文件中配置了。
<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="org.example.dao.Insertdao">
<insert id="insert" parameterType="org.example.pojo.Student" resultType="org.example.pojo.Student">
insert into student(name,sex) values(#{name},#{sex})
</insert>
</mapper>
这里的parameterType和resultType的值都是全限定类名,即包名加类名的格式(不定义别名的情况下)。
4.在测试类中测试:
@Test
public void inserttest(){
Student stu = new Student(10, "2225", "男");//构建带参的Student对象
StudentDaoImple in = new StudentDaoImple();//创建一个接口实现类对象
in.insertdao(stu); //调用接口的insertdao()方法
}
二、动态代理
- 在dao层里创建持久层接口:
package org.example.dao;
import org.example.pojo.Student;
import java.io.IOException;
public interface StudentDao {
public void insertdao(Student st) ;
}
2.映射文件中添加SQL语句(即mapper.xml):
<?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">
<!-- namespace:填写映射当前的Mapper接口,所有的增删改查的参数和返回值类型,
就可以直接填写缩写,不区分大小写,直接通过方法名去找类型-->
<mapper namespace="org.example.dao.Insertdao">
<insert id="insert" parameterType="org.example.pojo.Student">
insert into student(name,sex) values(#{name},#{sex})
</insert>
</mapper>
3.在测试类中测试:
@Test
public void inserttest() throws Exception {
Student stu = new Student(10, "2225", "男");
//StudentDaoImple in = new StudentDaoImple();
//in.insertdao(stu);
SqlSession session=Utils.getsession();
StudentDao in=session.getMapper(StudentDao.class);//将 mapper.xml 生成接口的实现类,通过调用接口对象就可以获取 mapper.xml 中编写的 sql.
in.insertdao(stu);
}
分析可以看出,使用动态代理,免去了业务逻辑层中接口实现类的一系列操作。但是,使用mapper的动态代理,需要有一下条件:
1.namespace 必须和 接口全限定路径 ( 包名 + 类名 ) 一致
2. id 值 必须和 接口中方法名 相同
3.如果接口中方法为多个参数,可以省略 parameterType
同时,由于SqlSession对象是由factory.openSession()获取得到,进行数据操作后为了将结果保存至数据库,还需要
session.commit()
完成对数据库更新。