Mybatis框架一文详解

Mybatis框架

1:三层框架

**界面层:**和用户打交道的,接收用户的请求参数,显示处理结果的。(jsp html servlet)

**业务逻辑层:**接收了界面层传递的数据,计算逻辑,调用数据库,获取数据。

**数据访问层:**就是访问数据库,执行对数据的查询,修改,删除等等。

三层对应的包:

界面层:controller包(servlet类)

业务逻辑层:service包(XXXservice类)

数据库访问层:dao包(XXXDao类)

三层中类的交互:

用户使用界面层–>业务逻辑层—>数据库访问层—>数据库(mysql)

三层对应的处理框架:

界面层(servlet类)—>springMVC(框架)

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

数据库访问层(dao类)—>myBatis(框架)

2:框架

框架介绍:

是一个舞台,模板。

框架是一个软件,半成品的软件,定义好了一些基础功能,需要加入你的功能就是完整的。基础功能是可以重复使用的,可升级的。

模板:

1:规定好了一些条款,内容。

2:加入自己的东西。

框架是一个模板

1:框架中定义好了一些功能,这些功能是可用的。

2:可以加入项目中自己的功能,这些功能可以利用框架中写好的功能。

框架的特点:

1:框架一般不是全能的,不能做所有的事情。

2:框架是针对某一个领域有效,特长在某一个方面,比如myBatis做数据库操作,但是它不能做其他的。

3:框架是一个软件。

3:使用JDBC的缺陷

1:代码比较多,开发效率低

2:需要关注Connection,Statement,ResultSet对象的创建和销毁

3:对ResultSet查询的结果,需要自己封装List集合。

4:重复的代码比较多。

5:业务代码和数据库操作混合在一起。

4:myBatis框架

一个框架,早期叫做ibatis,代码在gitHup

myBatis是 MyBatis SQL Mapper Framework for Java(sql映射框架)

1:sql Mapper:sql映射

可以把数据库表中的一行数据,映射为一个java对象。

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

Data Access Object (DAOs)

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

2:myBatis提供了那些功能?

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

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

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

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

开发人员做的是:提供sql语句。

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

3:总结

myBatis是一个sql映射框架,提供操作数据库的能力,增强的JDBC。

使用myBatis让开发人员集中精神写sql就可以了,不必关心Connection,Statement,ResultSet的创建和销毁以及sql语句的执行。

5:myBatis使用步骤:

下载地址:https://github.com/mybatis/mybatis-3/releases

实现步骤:

1:新建student表。

2:加入maven的myBatis坐标,mysql驱动的坐标。

3:创建实体类,Student–保存表中的一行数据的。

4:创建持久层的dao接口,定义操作数据库的方法。

5:创建一个myBatis使用的配置文件,叫做sql映射文件:写sql语句的。一般一个表一个sql映射文件。
这个文件是xml文件。
1:在接口所在的目录中。
2:文件的名称,和接口保持一致。

6:创建myBatis的主配置文件:
一个项目就一个主配置文件。
主配置文件提供了数据库的连接信息和SQL映射文件的位置信息。

7:创建使用myBatis类:
通过myBatis访问数据库。

接口创建步骤:

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

  		//插入数据方法
  		//参数:student,表示要插入到数据库的数据
  		//返回值:int,表示执行insert操作后,影响数据库的行数
  		int insertStudent(Student student);
	}

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">
<mapper namespace="com.sss.dao.StudentDao">

    <!--
        select:表示查询操作
        id:你要执行的sql语句的唯一标识,myBatis会使用找个id的值来找到要执行的sql语句。
            可以自定义,但是要求你使用接口中的方法名称。

        resultType:表示结果类型的,是sql语句执行后得到ResultSet,遍历这个ResultSet得到java对象的类型。
                    值写的是类型的全限定名称
    -->
    <select id="stuSelect" resultType="com.sss.entity.Student">
        select id,name,email,age from student order by id
    </select>

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

