MyBatis

Mybatis

第一章 框架的概述

1.三层架构

mvc: web开发中使用mvc模式。m:数据;v:视图;c:控制器

c控制器:接收请求,调用servlet对象,显示请求处理的结果,当前使用servlet作为控制器

v视图:目前使用jsp,html,css,js.显示请求的处理结果,把m中数据展示出来

m数据:来自数据库mysql,来自文件,来自网络。

mvc作用:

  1. 实现解耦合
  2. 让mvc各司其职
  3. 使得系统扩展更好

三层架构:

  1. 界面层(视图层):接收用户的请求,调用service,显示请求的处理结果的包含了jsp,servlet,html等对象
  2. 业务逻辑层:处理业务逻辑,使用算法处理数据的。将数据返回给界面层,对应的是service包和包中的很多XXService类,例如:StudentService,OrderService
  3. 持久层(数据库访问):访问数据库,或者读取文件,访问网络,获取对象,对应的包是dao包。dao包中很多的StudentDao,OrderDao,ShopDao等。

2.三层架构请求处理流程

用户发起请求—>界面层----->业务逻辑层----->持久层----->数据库

3.为什么使用三层架构?

  1. 结构清晰
  2. 可维护性高
  3. 有利于标准化
  4. 开发人员可以只关注整个结构的其中某一层的功能实现
  5. 有利于各层逻辑的复用

4.三层架构模式和框架

每一层对应一个框架

1)界面层—SpringMVC框架(3天)

2)业务层—Spring框架(4.5-5天)

3)持久层—MyBatis(2.5-3天)

5.框架

1) 什么是框架

框架:就是一个软件,完成了部分的功能。软件中的类和类之间的方法调用都已经规定好了。通过这些可以完成某些功能。框架可以看作是一个模板。

框架是可以升级的,改造的,框架是安全的

框架是对某一方面有用的,不是全能的。

6.框架解决的问题

  1. 框架能实现技术的整合

  2. 提升开发效率,降低难度

7.JDBC访问数据库优缺点

优点:

  1. 直观,易理解,易上手

缺点:

  1. 创建很多对象Connection,Statement,ResultSet
  2. 注册驱动
  3. 执行sql语句
  4. 把resultSet转为Student,List集合
  5. 关闭资源
  6. sql语句和业务逻辑混在一起

8.Mybatis框架

概述:

Mybatis是一个持久层框架,本是apache的一个开源项目 iBatis,2010年这个项目有apache software foundation 迁移到了google code,并且改名为MyBatis。2013年11月项目迁移到了GitHub。

Mybatis能够操作数据库,对数据库进行增删改查。可以看作高级的jdbc,解决jdbc的缺点

MyBtis能做什么

  1. 注册驱动
  2. 创建jdbc中使用的Connection,Statement,ResultSet
  3. 执行sql语句,得到ResultSet
  4. 处理ResultSet,把记录集中的数据转为java对象,同时能把java对象放入到List集合中
  5. 关闭资源
  6. 实现sql语句和java代码的解耦合

官网:https://mybatis.org/mybatis-3/zh/index.html

第二章 Mybatis入门

2.1第一个例子

