自学之框架---Mybatis

MyBatis

三层架构

1、界面层(controller包 servlet)

2、业务逻辑层(service包):接收表示传递过来的数据,检查数据,计算业务逻辑,计算业务逻辑,调用数据访问层获取数据。

3、数据访问层(dao包)

三层对应的处理框架:

界面层——servlet——springmvc(框架)

业务逻辑层——service类——spring(框架)

数据访问层——dao类——mybatis(框架)

MyBatis框架概述

基于java的持久层框架。早期叫做ibatis,代码在github。

mybatis是sql映射框架:

1)sql mapper:sql映射

可以把数据库表中的一行数据,映射为一个java对象。一行数据可以看作是一个java对象。操作这个对象,就相当于操作表中的数据。

2)数据访问,对数据库进行增删改查

mybatis提供了哪些功能:

1、提供了框架Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了

2、提供了执行sql语句的能力,不用你执行sql

3、提供了循环sql,把sql的结果转化为java对象,List集合的能力

4、提供了关闭资源的能力,不用你关闭Connection,Statement,ResultSet

开发人员提供sql语句

最后是:开发人员提供sql语句–mybatis处理sql–开发人员得到List集合或java对象(表中的数据)

基本步骤

1、加入依赖

<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>5.1.9</version>
    </dependency>

2、创建Dao接口

//接口操作Student表
public interface StudentDao {
    //查询Student表的所有数据
    public List<Student> selectStudents();
}

3、创建mapper文件,也叫做sql映射文件:写sql语句的,和接口中方法对应的sql语句

<?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:必须有值,自定义的唯一字符串
 推荐使用:dao 接口的全限定名称
--> <mapper namespace="org.example.domain.Student">
    <!--
    <select>: 查询数据, 标签中必须是 select 语句
    id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
    使用名称表示要执行的 sql 语句
    resultType: 表示结果类型的,是sql语句执行后得到的ResultSet,遍历这个ResultSet得到java对象的类型
    值写的类型的全限定名称
    -->
    <select id="selectStudents" resultType="org.example.domain.Student">
        <!--要执行的 sql 语句-->
        select id,name,email,age from student order by id
    </select>
</mapper>
<!--
sql映射文件:写sql语句的,mybatis会执行这些sql
1、指定约束文件
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的。

2、约束文件的作用:  限制,检查在当前文件中出现的标签,属性必须符合mybatis要求
3、mapper 是当前文件的根标签,必须的。
  namespace:叫做命名空间,唯一值的,可以是自定义的字符串
             要求你使用dao接口的全限定名称
4、在当前文件中,可以使用特定的标签,表示数据库的特定操作。
<select>:表示执行查询
<update>:表示更新数据库的操作,就是在<update>标签中  写的是update sql语句
<insert>:表示插入,放的是insert语句
<delete>:表示删除,执行的delete语句
-->

4、创建mybatis的主配置文件

1)连接数据库

2)指定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>
    <!--环境配置:数据库的连接信息
    default:必须和某个environment的id值一样。
    告诉mybatis使用哪个数据库的连接信息。也就是访问哪个数据库
    -->
    <environments default="mysql">
        <!--id:数据源的名称-->
        <environment id="mysql">
            <!--
            transactionManager:mybatis事务类型
                type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理)
            -->
            <transactionManager type="JDBC"/>
            <!--数据源 dataSource:创建数据库 Connection 对象
            type: POOLED 使用数据库的连接池
            -->
            <dataSource type="POOLED">
                <!--连接数据库的四个要素-->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!--一个mapper标签指定一个文件的位置
        从类路径开始的路径信息  target/classes(类路径)
        -->
        <mapper resource="org/example/dao/StudentDao.xml"/>
    </mappers>
</configuration>
<!--
mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置
1、约束文件
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
mybatis-3-config.dtd约束文件的名称
2、configuration 根标签
-->

5、使用mybatis的对象SqlSession,通过他的方法执行sql语句

public class MyApp {
    public static void main(String[] args) throws IOException {
        //访问mybatis读取student数据
        //1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes)
        String config = "mybatis.xml";
        //2.读取这个config表示的文件
        InputStream in = Resources.getResourceAsStream(config);
        //3.创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //4.创建SqlSessionFactoryBuilder对象
        SqlSessionFactory factory = builder.build(in);
        //5.获取SqlSession对象,从sqlSessionFactory中获取sqlSession
        SqlSession sqlSession = factory.openSession();
        //6.指定要执行sql语句的标识。sql映射文件中的namespace+"."+标签id值
        String sqlId = "org.example.domain.Student"+"."+"selectStudents";
        //7.执行sql语句,通过sqlId找到语句
        List<Student> studentList = sqlSession.selectList(sqlId);
        //8.输出结果
        //studentList.forEach(stu-> System.out.println(stu));
        for (Student stu:studentList) {
            System.out.println("查新的学生="+stu);
        }
        //9.关闭sqlSession对象
        sqlSession.close();
    }
}