</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>:表示执行查询,select语句。
        <update>:表示更新数据库的操作,就是在<update>标签中,写的是update sql语句。
        <insert>:表示插入,放的是insert语句。
        <delete>:表示删除,放的是delete语句。
-->
<select>:表示执行查询,select语句。
<update>:表示更新数据库的操作,就是在<update>标签中,写的是update sql语句。
<insert>:表示插入,放的是insert语句。
<delete>:表示删除,放的是delete语句。

–>

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>

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

    <!--环境配置:数据库的连接信息
        default:必须和某个environment的id值一样
        告诉myBatis使用那个数据库的连接信息,也就是访问那个数据库。
    -->
    <environments default="development">
        <!--environment:一个数据库信息的配置,环境
            id:一个唯一值,自定义,表示环境的名称。
        -->
        <environment id="development">
            <!--
                transactionManager:myBatis的事务类型
                type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理。)
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource:表示数据源,连接数据库的。
                type:表示数据源的类型,POOLED表示使用连接池。
            -->
            <dataSource type="POOLED">
                <!--
                    driver,url,username,password 是固定的,不能自定义。
                -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <!--连接数据库的url字符串-->
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                <!--访问数据库的用户名-->
                <property name="username" value="root"/>
                <!--访问数据库的密码-->
                <property name="password" value="999"/>
            </dataSource>
        </environment>
    </environments>

    <!-- sql mapper(sql映射文件)的位置-->
    <mappers>
        <!--一个mapper标签指定一个文件的位置
            从类路径开始的路径信息。target/clasess(类路径)
        -->
        <mapper resource="com/sss/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></configuration>:根标签
-->

<build>
	<resources>
      <resource>
        <!--所在的目录-->
        <directory>src/main/java</directory>
        <includes><!--包括目录下的.properties,.xml文件都会被扫描到-->
          <include>**/*.properties</include>
          <include>**/*.xml</include>
        </includes>
        <!--filtering 选项 false 不启用过滤器,*.property 已经起到过滤的作用了-->
        <filtering>false</filtering>
      </resource>
    </resources>
</build>

myBatis读取数据步骤案例:

//访问myBatis读取student数据。

//1:定义myBatis主配置文件的名称,从类路径的根开始(target/clasess)
String config = "myBatis.xml";

//2:读取这个config表示的文件。
InputStream in = Resources.**getResourceAsStream**(config);

//3:创建sqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//4:创建sqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);

//5:【重要】获取SqlSession对象,从SqlSessionFactory中获取SqlSession
SqlSession sqlSession = factory.openSession();

//6:【重要】指定要执行的sql语句的标识。sql映射文件中的namesapce + "." + 标签的id值
String sqlId = "com.sss.dao.StudentDao" + "." + "stuSelect";

//7:执行sql语句,通过sqlId找到语句。
List<Student> listStu = sqlSession.selectList(sqlId);

//8:输出结果
//listStu.forEach(student -> System.out.println(student));
for (Student stu : listStu) {
  System.**out**.println(stu);
}

//9:关闭sqlSession对象
sqlSession.close();

6:主要类的介绍:

1:Resources:

myBatis中的一个类,负责读取主配置文件的。

InputStream in = Resources.getResourceAsStream(config);

2:sqlSessionFactoryBuilder:

负责调用build()方法,来创建sqlSessionFactory对象。

//3:创建sqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();

//4:创建sqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);

3:sqlSessionFactory:

重量级对象,程序创建一个对象耗时比较长,使用资源比较多。在整个项目中,有一个就够用了。

SqlSessionFactory factory = builder.build(in);

sqlSessionFactory是一个接口,接口的实现类:DefaultSqlSessionFactory

sqlSessionFactory作用:通过调用openSession()方法,获取sqlSession对象。

SqlSession sqlSession = factory.openSession();

openSession()方法说明:

openSession():无参数的,获取的是非自动提交事务的sqlSession对象

openSession(boolean):布尔类型参数:true:获取自动提交事务的sqlSession,false:获取的是非自动提交事务的sqlSession对象。