实现步骤:

  1. 创建student表(id,name,email,age)

  2. 创建maven项目

  3. 修改pom.xml

    1) 加入mybatis依赖

    <!--mybatis依赖-->
        <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.1</version>
        </dependency>
    

    2) 再标签中加入资源插件

    <build>
        <resources>
          <resource>
            <directory>src/main/java/</directory>
            <includes>
              <include>**/*.xml</include>
              <include>**/*.properties</include>
            </includes>
            <filtering>false</filtering>
          </resource>
        </resources>
      </build>
    
  4. 创建实体类Student,定义属性,属性名和列名一致

  5. 创建Dao接口,定义操作数据库的方法

  6. 创建xml文件(mapper文件),写sql语句

    mybatis框架推荐按使用是把sql语句和java代码分开

    mapper文件:定义和dao接口再同一目录,一个表一个mapper文件

    <?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="org.mybatis.example.BlogMapper">
        <select id="selectBlog" resultType="Blog">
        select * from Blog where id = #{id}
      </select>
    <!--
    	1.约束文件:
    	 "http://mybatis.org/dtd/mybatis-3-mapper.dtd"
    	约束文件作用:定义和限制当前文件夹中使用的标签和属性,以及标签出现的顺序
    	2.mapper是跟标签
    		namespace:命名空间,必须有值,不能为空,唯一值;推荐使用Dao接口的全限定名称
    		作用:参与识别sql语句作用
    	3.再mapper文件中可以写<select><update><delete><select>等标签
    		<insert>里面是insert语句,表示执行的是insert操作
    		<update>里面是update语句,表示执行的是insert操作
    		<delete>里面是delete语句,表示执行的是insert操作
    		<select>里面是select语句,表示执行的是insert操作
    -->
    
    <!--
    <select>:表示查询操作,里面是select语句
    id:要执行的sql语句的唯一标识,是一个自定义字符串
    推荐使用dao接口中的方法名称
    resultType:告诉mybatis,执行sql语句,把数据值赋给哪个类型的java对象。
    resultType的值为现在使用的java对象的全限定名称
    -->
    <select id="selectStudentById" resultType="com.bjpowernode.domain.Student">
        select id, name, email,age from student where id=1001;  
    </select>
    
  7. 创建mybatis主配置文件

    1)定义创建连接实例的数据源(DataSource对象)

    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>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!--配置数据源,创建Connection对象-->
                <dataSource type="POOLED">
                    <!--driver:驱动内容-->
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <!--连接数据库配置-->
                    <property name="url" value="jdbc:mysql://localhost:3306/ssm?useUnicode=true&amp;characterEncoding=utf-8&amp;serverTimzone=GMT"/>
                    <property name="username" value="root"/>
                    <property name="password" value="root123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
              <!--
            使用mapper标签的resource属性指定mapper文件的路径。
            这个路径是从target/classes路径开始的
           
            使用注意:
            resource=“mapper文件的路径,使用 / 分割路径”
            一个mapper resource 指定一个mapper文件
            -->
            <mapper resource="org/mybatis/example/BlogMapper.xml"/>
        </mappers>
    </configuration>
    
  8. 创建测试的内容

    使用main方法,测试mybatis访问数据库

    也可以使用junit访问数据库

2.2 概念

1.自动提交:当你的SQL语句执行完毕后,提交事务。数据库更新操作直接保存数据

创建mapper文件模板

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n2hx1TNU-1633593739857)(C:\Users\linhuashang\AppData\Roaming\Typora\typora-user-images\image-20211006101857855.png)]

第三章 Mybatis的代理

3.1Dao代理

3.1.1 mybatis提供代理:

mybatis框架创建Dao接口的实现类对象,完成对sql语句的执行

换言之:mybatis创建一个对象代替你的dao实现类功能。

3.1.2 使用mybatis代理要求:

1.mapper文件中的sapcename必须是dao接口的全限定名称
2.mapper文件中标签的id是到接口中的方法名称(二者必须完全一致)

3.1.3 mybatis代理的实现方式

使用SqlSession对象的方法getMapper(dao.class)

例如:现有StudentDao接口

SqlSession sqlSession=MyUtil.getSqlSession();
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
Student student=studentDao.selectById(1001);

//上述代码中
StudentDao studentDao=sqlSession.getMapper(StudentDao.class);
//等同于
StudentDao studenrDao=new StudentDaoImpl();
//StudentDaoImpl:StudentDao接口的实现类


3.2 理解参数

理解参数是:通过java程序把数据传入到mapper文件中的sql语句。参数主要指的是dao接口方法的形参

3.2.1 parameterType

parameterType:表示参数类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用。

mybatis在给sql语句的参数赋值时使用。PreparedStatement.setXXX(位置,值)

<!-- 使用insert,update,delete,select标签写sql语句-->
<!--
parameterType:指定dao接口形参的类型
              这个属性的值可以使用java类的全限定名称或者 mybatis定义的别名
mybatis执行的sql语句:select id,name,email,age from student where id=?;
?是占位符,使用jdbc中的PreparedStatement执行这样的sql语句