输出日志

<!--settings:控制mybatis全局行为-->
    <settings>
        <!--设置mybatis输出日志-->
        <setting name="logImpl" value="STDOUT_LOGGING" />
    </settings>

主要类的介绍

//1)Resources:mybatis中的一个类,负责读取主配置文件  
InputStream in = Resources.getResourceAsStream(mybatis.xml);

//2) SqlSessionFactoryBuilder:创建SqlSessionFactory对象
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactory factory = builder.build(in);

/*3)SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多。在整个项目中,有一个就够用了。
    SqlSessionFactory接口,接口实现类:DefaultSqlSessionFactory
    SqlSessionFactor的作用:获取SqlSession对象。SqlSession sqlSession = factory.openSession();
    方法说明:
    1、openSession():无参数的,获取是非自动提交事务的SqlSession对象
    2、openSession(boolean):openSession(true) 获取自动提交事务的SqlSession
                            openSession(false) 非自动提交的SqlSession对象
*/

//4)SqlSession:
    //Sqlsession接口:定义了操作数据库的方法 例如: selectOne()  selectList()  insert()   update()  delete() commit()  rollback()
    //SqlSession接口的实现类  DefaultSqlSession
    //使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession()对象,在执行完sql语句后,需要关闭它,执行SqlSession.close().这样能保证他的使用是线程安全的。

动态代理

package org.example;

import org.apache.ibatis.session.SqlSession;
import org.example.dao.StudentDao;
import org.example.domain.Student;
import org.example.uitls.MyBatisUtils;
import org.junit.Test;

import java.util.List;

public class TestMybatis {

    @Test
    public void testSelectStudents(){
        /**
         * 使用mybatis的动态代理机制,使用SqlSession.getMapper(dao接口)
         * getMapper能获取dao接口对应的实现类对象
         */
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        //调用dao的方法执行数据库的操作
        List<Student> students = dao.selectStudents();
        for (Student stu:students){
            System.out.println("学生="+stu);
        }
    }
    @Test
    public void testInsertStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student = new Student();
        student.setId(1007);
        student.setName("盾山");
        student.setEmail("dunshan@qq.com");
        int nums = dao.insertStudent(student);
        sqlSession.commit();
        System.out.println("添加的对象的数量:"+nums);
    }
}

1.动态代理:使用SqlSession.getMapper(dao接口.class)获取这个dao接口的对象

2.传入参数:从java代码中把数据传入到mapper文件的sql语句中

​ 1)ParameterType:写在mapper文件中的一个属性。表示dao接口中方法的参数的数据类型。

​ 例如:StudentDao接口

​ public Student selectStudentById(Integer id);

​ 2)一个简单类型的参数:
​ 简单类型:mybatis把java的基本数据类型和String都叫简单类型

​ 在mapper文件获取简单类型的一个参数的值,使用#{任意字符}

​ 接口:public Student selectStudentById(Integer id);

​ mapper:select id, name, email, age from studentwhere id = #{studentId}

传参

1)多个参数,使用@Param命名参数

​ 接口:pubilc List selectMulitParam(@Param(“myname”)String name,@Param(“myage”)Ingter age)

​ 使用@Param(“参数名”) String name

​ mapper文件:

​ select

​ select * from student where name=#{myname} or age=#{myage}

​ /select