4:sqlSession:

sqlSession接口:定义了操作数据库的方法,例如:

selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()

​ sqlSession接口的实现类: DefaultSqlSession,这个类中实现了操作数据库方法的实现。

​ 使用要求:sqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,调用openSession()方法,获取sqlSession对象。在执行完sql语句后,需要关闭它,执行sqlSession.close();这样能保证他的使用是线程安全的。

7:myBatis工具类(简化代码)

实现代码:

package org.example.utils;

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;

/**
 * myBatis工具类
 */
public class MyBatisUtils {

    private static SqlSessionFactory sf = null;
    //在静态代码块中获取SqlSessionFactory对象【重量级对象,只需要创建一次】
    static {
        String config = "myBatis.xml"; //定义myBatis主配置文件
        try {
            //读取主配置文件
            InputStream in = Resources.getResourceAsStream(config);
            //创建sqlSessionFactory对象,使用sqlSessionFactoryBuild对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            sf = builder.build(in);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        SqlSession sqlSession = null;
        if (sf != null){
           sqlSession = sf.openSession();   //非自动提交事务
        }
        return sqlSession;
    }
}

8:动态代理及传入参数

1:动态代理介绍:

使用sqlSession.getMapper(dao接口.class) 获取这个dao接口的实现类对象。

myBatis的动态代理:myBatis根据dao的方法调用,获取执行sql语句的信息。
 myBatis根据你的dao接口,创建出一个dao接口的实现类,并创建出这个类的对象。
 完成sqlSession调用方法,访问数据库。
 简单说就是:通过myBatis的动态代理,就不需要创建接口的实现类,myBatis内部进行实现。

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

​ 1.dao接口和mapper文件放在一起,同一个目录下。

​ 2.dao接口和mapper文件名称一致。

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

​ 4.mapper文件中的,,等,它们的id是接口中方法的名称。

实现代码:

@Test
public  void testSelectStudent(){
  /**
   * 使用myBatis的动态代理机制,使用SqlSession.getMapper(dao接口)
   * getMapper能获取dao接口对应的实现类对象。
   * MyBatisUtils:自定义封装好的工具类
   */
  SqlSession sqlSession = MyBatisUtils.getSqlSession();
  StudenDao dao = sqlSession.getMapper(StudenDao.class);
  //调用dao的方法,执行数据库的操作。
  List<Student> studentList = dao.selectStudent();
  for (Student student:studentList) {
    System.**out**.println(student);
  }
}

3:传入参数:

从java代码中把数据传入到mapper文件的sql语句中。

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

​ 例如:StudentDao接口方法:

Student selectStudentById(Integer id);

2):传入一个简单类型的参数:

​ 简单类型:myBatis把java的基本数据类型和字符串都叫做简单数据类型。

​ 在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.example.dao.StudenDao">

    <!--
        parameterType:dao接口中方法参数的数据类型。
            parameterType它的值是java的数据类型全限定名称或者是myBatis定义的别名。
            例如:parameterType="java.lang.Integer"

            注意:parameterType不是强制的,myBatis通过反射机制能够发现接口参数的数据类型。
                所以可以没有,一般我们也不写
    -->
    <select id="selectStudentById" parameterType="java.lang.Integer" resultType="org.example.entity.Student">
        select id,name,email,age from student where id=#{id}
    </select>
</mapper>

3):传入多个参数,使用@param命名参数

​ 接口方法:

public List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") Integer age);

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

mapper文件中这样写:

<select>
	select * from student where name=#{myname} or age=#{myage}
</select>

4):使用java对象传入多个参数

​ 1:先创建储存对象的java类

​ 2:接口方法:

/**
     * 多个参数,使用java对象作为接口中方法的参数
     * @param param
     * @return
     */
    List<Student> selectMultiObject(QueryParam param);

​ 3:mapper文件sql语句怎么写?