PreparedStatement pst=coon.preparedStatement("select id,name,email,
age from student where id=?");
//给?赋值
参数是Integer:pst.setInt(1,1005);
参数是String:pst.setString(1,1005);

第一种用法:全限定名称:parameterType="java.lang.Integer"
第二种用法:使用别名:parameterType="int"

parameterType:mybatis可以通过反射机制自动获取dao接口方法的参数类型,可以不写
-->
    <select id="selectById" parameterType="java.lang.Integer" resultType="com.bipowernode.domain.Student" >
        select id,name,email,age from student where id=#{studentId};
    </select>

3.2.2 dao接口方法参数为简单数据类型

//dao接口的方法形参是一个简单类型
//简单类型:java基本数据类型和String
Student selectByEmail(String email);

mapper文件

<!--dao接口方法参数是一个简单类型    mapper文件获取这个参数值,使用#{任意字符}--><select id="selectByEmail" resultType="com.bipowernode.domain.Student">    select id ,name,email,age from student where email=#{email};</select>

3.2.3 dao接口方法有多个简单类型参数

@Param:命名参数。在方法形参前使用,定义参数名。这个名称可以用在mapper中

dao接口方法定义:

<!--当使用了@Param命名后,例如@Param("myName")在mapper文件中,使用#{命名的参数},例如#{myName}--><select id="selectByNameOrEmail" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where name=#{myName} or email=#{myEmail}</select>

mapper文件写法:

/*多个简单类型的参数使用@Param命名参数,注解是mybatis提供的位置:在形参定义的前面属性:value 自定义形参的参数名称 */List<Student> selectByNameOrEmail(@Param("myName") String name,@Param("myEmail") String email);

3.2.4 dao接口方法使用一个对象作为参数

方法的形参是一个Java对象,这个java对象表示多个参数,使用对象的属性值作为参数使用。

/**一个Java对象作为参数(对象有属性,有set get方法) */List<Student> selectByObject(Student student);

mapper文件:

<!--一个对象作为接口方法的参数,使用对象的属性作为参数值使用。简单的语法:#{属性名},mybatis使用此属性的getXXX()方法获取属性值--><select id="selectByObject" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where name=#{name}</select>

3.25 复杂的获取属性值语法:

#{property,javaType=java中数据类型名,jdbcType=数据类型名称(数据库中的类型)}

<select id="selectByNameOrEmail" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where name=#{myName,javaType=java.lang.String,jdbcType=VARCHAR}     or email=#{myEmail,javaType=java.lang.String,jdbcType=VARCHAR}     age=#{myEmail,javaType=java.lang.Integer,jdbcType=INTEGER}   </select>-->

3.2.6 Dao接口中多个简单类型参数,按位置传递参数(了解)

参数位置:dao接口中方法的形参列表,从左往右,参数位置是0,1,…

语法格式:#{arg0},#{arg1},#{arg2},#{arg3},(mybatis 3.4以后支持)依次代表参数1,参数2,…

不建议使用(代码可读性不好)

dao接口的方法

List<Student> selectByPosition(String name,Integer age);

mapper文件

<select id="selectByPosition" resultType="com.bjpowernode.domain.Student">select id,name,email,age from student where name=#{arg0},age=#{arg1}</select>

3.2.6 dao接口参数是map(了解)

/**使用map作为参数 */List<Student> selectStudentByMap(Map<String,Object> map);

mapper文件

<!--使用Map传递参数:在mapper文件中,获取map的值,是通过key获取的,语法#{key}--><select id="selectStudentByMap" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where name =#{myname} or age=#{myage};</select>

测试代码

@Testpublic void testSelectByMap(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    Student st=new Student(1001,"宋江","songjiang@qq.com",23);    Map<String,Object> data=new HashMap<>();    data.put("myname","宋江");    data.put("myage",20);    List<Student> list=dao.selectStudentByMap(data);    for(Student s:list){        System.out.println(s);    }    sqlSession.close();}

依然不建议使用

3.2.7 #和$区别

1. 语法:#{字符}

mybatis处理#{}使用jdbc对象是PreparedStatement对象

<select id="selectByObject" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where id=#{id}</select>mybatis创建出PreparedStatement对象,执行sql语句String sql="select id,name,email,age from student where id=?";PreparedStatement psy=conn.prepareStatement(sql);pst.setInt(1,1001);//传递参数ResultSet rs=pst.excuteQuery();//执行sql语句

#{}特点:

  1. 使用的PreparedStatement对象,执行SQL语句,效率高
  2. 使用的PreparedStatement对象,能避免sql注入,sql语句执行更安全
  3. #{}常常作为列值使用,位于等号的右侧,#{}位置的值和数据类型有关
2 $占位符

语法:${字符}

mybatis执行${}占位符的sql语句

<select id="selectByObject" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where id=${studentId}</select>${}表示字符串连接,把sql语句的其他内容和${}内容使用字符串连接的方式连在一起String sql="select id,name,email,age from student where id="+"1001";mybatis创建的是Statement对象,执行sql语句Statement stmt=conn.createStatement(sql);ResultSet rs=stmt.excuteQuery();//执行sql语句

${}特点

  1. 使用Statement对象,执行sql语句,效率低
  2. ${}占位符的值,使用的是字符串拼接,有sql注入危险,有代码安全问题
  3. ${}数据是原样使用的,不会区分数据类型
  4. 常 用 在 表 名 或 列 明 , 在 保 证 数 据 安 全 的 前 提 下 使 用 {}常用在表名或列明,在保证数据安全的前提下使用 常用在表名或列明,在保证数据安全的前提下使用{}

使用大体与#{}类似;

注意:

  1. dao接口简单参数必须使用@Param()
  2. ${}数据是原样使用的;若传入参数为“lisi”,

select id,name,email,age from student where id=${studentname}

则执行sql语句:

select id,name,email,age from student where id=lisi

而不是

select id,name,email,age from student where id=‘lisi’

  1. 同样,按列名排序使用${}而不使用#{};

    select id,name,email,age from student orderby ${param}(param变量,可从方法参数传入以实现按不同列排序)

3.3 封装MyBatis输出结果

封装输出结果:MyBatis执行sql语句后,得到ResultSet,转为java对象。

有两个:resultType,resultMap

3.3.1 resultType

resultType属性:在执行select时使用,作为标签的属性出现的

result Type:表示结果类型,mysql执行sql语句,得到java对象的类型,它的值有两种:

  1. java的全限定名称
  2. 使用别名

1)resultType表示java自定义对象

