MyBatis框架学习
MyBatis框架学习

MyBatis框架学习

MyBatis

框架及三层架构介绍

1.三层架构介绍

(1)三层架构介绍

  • 界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果(jsp ,html ,servlet)
  • 业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据
  • 数据访问层: 就是访问数据库, 执行对数据的查询,修改,删除等等

(2)三层架构对应框架

  • 界面层---servlet---springmvc(框架)
  • 业务逻辑层---service类--spring(框架)
  • 数据访问层---dao类--mybatis(框架)

2.框架介绍

框架是一个模块

  • 框架中定义好了一些功能。这些功能是可用的。
  • 可以加入项目中自己的功能, 这些功能可以利用框架中写好的功能

    框架特点:

  • 框架一般不是全能的, 不能做所有事情
  • 框架是针对某一个领域有效。 特长在某一个方面,比如mybatis做数据库操作强,但是他不能做其它的
  • 框架是一个软件

3.Mybatis框架

(1)简介:

早期叫做ibatis,mybatis是sql映射框架

(2)Mybatis功能:

1. 提供了创建Connection ,Statement, ResultSet的能力 ,不用开发人员创建这些对象了
2. 提供了执行sql语句的能力, 不用手动执行sql
3. 提供了循环sql, 把sql的结果转为java对象, List集合的能力
4. 提供了关闭资源的能力,不用手动关闭Connection, Statement, ResultSet
   - 开发人员做的是: 提供sql语句

(3)总结:
mybatis是一个sql映射框架,提供的数据库的操作能力。增强的JDBC

入门案例

  • 创建数据表

  • 引入maven依赖
<!--mybatis依赖-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.1</version>
</dependency>
<!--mysql驱动-->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.27</version>
</dependency>
  • 编写Dao接口
public interface StudentDao {
    /*查询全部学生信息*/
    List<Student> selectAllStudents();

    /*插入学生信息*/
    int insertStudent(Student student);
}
  • 编写Dao映射文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--指定约束条件,表示mybatis将会执行这些sql语句-->