2)多个参数,使用对象,使用位置,使用Map

    <select id="selectMultiObject" resultType="org.example.domain.Student">
        select id,name,email,age from student where name = #{paramName} or age=#{paramAge}
    </select>
    <!--多个参数使用对象-->
    <select id="selectMultiStudent" resultType="org.example.domain.Student">
        select id,name,email,age from student where name = #{name} or age=#{age}
    </select>
    <!--多个参数使用位置-->
    <select id="selectMultiPosition" resultType="org.example.domain.Student">
        select id,name,email,age from student where name = #{arg0} or age=#{arg1}
    </select>
    <!--多个参数使用Map,使用语法#{map的key}-->
    <select id="selectMultiByMap" resultType="org.example.domain.Student">
        select id,name,email,age from student where name = #{myname} or age=#{age}
    </select>
    @Test
    public void testSelectMultiObject(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        QueryParam param = new QueryParam();
        param.setParamName("张三");
        param.setParamAge(28);

        List<Student> students = dao.selectMultiObject(param);

        for (Student stu:students){
            System.out.println("学生="+stu);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectMultiStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        Student student = new Student();
        student.setName("张三");
        student.setAge(28);

        List<Student> students = dao.selectMultiStudent(student);

        for (Student stu:students){
            System.out.println("学生="+stu);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectMultiPosition(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);



        List<Student> students = dao.selectMultiPosition("李四",20);

        for (Student stu:students){
            System.out.println("学生="+stu);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectMultiByMap(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);

        Map<String,Object> data = new HashMap<>();
        data.put("myname","张三");
        data.put("age",28);



        List<Student> students = dao.selectMultiByMap(data);

        for (Student stu:students){
            System.out.println("学生="+stu);
        }
        sqlSession.close();
    }

$和#

#:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。这样做更安全,更迅速,通常也是首选做法。

** ∗ ∗ ∗ ∗ 字 符 串 替 换 , ∗ ∗ 告 诉 m y b a t i s 使 用 ** **字符串替换,**告诉 mybatis 使用 mybatis使包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${}的

内容连接起来。主要用在替换表名,列名,不同列排序等操作。

: 可 以 替 换 表 明 或 者 列 名 , 你 能 确 定 数 据 是 安 全 的 。 可 以 使 用 :可以替换表明或者列名,你能确定数据是安全的。可以使用 :使

$和#的区别:

1、#使用?在sql语句中做占位的,使用PreparedStatement执行sql,效率高

2、#能够避免sql注入,更安全

3、$不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低

4、$有sql注入的风险,缺乏安全性

5、$:可以替换表明或者列名

封装Mybatis输出结果

resultType

resultType: 执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集

合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。

mybatis的输出结果:

mybatis执行了sql语句,得到java对象

1)resultType结果类型,指sql语句执行完毕后,数据转为的java对象,java类型是任意的

​ resultType结果类型的它值 1.类型的全限定名称 2.类型的别名,例如java.lang.Ingter别名是int

​ 处理方式:

​ 1.mybatis执行sql语句,然后mybatis调用类的无参数构造方法,创建对象

​ 2.mybatis把ResultSet指定的列指附给同名的属性。

<select id="selectMultiPosition" resultType="org.example.domain.Student">
    select id,name,email,age from student 
</select>

对等的jdbc

ResultSet rs = executeQuery("select id,name,email,age from student")
    while(rs.next()){
        Student student = new Student;
        student.setId(rs.getInt("id"));
        student.setName(rs.getString("name"));
    }

2)定义自定义类型的别名

​ 1)在mybatis主配置文件中定义,使定义别名

​ 2)可以在resultType中使用自定义别名

    <!--定义别名-->
    <typeAliases>
    <!--
        第一种方式:
        可以指定一个类型一个自定义别名
        type:自定义类型的全限定名称
        alias:别名(短小,容易记忆的)
    -->
    <!--<typeAlias type="org.example.domain.Student" alias="stu"/>-->
    <!--<typeAlias type="org.example.vo.ViewStudent" alias="vstu"/>-->

        <!--
        第二种方式:
        <package> name是报名,这个包中的所有类,类名就是别名(类名不区分大小写)
    -->
        <package name="org.example.domain"/>
        <package name="org.example.vo"/>
    </typeAliases>

​ 3)resultMap:结果映射,指定列名和java对象的属性对应关系。

​ 1)你自定义的列值赋值给哪个属性

​ 2)当你的列名和属性名不一样时,一定使用resultMap

​ resultMap和resultType不要一起用,二选一

模糊查询

    <!--第一种like,java代码指定like的内容-->
    <select id="selectLikeOne" resultType="org.example.domain.Student">
        select id,name,email from student where name like #{name}
    </select>

    <!--第二种方式:在mapper文件中拼接like的内容-->
    <select id="selectLikeTwo" resultType="org.example.domain.Student">
        select id,name,email from student where name like "%" #{name} "%"
    </select>

动态SQL

动态sql:sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化

动态sql的实现,使用的是mybatis提供的标签,,,

1)是判断条件的,

​ 语法

​ 部分sql语句

2)用来包含 多个的,当多个if有一个成立的,会自动增加一个where关键字,并去掉if中多余的and,or等。

3)循环java中的数组,list集合的。主要用在sql的in语句中

学生id是 1001,1002,1003的三个学生

select * from student where id in(1001,1002,1003)

collection:表示接口中方法参数的类型,如果是数组使用array,如果是list集合使用list

item:自定义的,表示数组和集合成员的变量

open:循环开始时的字符

close:循环结束时的字符