<select id="selectByObject" resultType="com.bipowernode.domain.Student">    select id,name,email,age from student where name=#{name}</select>resultType:现在使用java对象的全限定·名称。表示的意思是mybatis执行sql语句,把ResultSet中的数据转为Student类型的对象。mybatis会执行以下操作:1.调用com.bipowernode.domain.Student的无参构造方法,创建对象Student student=new Student();//使用反射创建对象2.同名的列赋给同名的属性student.setId(rs.getInt("id"));student.setName(rs.getString("name"))3.得到java对象,如果dao接口返回值List集合,mybatis会将student对象放入到List集合所以执行 Student student=dao.selectById(1001);得到数据库中 id=1001这行数据。这行数据的列值赋给了student对象。就相当于是id=1001这行数据。

2)resultType表示简单类型

dao接口方法

long countStudent();

mapper文件

<select id="countStudent" resultType="java.lang.Long">    select count(*) from student</select>

3)resultType表示map结构

dao接口

Map<Object,Object> selectMap(Integer id);

mapper文件

<!--执行sql语句,得到一个Map结构的数据,mybati执行sql语句,把ResultSet转为Map列名做map的key,列值作为valuesql执行得到的是一条记录,转为map结构是正确的dao接口返回值类型为map时,sql语句执行结果最多获得一条记录,多于一条会报错--><select id="selectMap" resultType="java.util.HashMap">    select id,name,email from student where id!=#{stuid};</select>

3.4.2 resultMap

resultMap:结果映射。自定义列表和java对象属性的对应关系。常用在列表名和属性名不同的情况