<!--作用:限制,检查在当前文件中出现的标签,属性是否符合mybatis要求-->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!--mapper:当前文件根标签-->
<!--namespace:命名空间,使用dao接口的全限定名称-->
<!--在当前文件中,使用特定的标签,表示数据库的特定操作-->
<mapper namespace="com.dao.StudentDao">

    <!--id: sql语法的标识,mybatis使用id值找到对应sql语句,id使用对应的方法名称-->
    <!--查询: resultType: 表示结果类型,使用类的全限定名称-->
    <select id="selectAllStudents" resultType="com.bean.Student">
        /*直接写入sql语句*/
        select * from Student
    </select>

    <!--插入-->
    <insert id="insertStudent">
        insert into student values(#{id},#{name},#{email},#{age});
    </insert>

</mapper>
  • 创建主配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--mybatis主配置文件-->
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!--环境配置,数据库的连接信息
    default:必须与某个environment id相同,告诉mybatis使用哪个数据库连接信息(访问哪个数据库)-->
    <environments default="development">
        <!--一个数据库的配置(环境),id:表示环境的名称(自定义)-->
        <environment id="development">
            <!--mybatis事务类型, type:JDBC(表示使用JDBC中commit,rollback做事物处理)-->
            <transactionManager type="JDBC"/>
            <!--表示数据源,连接数据库  type:表示数据源的类型,POOLED:表示连接池-->
            <dataSource type="POOLED">
                <!--连接具体内容-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="502502"/>
            </dataSource>
        </environment>
    </environments>

    <!--sql mapper(sql映射文件) 位置-->
    <mappers>
        <!--指定文件位置-->
        <mapper resource="com/dao/StudentDao.xml"/>
    </mappers>
</configuration>

可选择是否添加日志

<!--添加日志-->
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
  • 创建测试

session.方法(Student.xml中mapper的 namespace.id)

openSession():无参默认非自动提交,提交需加入:session.commit()

openSession(true):自动提交

public class StudentTest {
    /*获取SqlSession对象*/
    private static SqlSession utils() throws IOException {
        /*读取mybatis.xml配置文件*/
        InputStream stream = Resources.getResourceAsStream("mybatis.xml");
        /*创建SqlSessionFactory对象,获取SqlSession*/
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        /*获取SqlSession对象*/
        SqlSession session = factory.openSession();
        return session;
    }

    /*查询操作*/
    @Test
    public void Test1() throws IOException {
        SqlSession session =StudentTest.utils();
        /*执行SqlSession的selectAllStudents方法*/
        List<Student> studentList = session.selectList("com.dao.StudentDao.selectAllStudents"); 
        for (Student student:studentList){
            System.out.println(student);
        }
        /*关闭SqlSession对象*/
        session.close();
    }

    /*插入操作*/
    @Test
    public void Test2() throws IOException {
        SqlSession session = StudentTest.utils();
        Student student = new Student(3, "qbl", "qbl@qq.com", 58);
        int insert = session.insert("com.dao.StudentDao.insertStudent",student);

        /*mybatis默认不提交事物,在insert,update,delete之后需要手动提交事物*/
        session.commit();
        session.close();
        System.out.println("插入的数据数为: "+insert);
    }
}
  • 补充:
<!--更改-->
<update id="updateStudent">
    update student set name=#{name},email=#{email},age=#{age} where id=#{id};
</update>

<!--删除-->
<delete id="deleteStudent">
    delete from student where id=#{id};
</delete>

MyBatis对象分析

1.模板的使用

  • 使用模板后,创建该类型文件即可自动生成模板中代码

2.对象分析

(1) Resources 类

Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返 回不同类型的 IO 流对象。

(2) SqlSessionFactoryBuilder 类

SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将 该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。

(3) SqlSessionFactory 接口

SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用 只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。

  • openSession(true):创建一个有自动提交功能的 SqlSession

  • openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交

  • openSession():同 openSession(false)

(4) SqlSession 接口

SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。

SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将 其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。

MyBatis动态代理DAO

1.DAO动态代理实现CRUD

MyBatis动态代理:可以去掉Dao接口实现类

(1)只需在接口中定义方法,并在MyBatisDao.xml配置文件中创建对应id的sql语句

public interface StudentDao {
    List<Student> selectAllStudents() throws IOException;
}
<mapper namespace="com.dao.StudentDao">
    <select id="selectAllStudents" resultType="com.bean.Student">
        select * from student;
    </select>
</mapper>

(2)在调用并执行sql语句时,只需调用sqlSession对象的getMapper()方法,即可获取指定接口的实现类对象。

(MyBatisUtils为获取sqlSession对象的工具类)

MyBatisUtils:

public static SqlSession createSqlSession() throws IOException {
    /*读取mybatis.xml配置文件*/
    InputStream stream = Resources.getResourceAsStream("mybatis.xml");
    /*创建SqlSessionFactory对象,获取SqlSession*/
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
    /*获取SqlSession对象*/
    SqlSession session = factory.openSession(true);
    return session;
}

测试:

@Test
public void Test1() throws IOException {
    SqlSession sqlSession = MyBatisUtils.createSqlSession(); //获取sqlSession对象
    StudentDao mapper = sqlSession.getMapper(StudentDao.class); //获取接口实现类对象
    List<Student> students = mapper.selectAllStudents(); //调用接口实现类中的方法
    for (Student student: students){
        System.out.println(student);
    }
}

2.定义接口传入参数

(1)一个简单参数

  • 在接口中定义需要传入参数的方法
Student selectStudentById(int id);

Student selectStudentByName(String name);
  • 在xml配置文件中:(参数的数据类型可写可不写)
<!--parameterType: 传入参数的数据类型的全类名,可加可不加-->
<select id="selectStudentById" resultType="com.bean.Student" parameterType="java.lang.Integer">
    select * from student where id=#{id};
</select>

<select id="selectStudentByName" resultType="com.bean.Student">
    select * from student where name=#{name};
</select>

(2)多个简单参数@Param

  • 在DAO接口中

@Param("studentId") int id : 表示给id属性起别名,在DAO.xml文件中,#{student}所填入的值

List<Student> selectStudentByIdAndName(@Param("studentId") int id, @Param("studentName") String name);
  • 在DAO.XML文件中
<select id="selectStudentByIdAndName" resultType="com.bean.Student">
    select * from student where id=#{studentId} or name=#{studentName};
</select>
  • 测试
@Test
public void Test2() throws IOException {
    SqlSession sqlSession = MyBatisUtils.createSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    List<Student> students = studentDao.selectStudentByIdAndName(1, "lbw");
}

(3)使用对象传参

  • 创建传参类和属性,并生成构造方法
public class ParamType {
    public String paramName; //表示姓名
    public Integer paramId;  //表示id
}
  • 在Dao接口中创建方法,参数为ParamType对象
List<Student> selectStudentByParam(ParamType paramType);
  • 在Dao.xml配置文件文件中写入当前方法的sql语句
<select id="selectStudentByParam" resultType="com.bean.Student">
    select * from mybatis.student where name=#{paramName} or id=#{paramId};
</select>

(4)通过位置传参

  • 在Dao中创建方法
List<Student> selectStudentByContext(String name,int id);
  • 在Dao.xml写入sql语句
<select id="selectStudentByContext" resultType="com.bean.Student">
    select * from mybatis.student where name=#{arg0} or id=#{arg1};
</select>

(4)通过Map集合传参

  • 在Dao中创建方法
List<Student> selectStudentByMap(Map<String,Object> map);
  • 在Dao.xml写入sql语句
<select id="selectStudentByMap" resultType="com.bean.Student">
    select * from mybatis.student where name=#{studentName} or id=#{studentId};
</select>
  • 测试,传入Map集合
@Test
public void Test8() throws IOException {
    SqlSession sqlSession = MyBatisUtils.createSqlSession();
    StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
    HashMap<String, Object> map = new HashMap<>();
    map.put("studentName","cxk");
    map.put("studentId",4);
    List<Student> students = studentDao.selectStudentByMap(map);
    for (Student student:students){
        System.out.println(student);
    }
}

3.#和$

  • #:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法
  • $ :字符串替换,告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的 内容连接起来。主要用在替换表名,列名,不同列排序等操作

4.ResultType

(1)简介

执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集 合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。

(2)别名

在MyBatis.xml主文件中,定义别名。在dao.xml配置文件中可使用定义的别名

  • 方式一:type为类型的全路径,alias为别名
<typeAliases>
        <typeAlias type="com.bean.Student" alias="Student"/>
        <typeAlias type="com.param.ParamType" alias="ParamType"/>
</typeAliases>

使用:

<select id="selectStudentByIdAndName" resultType="Student">
    select * from mybatis.student where id=#{studentId} or name=#{studentName};
</select>
  • 方式二:name为包名,包下的所有类别名就为类名
<typeAliases>
    <package name="com.bean"/>
</typeAliases>

使用:

<select id="selectStudentByIdAndName" resultType="Student">
    select * from mybatis.student where id=#{studentId} or name=#{studentName};
</select>

5.ResultMap

(1)简介

结果映射:指定列明和java对象的属性对应关系

resultMap 可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。 常用在列名和 java 对象属性名不一样的情况。

(2)运用

  • 在dao中创建方法
List<Student> selectAllStudents();
  • 在dao.xml配置文件中定义

(1)定义resultMap:指定查询出来的每个字段的值赋给哪个属性

(2)在select标签中运用resultMap属性,选择需要调用的resultMap标签(id值)

<!--定义resultMap
表示将指定字段的值赋给指定属性
id:自定义名称
type:定义类型的全限定名称
-->
<resultMap id="studentMap" type="com.bean.Student">
    <!--主键列,使用id标签 column:列名,property:类的属性名-->
    <id column="id" property="id"/>
    <!--非主键列,使用result标签,-->
    <result column="name" property="name"/> <!-- 表的name字段—>类的name属性 -->
    <result column="email" property="email"/>
    <result column="age" property="age"/>
</resultMap>
<!--定义sql语句 resultMap:指定定义好的resultMap-->
<select id="selectAllStudents" resultMap="studentMap">
    select * from mybatis.student;
</select>

注意:resultType和resultMap二者选其一


6.模糊查询

模糊查询

  • 方式一:

传入模糊查询where条件的完整格式

dao:

List<Student> selectStudentLike(@Param("name") String name);

dao.xml:

<select id="selectStudentLike" resultType="com.bean.Student">
    select * from mybatis.student where name like #{name};
</select>

测试:

List<Student> students = mapper.selectStudentLike("%b%");
  • 方式二:

在dao.xml的where条件已经书写好模糊查询格式,只需传入具体内容

dao:

List<Student> selectStudentLike2(@Param("name") String name);

dao.xml:

<select id="selectStudentLike2" resultType="com.bean.Student">
    select * from mybatis.student where name like "%" #{name} "%";
</select>

测试:

List<Student> students = mapper.selectStudentLike2("b");

动态sql

  • 动态 SQL,通过 MyBatis 提供的各种标签对条件作出判断以实现动态拼接 SQL 语句。
  • 常用的动态sql标签有if,where,foreach,choose等

1.if标签

将满足if条件的语句加入到sql语句中

    <select id="selectStudentIf" resultType="com.bean.Student">
        select * from mybatis.student where
<if test="name!=null">
    name=#{name}
</if>
<if test="id>0">
    or id=#{id}
</if>
    </select>

注:若前一个条件不满足,后一个条件or会导致sql语法错误

2.Where标签

能更好的避免标签中语法错误问题

<select id="selectStudentWhere" resultType="com.bean.Student">
        select * from mybatis.student
<where>
    <if test="name!=null">
        name=#{name}
    </if>
    <if test="id!=null">
        or id=#{id}
    </if>
</where>
    </select>

3.foreach标签

处理sql语句中传入多个值得问题

  • 方式一

直接传入sql语句中所需的字符

List<Student> selectStudentForEach(List<Integer> list);

collection:遍历的集合或数组类型(list,array)

item:遍历的成员

open:开始字符

close:结束字符

separator:分隔符

select id="selectStudentForEach" resultType="com.bean.Student">
        select * from mybatis.student where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
    #{id}
</foreach>
    </select>
  • 方式二

传入对象

List<Student> selectStudentForEach2(List<Student> studentList);
<select id="selectStudentForEach2" resultType="com.bean.Student">
        select * from mybatis.student where id in
<foreach collection="list" item="student" open="(" close=")" separator=",">
    #{student.id}
</foreach>
    </select>

4.动态代码片段

  • 可定义一段sql语句,在需要重复使用此sql语句的地方导入(复用sql语句)
<!--sql语句截取片段-->
<sql id="sql">
    select * from mybatis.student where
</sql>
<!--引入片段-->
<select id="selectSomeStudent" resultType="com.bean.Student">
    <include refid="sql"/>
    id>#{id}
</select>

MyBatis配置文件

1.主配置文件

主配置文件 之前项目中使用的 mybatis.xml 是主配置文件。

主配置文件特点:

  1. xml 文件,需要在头部使用约束文件
<?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">

2.根元素

<configuration>

3.主要包含内容:

  • 定义别名

  • 数据源

  • mapper 文件

2.dataSource标签

Mybatis 中访问数据库,可以连接池技术,但它采用的是自己的连接池技术。在 Mybatis 的 mybatis.xml 配置文件中,通过

<dataSource type=”pooled”>

来实现 Mybatis 中连接池的配置。

dataSource 类型:

  • UNPOOLED 不使用连接池的数据源
  • POOLED 使用连接池的数据源
  • JNDI 使用 JNDI 实现的数据源

3.指定properties资源文件

  • 在同resources目录下创建jdbc.properties资源文件
mybatis.url=jdbc:mysql://localhost:3306/mybatis
mybatis.username=root
mybatis.password=502502
mybatis.driverClassName=com.mysql.cj.jdbc.Driver
  • 在主配置文件中指定并使用资源文件
<properties resource="jdbc.properties"/>
<!--指定后,dataSource的property标签中的value属性值修改为${...}-->
<environments default="development">   
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <!--连接具体内容,value中都修改为properties指定的key-->
            <property name="driver" value="${mybatis.driverClassName}"/>
            <property name="url" value="${mybatis.url}"/>
            <property name="username" value="${mybatis.username}"/>
            <property name="password" value="${mybatis.password}"/>
        </dataSource>
    </environment>
</environments>

4.指定多个mapper文件

  • 方式一:

写多行mapper resource

<mappers>
    <mapper resource="com/dao/MyBatisDao.xml"/>
    <mapper resource="com/dao/MyBatisDao2.xml"/>
</mappers>
  • 方式二:

写多个mapper文件所在的包路径

<mappers>
    <package name="com.dao"/>
</mappers>

发表回复

您的电子邮箱地址不会被公开。