separator:集合成员之间的分隔符

    <!--if
    <if test="使用参数java对象的属性值作为判断条件,语法 属性=xxx值"></if>

    -->
    <select id="selectStudentIf" resultType="org.example.domain.Student">
        select id,name,age,email from student
        where 1=1
        <if test="name !=null and name !='' ">
            name = #{name}
        </if>
        <if test="age > 0">
            and age> #{age}
        </if>
    </select>

    <!--
    where:<where><if><if>...</where>
    -->
    <select id="selectStudentWhere" resultType="org.example.domain.Student">
        select id,name,email,age from student
        <where>
            <if test="name !=null and name !='' ">
                name = #{name}
            </if>
            <if test="age > 0">
                or age= #{age}
            </if>
        </where>
    </select>

    <!--foreach使用1,List<Integer>-->
    <select id="selectForeachOne" resultType="org.example.domain.Student">
        select * from student where id in
        <foreach collection="list" item="myid" open="(" close=")" separator=",">
            #{myid}
        </foreach>
    </select>

    <!--foreach使用2,List<Integer>-->
    <select id="selectForeachTwo" resultType="org.example.domain.Student">
        select * from student where id in
        <foreach collection="list" item="stu" open="(" close=")" separator=",">
            #{stu.id}
        </foreach>
    </select>

4)sql代码片段,就是复用一些语法

步骤:

1.先定义 sql语句,表明,字段等

2.再使用,

Mybatis配置文件

1.数据库的属性配置文件:把数据库连接信息放到一个单独的文件中。和mybatis主配置文件分开。

目的是便于修改,保存,处理多个数据库的信息。

​ 1)在resources目录中定义一个属性配置文件,xxx.properties,例如jdbc.properties

​ 在属性配置文件中,定义数据,格式是key=value

​ key:一般使用 . 做多级目录的

​ 例如 jdbc.mysql.driver

​ 2)在mybatis的主配置文件,使用指定文件的位置

​ 在需要使用值的地方${key}

2.mapper文件,使用package指定路径

    <mappers>
        <!--第一种方式:指定多个mapper文件-->
<!--        <mapper resource="org/example/dao/StudentDao.xml"/>-->
<!--        <mapper resource="org/example/dao/OrderDao.xml"/>-->
        <!--第二种方式:使用包名
            name:xml文件(mapper文件) 所在的包名,这个包中的所有xml文件一次都能加载给mybatis
            使用package的要求:
            1.mapper文件名称需要和接口名称一样,区分大小写的一样
            2.mapper文件和dao接口需要在同一目录
        -->
        <package name="org.example.dao"/>
    </mappers>

扩展

PageHelper做数据分页

复习

什么是动态代理:

mybatis帮你创建dao接口的实现类,在实现类中调用SqlSession的方法执行sql语句

使用动态代理的方式:

1、获取SqlSession对象,SqlSessionFactory.openSession()

2、使用getMapper方法获取某个接口的对象,sqlSession.getMapper(接口.class)

3、使用dao接口的方法,调用方法就执行了mapper文件中的sql语句

使用动态代理方式的要求:

1、dao接口和mapper文件放在一起,同一个目录

2、dao接口和mapper文件名称一致

3、mapper文件中的namespace的值是dao接口的全限定名称

4、mapper文件中的,,,等的id是接口中方法的名称

5、dao接口中不要使用重载方法,不要使用同名的,不同参数的方法

理解参数:

从java代码中把实际的值传入到mapper中

1、一个简单类型的参数:#{任意字符}

2、多个简单类型的参数@Param(“自定义名称”)

3、使用一个java对象,对象的属性值作为mapper文件找到参数,#{java对象的属性名称}

4、使用参数的位置,语法#{arg0},#{arg1},mybatis3.4之前的版本,使用#{0},#{1}

5、使用Map作为参数,#{map的key}

#和$的区别:

1、#是占位符,表示列值的,放在等号右侧

2、$占位符,表示字符串的连接,把sql语句连接成一个字符串

3、#占位符使用的jdbc指定PreparedStatement对象执行SQL语句,效率高,没有sql注入的风险

4、$使用的是Statement对象执行sql,效率低,有sql注入的风险

mybatis返回结果:

resultType——表示sql语句的执行结果,转为的java对象的类型:

1.类型的全限定名称

2.别名:

在mybatis主配置文件定义别名:

①使用

②使用:类名就是别名

resultMap——自定义列名和java对象的属性名对应关系

列名和属性名不一样解决方式:

1.使用列名

2.使用resultMap

like:

1.在java代码中指定like的内容

2.在mapper中拼接like

动态sql:

1.根据条件,能够得到不同的sql语句,使用mybatis的标签,例如if,where,foreach等

2.if:判断条件的,条件为true,就会把if之间的sql加入到主sql之后

3.where:标签里面是多个if,如果有一个if判断为true,会在sql的后面加入where关键字,会去掉无用的and,or等字符

4.foreach:循环数组,list集合

5.sql代码片段:复用部分sql语句的

mybatis主配置文件:

1.mybatis属性配置文件的使用

2.在mybatis文件的位置

PageHelper:

1.功能:实现多种数据库的分页,mysql就是代替limit语句的

2.使用步骤

1)加入maven依赖

2)在mybatis主配置文件加入plugin

3)在你的查询方法之前,加入PageHelper方法调用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值