用法:

  1. 先定义resultMap标签,指定列名和属性名对应关系

  2. 在select标签中使用resultMap属性,指上面定义的resultMap的id

    <!--resultMap定义resultMap:id:给resultMap的映射关系起个名称,唯一值type:java类型的全限定名称--><resultMap id="customMap" type="com.bipowernode.vo.CustomObject">    <!--定义列明和属性名的对应-->    <!--主键类型使用id标签-->    <id column="id" property="cid"></id>    <!--非主键列使用result标签-->    <result column="name" property="cname"></result>    <!--列名与属性名相同无需定义,定义也不错--></resultMap><!--使用resultMap属性,指定映射关系的id    不能与resultTtpe同时使用,二选一--><select id="selectCustomById" resultMap="customMap"  >        select id,name,email,age from student where id=#{stuid};    </select>
    

3.5 使用别名

MyBatis提供的对java类型简短定义,名称好记

自定义别名的步骤:

  1. 在MyBatis的主配置文件,使用typeAliase标签声明别名

  2. 在mapper文件中,resultType=“别名”

    第一种方式

    <!--声明别名--><typeAliases>    <!--第一种语法格式        type:java类型的全限定名称(自定义类型)        alias:自定义别名		优点:别名可以自定义		缺点:每个类型必须单独定义    -->    <typeAlias type="com.bipowernode.domain.Student" alias="student"></typeAlias></typeAliases>
    
<select id="selectById" parameterType="java.lang.Integer" resultType="student" >    select id,name,email,age from student where id=#{studentId};</select>

第二种方式

  <!--第二种方式:name:包名。mybatis会自动把这个包下的所有类名作为别名(不用区分大小写)优点:使用方便,一次可以给多个类定义别名缺点:别名不能自定义,必须是类名。若不同包下有相同类名会报错。-->    <package name="com.bipowernode.domain"/>
<select id="selectById" parameterType="java.lang.Integer" resultType="student" >    select id,name,email,age from student where id=#{studentId};</select>

建议使用全限定名称,可读性好。

3.6 列名与java对象属性名称不一样解决方式

  1. 使用resultMap:自定义列名和属性名称对应关系
  2. 使用resultType:使用列的别名,使列的别名与对象属性名相同。

3.7 like模糊查询

第一种方式:在java程序中,把like的内容组装好,把这个内容传入到sql语句

dao

//模糊查询第一种方式List<Student> selectLikeOne(@Param("name") String name);

mapper

<select id="selectLikeOne" resultType="student">    select id,name,email,age from student where name like #{name}</select>

测试代码

@Testpublic void testSelectLikeOne(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    String name="%李%";    List<Student> stus=dao.selectLikeOne(name);   for(Student s:stus){       System.out.println(s);   }   sqlSession.close();}

第二种方式:在sql语句中组织like的内容

sql语句中like的格式:where name like “%“空格#{name}空格”%”

dao

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

mapper

 <select id="selectLikeTwo" resultType="student">        select id,name,email,age from student where name like "%" #{name1} "%"    </select>

Test

@Testpublic void testSelectLikeTwo(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    String name="李";    List<Student> stus=dao.selectLikeTwo(name);    for(Student s:stus){        System.out.println(s);    }    sqlSession.close();}

第四章 动态sql

什么是动态sql:同一个dao的方法,跟进不同的条件可以表示不同的sql语句,主要是where部分变化

使用mybatis提供的标签,实现动态sql,主要学习if,where,foreach,sql。

使用动态sql时dao方法的形参要使用java对象

4.1 if

语法:可以有多个if,没有else

主要用于多条件查询。

<if test="boolean判断结果">sql代码</if><if test="boolean判断结果">sql代码</if><if test="boolean判断结果">sql代码</if>在mapper文件中 <select id="selectById" resultType="com.bipowernode.domain.Student" >            select id,name,email,age from student(主sql)      <if test="条件">         sql语句(部分sql)     </if> </select>

注意sql语句中小于号”<" 报错使用实体

实体符号表

< 小于 &lt;
> 大于 &gt;
<= 小于等于 &lt;=
>= 大于等于 &gt;=

4.2 where 标签

使用if标签时,容易引起sql语法错误,使用where标签可以解决if产生的语法问题

使用where时,里面是一个或多个if条件,当有一个if标签判断条件为true,where标签会转为where关键字附加到sql语句后面,如果没有一个if条件为true,忽略where和里面的if

where标签会删除据它最近的那个or或and

语法:<where>    <if test="条件一"></if>    <if test="条件二"></if></where>

dao

List<Student> selectWhere(Student student);