<!--多个参数,使用java对的属性值,作为参数的实际值
        使用对象语法:#{属性名,javaType=类型名称,jdbcType=数据类型}   很少用
        javaType:指java中的属性数据类型。
        jdbcType:指数据库中的数据类型。
        最完整的方式:
        例如:name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}

        简化方式:#{属性名},javaType,jdbcType的值myBatis反射能获取,不用提供。
    -->
    <select id="selectMultiObject" resultType="org.example.entity.Student">
        /*select id,name,email,age from student where name=#{paramName,javaType=java.lang.String,jdbcType=VARCHAR}
        or age=#{paramAge,javaType=java.lang.Integer,jdbcType=INTEGER}*/

        select id,name,email,age from student where name=#{paramName} or age=#{paramAge}
    </select>

9:#和$的区别

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

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

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

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

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

#:占位符

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

mapper 文件

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

转为 MyBatis 的执行是:

String sql=” select id,name,email,age from student where id=?;

PreparedStatement ps = conn.prepareStatement(sql);

ps.setInt(1,1005);

解释:

where id=? 就是 where id=#{studentId}

ps.setInt(1,1005) , 1005 会替换掉 #{studentId}

$ :字符串替换

告诉 mybatis 使用 包 含 的 “ 字 符 串 ” 替 换 所 在 位 置 。 使 用 S t a t e m e n t 把 s q l 语 句 和 包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和 使Statementsql{}的

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

例 1: 分别使用 id , email 列查询 Student

接口方法:

Student findById(int id);

Student findByEmail(String email);

mapper 文件:

<select id="findById" resultType="com.bjpowernode.domain.Student">
 select * from student where id=#{studentId}
</select>
<select id="findByEmail" resultType="com.bjpowernode.domain.Student">
 select * from student where email=#{stuentEmail}
</select>

测试方法:

@Test
public void testFindStuent(){
 Student student1 = studentDao.findById(1002);
 System.out.println("findById:"+student1);
 Student student2 = studentDao.findByEmail("zhou@126.net");
 System.out.println("findByEmail:"+student2);
}

例 2:通用方法,使用不同列作为查询条件

接口方法:

Student findByDiffField(@Param("col") String colunName,@Param("cval") Object 
value);

mapper 文件:

<select id="findByDiffField" resultType="com.bjpowernode.domain.Student">
 select * from student where ${col} = #{cval}
</select>

测试方法:

@Test
public void testFindDiffField(){
 Student student1 = studentDao.findByDiffField("id",1002);
 System.out.println("按 id 列查询:"+student1);
 Student student2 = studentDao.findByDiffField("email","zhou@126.net");
 System.out.println("按 email 列查询:"+student2);
}

10:myBatis的输出结果

​ myBatis执行了sql语句,得到了java对象。

1:resultType结果类型

​ 指sql语句执行完毕后,数据转为的java对象,java对象类型是任意的。

resultType结果类型的值:1:类型的全限定名称【建议使用】。2:类型的别名,例如java.lang.Integer别名是int

​ resultType结果类型处理方式:

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

​ 2:myBatis把ResultSet指定列值,赋值给同名的属性。

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

​ 1:在myBatis主配置文件中定义,使用定义别名。

​ 2:可以在resultType中使用自定义的别名。

在myBatis主配置文件中设置:

 <!--定义别名-->
    <typeAliases>
        <!--可以指定一个类型,一个自定义的别名
            type:自定义类型的全限定名称
            alias:别名(短小,容易记忆的)
        -->
        <typeAlias type="org.example.entity.Student" alias="stu"/>
        
        <!--
            第二种方式:
            <package> name是包名,这个包中所有类,类名就是别名(类名不区分大小写)
            例如:<package name="org.example.vo"/> 这个包中的QueryParam类,就是别名。
			【常用方式】
        -->
        <package name="org.example.vo"/>
    </typeAliases>

3:resultMap:结果映射

​ 指定列名和java对象的属性对应关系。

​ 1:你自定义列值赋值给那个属性。

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

​ 3:resultMap和resultType只能出现一个。

mapper文件:

<!--定义resultMap
        id:自定义名称,表示你定义的这个resultMap
        type:java类型的全限定名称
    -->
    <resultMap id="studentMap" type="org.example.entity.Student">
        <!--定义列名和java属性的关系-->
        <!--主键列,使用id标签
            column:列名
            property:java类型的属性名
        -->
        <id column="id" property="id"></id>
        <!--非主键类,使用result-->
        <result column="name" property="name"></result>
        <result column="email" property="email"></result>
        <result column="age" property="age"></result>
    </resultMap>

	<!--列名和属性名不一样,第一种解决方式:-->
	<select id="selectStudents" resultMap="studentMap">
        select id,name,email,age from student
    </select>


	<!--查询所有学生信息
        resultType的默认原则是,同名的列值赋值给同名的属性,使用列别名(java对象的属性名)
    -->
    <!--列名和属性名不一样,第二种解决方式:-->
    <select id="selectDiff" resultType="org.example.entity.Student">
        select id as id,name as name,email,age from student
    </select>

4:like模糊查询

dao接口:

 	/**
     * 第一种模糊查询,在java代码中指定 like的内容
     */
    List<Student> selectLikeOne(String name);

    /**
     * 第二种模糊查询,name就是关值,在mapper文件中拼接 like "%" 关 "%"
     */
    List<Student> selectLikeTwo(String name);

mapper文件:

	<!--第一种like,java代码中指定like的内容【推荐使用第一种方式】-->
    <select id="selectLikeOne" resultType="org.example.entity.Student">
        select id,name,email,age from student where name like #{name}
    </select>

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

@Test:

	/**
     * 测试模糊查询
     */
    @Test
    public  void testSelectLikeOne(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudenDao dao = sqlSession.getMapper(StudenDao.class);
        String name = "%关%";
        List<Student> student = dao.selectLikeOne(name);
        for (Student student1: student) {
            System.out.println(student1);
        }
    }

    @Test
    public  void testSelectLikeTwo(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudenDao dao = sqlSession.getMapper(StudenDao.class);
        List<Student> student = dao.selectLikeTwo("关");
        for (Student student1: student) {
            System.out.println(student1);
        }
    }

11:动态Sql

介绍:

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

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

1:if是判断条件的

​ 语法:

<if test="判断java对象的属性值">

​	部分的sql语句

</if>

mapper文件:

 <!--if
        <if test = "使用参数java对象的属性值作为判断条件,语法 属性名 = xxx值">
    -->
    <select id="selectStudentIf" resultType="org.example.entity.Student">
        select id,name,email,age from student
        where 1=1
        <if test="name != null and name !='' ">
            name = #{name}
        </if>
        <if test="age > 0">
            or age > #{age}
        </if>
    </select>

2:where

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

mapper文件:

 <!--
        where:<where> <if></if>...</where>
    -->
    <select id="selectStudentWhere" resultType="org.example.entity.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>

3:foreach

​ 循环java中的数据,List集合的,主要用在sql的in语句中。

​ 查找学生id是 1001,1002,1003的三个学生。

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

foreach第一种方式:传入的是单个数据

dao接口:

	//foreach 用法 1
    List<Student> selectForeach(List<Integer> list);

mapper文件:

<!--
    foreach 使用 1
    collection:表示接口中的方法参数的类型,如果是数组使用array,如果是List集合使用list
    item:自定义的,表示数组或集合成员的变量。
    open:循环开始时的字符
    close:循环结束时的字符
    separator:集合成员之间的分割符
    循环体: #{myid}
-->
<select id="selectForeach" resultType="org.example.entity.Student">
    select * from student where id in
    <foreach collection="list" item="myid" open="(" close=")" separator=",">
        #{myid}
    </foreach>
</select>

@Test:

/**
     * 测试foreach 1
     */
    @Test
    public  void testSelectForeach(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudenDao dao = sqlSession.getMapper(StudenDao.class);
        List<Integer> list = new ArrayList<>();
        list.add(1001);
        list.add(1002);
        list.add(1003);
        List<Student> studentList = dao.selectForeach(list);
        for (Student student : studentList) {
            System.out.println(student);
        }
        sqlSession.close();
    }