mapper

<select id="selectWhere" resultType="com.bipowernode.domain.Student">    select * from student    <where>        <if test="name !=null and name !=''">          or name=#{name}        </if>        <if test="age>0">        or age  &lt;#{age }        </if>    </where></select>

测试

@Testpublic void testSelectWhere(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    Student stu=new Student(1006,"李广","wangwu@qq.com",45);    List<Student> list=dao.selectWhere(stu);    for(Student s:list){        System.out.println(s);    }    sqlSession.close();}

4.3 foreach循环

手动实现sql语句

@Testpublic void testFor(){    List<Integer> idList=new ArrayList<>();    idList.add(1001);    idList.add(1002);    idList.add(1003);    //查询id在idlist中的student    //select * from student where id in(1001,1002,1003)    StringBuffer sql=new StringBuffer();    sql.append("select * from student where id in ");    sql.append("(");    //使用循环,把List数据追加到sql中    for(int i=0;i<idList.size();i++){        int item=idList.get(i);        sql.append(item+",");    }    sql.setCharAt(sql.length()-1,')');    System.out.println(sql.toString());}

使用foreah可以循环数组,list集合,一般使用在in语句中

语法:

<foreach collection="集合类型" open="开始的字符" close="结束的字符" m="集合中的员"         separartor="集合成员之间的分隔符">    #{item的值}</foreach>标签属性:collection:表示循环的对象 是数组 还是List集合。如果dao接口方法参数 是数组,collection="array",如果是List,collection="list"open:循环开始的字符 sql.append("(");close:循环结束时的字符 sql.setCharAt(sql.length()-1,')');item:集合成员,自定义的变量separator:集合成员间的分隔符 如','#{item}:获取item的值

List集合存放简单类型数据:

dao:

List<Student> selectForeach1(List<Integer> idlist);

mapper文件

<select id="selectForeach1" resultType="com.bipowernode.domain.Student">    <if test="list!=null and list.size>0">        select * from student where id in        <foreach collection="list" open="(" close=")" separator="," item="myid">            #{myid}        </foreach>    </if>    <if test="list=null or list.size&lt;=0">        select * from student where 1=-1    </if>

test

@Testpublic void testSelectForeahOne(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    List<Integer> idList=new ArrayList<>();    idList.add(1001);    idList.add(1002);    idList.add(1003);   List<Student> list= dao.selectForeach1(idList);   for(Student s:list){       System.out.println(s);   }    sqlSession.close();}

list存的是对象

List<Student> selectForeach2(List<Student> idlist);

mapper

</select><select id="selectForeach2" resultType="com.bipowernode.domain.Student">    <if test="list!=null and list.size>0">        select * from student where id in        <foreach collection="list" open="(" close=")" separator="," item="student">            #{student.id}//对象.属性名 获取值        </foreach>    </if>    <if test="list=null or list.size&lt;=0">        select * from student where 1=-1    </if></select>

test

@Testpublic void testSelectForeach2(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    List<Student> idList=new ArrayList<>();   Student s1=new Student();   Student s2=new Student();   s1.setId(1001);   s2.setId(1002);    idList.add(s1);    idList.add(s2);    List<Student> list= dao.selectForeach2(idList);    for(Student s:list){        System.out.println(s);    }    sqlSession.close();}

4.4 代码片段

代码标签用于定义sql片段,以便于其他标签使用该SQL片段,需要使用子标签.该标签可以dingyisql语句中的任何部分,所以子标签可以放在动态sql的任何位置

接口方法:

ListselectStudentSqlFragment(List stuList);

mapper文件:

 <sql id="studentSql">        select * from student where    </sql>    <select id="selectStudentSqlFragment" resultType="com.bipowernode.domain.Student">        <include refid="studentSql"/>        <if test="list!=null and list.size>0">             id in            <foreach collection="list" open="(" close=")" separator="," item="student">                #{student.id}            </foreach>        </if>        <if test="list=null or list.size&lt;=0">          1=-1        </if>    </select>

test

@Testpublic void selectStudentSqlFragment(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    List<Student> idList=new ArrayList<>();    Student s1=new Student();    Student s2=new Student();    s1.setId(1001);    s2.setId(1002);    idList.add(s1);    idList.add(s2);    List<Student> list= dao.selectStudentSqlFragment(idList);    for(Student s:list){        System.out.println(s);    }    sqlSession.close();}

第五章 MyBatis配置文件

MyBatis配置文件有两大类:

  1. 主配置文件,提供Mybatis全局设置的.包含的内容有 日志,数据源,mapper文件位置等
  2. mapper文件:写sql语句的.一个表一个mapper文件

5.1 settings部分

settings是mybatis的全局设置,影响整个mybatis的运行.这个设置一般用默认值就行.

完整的settings

<settings>  <setting name="cacheEnabled" value="true"/>  <setting name="lazyLoadingEnabled" value="true"/>  <setting name="multipleResultSetsEnabled" value="true"/>  <setting name="useColumnLabel" value="true"/>  <setting name="useGeneratedKeys" value="false"/>  <setting name="autoMappingBehavior" value="PARTIAL"/>  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>  <setting name="defaultExecutorType" value="SIMPLE"/>  <setting name="defaultStatementTimeout" value="25"/>  <setting name="defaultFetchSize" value="100"/>  <setting name="safeRowBoundsEnabled" value="false"/>  <setting name="mapUnderscoreToCamelCase" value="false"/>  <setting name="localCacheScope" value="SESSION"/>  <setting name="jdbcTypeForNull" value="OTHER"/>  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/></settings>

5.2 typeAlias

设置别名,可用可不用

<!--声明别名--><typeAliases>    <!--第一种语法格式        type:java类型的全限定名称(自定义类型)        alias:自定义别名    -->    <typeAlias type="com.bipowernode.domain.Student" alias="student"></typeAlias>    <!--第二种方式:name:包名。mybatis会自动把这个包下的所有类名作为别名(不用区分大小写)优点:使用方便,一次可以给多个类定义别名缺点:别名不能自定义,必须是类名。若不同包下有相同类名会报错。-->    <package name="com.bipowernode.domain"/></typeAliases>

5.3 配置环境

enviroments:环境标签,里面那可以配置多个enviroment

  • enviroment:表示一个数据库的连接信息
    • 属性id 自定义的环境标识.唯一值
    • 属性default必须是某个enviroment的id属性值,表示mybatis默认连接数据库.
    • transactionManager:事务管理器
      • type:标识事务管理器类型
        属性值:1)JDBC:使用Connection对象,由mybatis自己完成事务处理
        2)MANAGED:管理,表示把事务交给容器实现(由其他软件完成事务的提交回滚)
    • dataSource: 数据源,创建Cennection对象,连接数据库
      • type属性:表示数据源的类型;
        • 属性值:1.POOLED表示mybatis会在内存中创建PooledDataSource类,管理多个Connection对象,使用的连接池
        • 2.UNPOOLED,不使用连接池,mybatis创建一个UnPooledDataSource类,每次执行sql语句先创建Connection对象,再执行sql语句,最后关闭Connection(基本不用)
        • 3.JDNI:java的命名和目录服务.
<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/           ssm?useUnicode=true &amp;characterEncoding=UTF-8 &amp;serverTimezone=GMT"/>            <property name="username" value="root"/>            <property name="password" value="root123456"/>        </dataSource>    </environment>      <environment id="online">        <transactionManager type="JDBC"/>        <!-- 项目上线使用的数据库-->        <dataSource type="POOLED">            <property name="driver" value="com.mysql.cj.jdbc.Driver"/>            <property name="url" value="jdbc:mysql://localhost:3306/           ssm?useUnicode=true &amp;characterEncoding=UTF-8 &amp;serverTimezone=GMT"/>            <property name="username" value="admin"/>            <property name="password" value="123456"/>        </dataSource>    </environment></environments>

5.4 使用数据库配置文件(掌握)

需要把把数据库的配置信息放到一个单独文件中,独立管理,这个文件扩展名是properties.在这个文件中使用自定义的key=value的格式表示数据

使用步骤:

  1. 在resource目录中,创建xxx.properties文件

  2. 在文件和中使用key=vaule的格式定义数据

    例如:jdbc.url=jdbc:mysql://localhost:3306/springdb

  3. 在mybatis主配置文件,使用properties标签引用外部的属性配置文件

  4. 在使用值得位置,使用${key}获取key对应的value(等号的右侧)