foreach 第二种方式:传入的是java集合对象

dao接口:

//foreach 用法 2
List<Student> selectForeachTwo(List<Student> stulist);

mapper文件:

<select id="selectForeachTwo" resultType="org.example.entity.Student">
    select * from student where id in
    <foreach collection="list" item="stu" open="(" close=")" separator=",">
        #{stu.id}
    </foreach>
</select>

@Test:

/**
 * 测试foreach 2
 */
@Test
public  void testSelectForeachTwo(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudenDao dao = sqlSession.getMapper(StudenDao.class);
    List<Student> studentList = new ArrayList<>();

    Student student = new Student();
    student.setId(1001);
    studentList.add(student);

    System.out.println(studentList);
    List<Student> studentList1 = dao.selectForeachTwo(studentList);
    for (Student student3 : studentList1) {
        System.out.println(student3);
    }
    sqlSession.close();
}

4:sql代码片段

用来复用一些sql语句。

步骤:

​ 1:先使用 sql语句

​ 2:再使用,

<!--定义sql片段-->
<sql id="studentSql">
    select id,name,email,age from student
</sql>

<select id="selectStudentIf" resultType="org.example.entity.Student">
    <include refid="studentSql"/>
</select>

12:数据库的属性配置文件

​ 把数据库连接信息放到一个单独的文件中,和myBatis主配置文件分开。

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

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

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

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

​ 例如:jdbc.mysql.driver 或者 jdbc.driver

jdbc.mysql.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm
jdbc.user=root
jdbc.password=999

​ 2:在myBatis主配置文件中,使用指定文件的位置。

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

<!--指定properties文件的位置,从类路径根开始找文件-->
<properties resource="jdbc.properties"></properties>

    <environments default="development">
        <environment id="development">
            <!--
                transactionManager:myBatis提交事务,回滚事务的方式
                type:事务的处理类型。
                    1):JDBC:表示myBatis底层是调用JDBC中的Connection对象的,commit,rollback
                    2):MANAGED:把myBatis的事务处理委托给其他容器(一个服务器,一个框架(spring))
            -->
            <transactionManager type="JDBC"/>
            <!--
                dataSource:表示数据源,java体系中,规定实现了javax.sql.DataSource接口的都是数据源
                    数据源表示连接Connection对象的。

                type:指定数据源的类型
                    1):POOLED:使用连接池,myBatis会创建PooledDataSource类
                    2):UPOOLED:不使用连接池,在每次执行sql语句,先创建连接,执行sql,再关闭连接。
                                 myBatis会创建一个UnPooledDataSource,管理Connection对象的使用。
                    3):JNDI:java命令和目录服务(windows注册表)
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.mysql.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

mapper文件位置的指定:

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

13:扩展:PageHelper

PageHelper做数据分页的。

步骤:

1:pom.xml:添加依赖

<!--pageHelper分页插件依赖-->
<dependency>
  <groupId>com.github.pagehelper</groupId>
  <artifactId>pagehelper</artifactId>
  <version>5.1.10</version>
</dependency>

2:myBatis主配置文件:

<!--配置插件:在environments之前加入插件-->
<plugins>
    <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>

3:dao接口:

//使用pageHelper分页数据
List<Student> selectAll();

4:mapper文件:

<!--查询所有-->
<select id="selectAll" resultType="org.example.entity.Student">
   select id,name,email,age from student
</select>

5:@Test

/**
 * 测试分页
 */
@Test
public  void testSelectAll(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudenDao dao = sqlSession.getMapper(StudenDao.class);

    //加入pageHelper的方法,分页方法
    //两个参数
    //pageNum:第几页,从1开始
    //pageSize:一页中有多少行数据
    PageHelper.startPage(1,3);
    List<Student> studentList1 = dao.selectAll();
    for (Student student : studentList1) {
        System.out.println(student);
    }
    sqlSession.close();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柳落青

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值