properties文件

jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/ssm?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMTjdbc.username=rootjdbc.password=root123456

主配置文件

<?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>    <!--使用外部属性配置文件    resource:用来指定类路径下的某个属性配置文件    -->    <properties resource="jdbc.properties"/>    <!--日志-->    <settings>        <setting name="logImpl" value="STDOUT_LOGGING"/>    </settings>    <!--声明别名-->    <typeAliases>        <package name="com.bipowernode.domain"/>    </typeAliases>    <environments default="development">        <environment id="development">            <transactionManager type="JDBC"/>            <!-- 配置数据源-->            <dataSource type="POOLED">                <property name="driver" value="${jdbc.driver}"/>                <property name="url" value="${jdbc.url}"/>                <property name="username" value="${jdbc.username}"/>                <property name="password" value="${jdbc.password}"/>            </dataSource>        </environment>    </environments>    <mappers>        <!--    resource=“mapper文件按的路径使用 / 分隔路径”    -->        <mapper resource="com/bipowernode/dao/StudentDao.xml"/>    </mappers></configuration>

5.5 mapper 标签

使用mapper指定其他文件的位置

mapper标签使用格式:有两种常用方式

  1. 第一种方式: resources=“mapper文件路径”;

    优点:文件清晰,加载哪个文件一目了然,文件的位置灵活;

    缺点:文件较多时代码量比较大,管理难度大

  2. 第二种方式:name=“包名”. mapper文件所在的包名

    特点:将该包中的所有所有mapper文件一次加载.

    使用要求:mapper文件和dao接口在同一目录,且与dao接口名称完全一致.

<!--第一种方式,使用resources--><mapper resource="com/bipowernode/dao/StudentDao.xml"/><!--第二种方式,使用name--><package name="com.bipowernode.daol"/>

第六章 PageHelper

PageHelper做数据分页.在你的select语句后面加入分页的sql内容.如果你使用的mysql数据库,它就是在select* from student 后加上limit语句

使用步骤

  1. 加入pagehelper依赖

    <!--加入pagehelper依赖--><dependency>  <groupId>com.github.pagehelper</groupId>  <artifactId>pagehelper</artifactId>  <version>5.1.10</version></dependency>
    
  2. 在mybatis主配置未见加入plugin声明

    <!--在enviroments之前--><plugins>    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin></plugins><environments default="development">        <environment id="development">            <transactionManager type="JDBC"/>            <!-- 配置数据源-->            <dataSource type="POOLED">                <property name="driver" value="${jdbc.driver}"/>                <property name="url" value="${jdbc.url}"/>                <property name="username" value="${jdbc.username}"/>                <property name="password" value="${jdbc.password}"/>            </dataSource>        </environment>    </environments>
    
  3. 在select语句之前,调用PageHelper.startPage(页码,每页大小)(页码从1开始)

测试使用:

@Testpublic void testPageHelper(){    SqlSession sqlSession=MyBatisUtil.getSqlSession();    StudentDao dao=sqlSession.getMapper(StudentDao.class);    List<Student> idList=new ArrayList<>();    PageHelper.startPage(2,3);    List<Student> list= dao.selectAllStudent();    for(Student s:list){        System.out.println(s);    }    sqlSession.close();}

控制台输出结果:

Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@8297b3a]==>  Preparing: SELECT count(0) FROM student ==> Parameters: <==    Columns: count(0)<==        Row: 7<==      Total: 1==>  Preparing: select * from student order by id LIMIT ?, ? ==> Parameters: 3(Integer), 3(Integer)<==    Columns: id, name, email, age<==        Row: 1004, 公明, gongming@qq.com, 47<==        Row: 1005, 李广, liguang@qq.com, 20<==        Row: 1006, 武松, wusong@qq.com, 38<==      Total: 3Student{id=1004, name='公明', email='gongming@qq.com', age=47}Student{id=1005, name='李广', email='liguang@qq.com', age=20}Student{id=1006, name='武松', email='wusong@qq.com', age=38}
上一篇:Dao模式


下一篇:Synthetix创始人新作:募资,应以DAO当先