zoukankan      html  css  js  c++  java
  • MyBatis学习笔记

    MyBatis官方文档

    1.框架概述

    MVC模式(Model–view–controller)是软件工程中的一种软件架构模式,把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。

    1.1 目前一般采用以下三层架构

    • 界面层: 和用户打交道的, 接收用户的请求参数, 显示处理结果的。在实现代码中,界面层的代码一般放置于controller包中。
    • 业务逻辑层: 接收了界面层传递的数据,计算逻辑,调用数据库,获取数据。在实现代码中,业务逻辑层的代码一般放置于service包中(XXXService类)。
    • 数据访问层(持久层): 就是访问数据库, 执行对数据的查询,修改,删除等等的。在实现代码中,数据访问层的代码一般放置于dao包中(XXXDao类)。

    1.2 三层中各个类的交互方式

    用户使用界面层 --> 业务逻辑层 ---> 数据访问层(持久层)--> 数据库(mysql)

    1.3 三层对应的处理框架

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

    这三层对应的框架便是非常著名的SSM三件套。利用SpringMVC接收用户请求,响应结果。利用Spring管理service类。利用mybatis代替jdbc访问数据库,所以mybatis可以看成是功能更加完善的jdbc。

    1.4 三个框架简介

    MyBatis框架:
    MyBatis是一个优秀的基于java的持久层框架,内部封装了jdbc,开发者只需要关注sql语句本身,而不需要处理加载驱动、创建连接、创建statement、关闭连接,资源等繁杂的过程。MyBatis通过xml或注解两种方式将要执行的各种sql语句配置起来,并通过java对象和sql的动态参数进行映射生成最终执行的sql语句,最后由 mybatis框架执行sql并将结果映射为java对象并返回。开发人员使用MyBatis的流程如下:
    开发人员提供sql语句 ---> mybatis处理sql ---> 开发人员得到List集合或java对象(表中的数据)
    
    Spring框架:
    Spring框架为了解决软件开发的复杂性而创建的。Spring使用的是基本的JavaBean来完成以前非常复杂的企业级开发。Spring解决了业务对象,功能模块之间的耦合,不仅在javase,web中使用,大部分Java应用都可以从Spring中受益。Spring是一个轻量级控制反转(IoC)和面向切面(AOP)的容器。
    
    SpringMVC框架
    SpringMVC属于SpringFrameWork 3.0 版本加入的一个模块,为Spring框架提供了构建Web应用程序的能力。现在可以Spring框架提供的SpringMVC模块实现web应用开发,在web项目中可以无缝使用Spring和SpringMVC框架。
    

    1.5 MyBatis功能

    MyBatis是一个sql映射框架,提供对数据库的操作能力。可以理解为是增强的JDBC。其主要有两个功能

    • sql mapper:sql映射功能,可以把数据库表中的一行数据映射为一个java对象。操作这个对象,就相当于操作表中的数据
    • Data Access Objects(DAOs) : 数据访问功能, 可以对数据库进行增删改查等操作。

    2.MyBatis框架快速入门

    2.1 MyBatis查询数据库操作

    MyBatis的基本使用步骤如下:

    • 1.在数据库中新建student表

    • 2.在Maven中加入mybatis和mysql的相关依赖

    • 3.创建实体类:student,用于保存数据库中student表中对应的一行数据。一般实体类在实现代码中都放在entity包中。

    • 4.创建持久层的dao接口,定义操作数据库的方法(只需要声明方法即可)

      • package com.sysu.dao;
        import com.sysu.entity.Student;
        
        import java.util.List;
        public interface StudentDao {
            public List<Student> selectStudents();
        }
        
    • 5.创建一个mybatis使用的配置文件:sql映射文件(一个xml文件,文件内容如下),然后在映射文件中写sql语句,一般一个表对应一个sql映射文件。

      • xml文件应该创建在接口所在的目录中,同时最好保证文件名称和接口名字一致。

      • <!--
            sql映射文件:用于写sql语句的,mybatis会执行这些sql语句。
            1.指定约束文件
                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:命名空间,namespace对应的值必须使用dao接口的全限定名称
              <mapper namespace="dao接口对应的全限定名称">
        
            4.在xml文件中,可以使用特定的标签来表示数据库中的特定操作。
              <select>:表示执行查询操作
                <select id = "接口中对应的方法名称" resultType="sql语句执行结果的对象类型对应的全限定名称">
              <update>:表示更新数据库的操作
              <insert>:表示插入
              <delete>:表示删除
        
            5.namespace与id就是帮助MyBatis框架定位sql语句对应的方法,所以需要使用dao接口的全限定名。
        -->
        
        <?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.sysu.dao.StudentDao">
            <select id="selectStudents" resultType="com.sysu.domain.Student">
                select id,name,email,age from student order by id
            </select>
        </mapper>
        
    • 6.创建mybatis的主配置文件:主配置文件提供了数据库的连接信息和sql映射文件的位置信息,一般一个项目对应一个主配置文件。配置文件内容如下:

      • <!--
            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>根标签,该标签通常包括两部分:
                <environments>:数据库的连接信息
                <mappers>:sql映射文件的位置(相对于main/java而言)
        -->
        
        <?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的值必须与其中一个的<environment id="">相同-->
            <environments default="development">
                <environment id="development">
                    
                    <transactionManager type="JDBC"/>
        <!--    transactionManager用于定义提交事务、回滚事务的方式。type有两种取值:
        		(1)JDBC:表示mybatis底层调用JDBC中的Connection对象进行事务的处理
        		(2)MANAGED:将mybatis的事务处理委托给其他容器(例如spring等)-->
                    
                    <dataSource type="POOLED">
        <!--    type:指定数据连接的类型
        		(1)POOLED:使用连接池
        		(2)UNPOOLED:不使用连接池,每次执行sql语句都新建连接,执行完sql语句后在关闭连接。-->
                        <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 resource="com/sysu/dao/StudentDao.xml"/>
            </mappers>
        </configuration>
        
    • 7.获取SqlSession对象,通过它的方法执行sql语句。

      • public class myapp {
            public static void main(String[] args) throws IOException {
                //1.定义mybatis主配置文件的名称,从类路径开始(target/classes),如果target/classes路径下没有mybatis.xml,则说明mvn compile命令执行不完善,可以手动将mybatis.xml文件复制一份到target/classes目录下。
                //通常情况下都会把12345这五个步骤封装至utils中。
                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.从SqlSessionFactory对象中获取SqlSession对象,可以根据openSession()传入的参数自定义是否自动提交事务,openSession(true)表示自动提交事务。
                SqlSession sqlSession = factory.openSession();
                
                //67本质是StudentDao接口中selectStudents()方法的实现,该部分代码在后期可以省略,因为根据MyBatis动态代理可以达到同样的效果。
                //6.【自定义】指定要执行的sql语句标识
                String sqlId = "com.bjpowernode.dao.StudentDao.selectStudents";
                //7.【自定义】执行sql语句,得到执行结果
                List<Student> studentList = sqlSession.selectList(sqlId);
                for(Student st : studentList) System.out.println(st);
                sqlSession.close();
                //上述代码执行查询操作,当执行insert、update、delete等操作时候一定要主动提交事务,否则数据库中的数据不改变.
                //sqlSession.commit();
         ------------------------------------------------------------------------------
                
                //动态代理的实现方式如下:
                //StudentDao dao = sqlSession.getMapper(StudentDao.class);
                //List<Student> students = dao.selectStudents();
                //for(Student student : students) System.out.println(student);
            }
        }
        

    第七个步骤 “获取SqlSession对象,通过它的方法执行sql语句",该步骤有两种实现方式:

    • 传统Dao开发模式:实现StudentDao接口中的方法,并使用这些方法对数据库进行操作。
    • MyBatis动态代理模式(必须掌握):MyBatis动态代理可以让我们省去实现StudentDao接口中的方法这一步骤,它会直接定位到映射文件 mapper 中的相应 SQL 语句,对DB进行操作。底层是通过反射进行实现的。
    //动态代理的实现方式如下:
    获取SqlSession对象
    SqlSession sqlSession = factory.openSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Student> students = dao.selectStudents();
    for(Student student : students) System.out.println(student);
    

    2.2 MyBatis Insert操作(使用动态代理)

    MyBatis初始化的时候比较麻烦,日后在和数据库打交道就比较简单了。

    • 1.在dao接口中定义操作数据库的方法(只需要声明方法即可)
    package com.sysu.dao;
    import com.sysu.entity.Student;
    import java.util.List;
    
    public interface StudentDao {
        public List<Student> selectStudents();
        //定义insert插入方法,该方法只有一个参数Student,所以在sql映射文件中不需要写parameterType=”“参数
        //如果方法中有多个参数需要使用@Param命名参数(见3.3.2)
        public int insertStudent(Student student);
    }
    
    • 2.在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">
    <mapper namespace="com.sysu.dao.StudentDao">
        <select id="selectStudents" resultType="com.sysu.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>
    
    • 3.获取SqlSession对象,通过MyBatis动态代理实现对数据库的访问与操作。
    package com.sysu;
    import com.sysu.entity.Student;
    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;
    import java.util.List;
    
    public class myapp {
        public static void main(String[] args) throws IOException {
            //通常把下面4个步骤封装至utils包中,用于获取SqlSession对象
            String config = "mybatis.xml";
            InputStream in = Resources.getResourceAsStream(config);
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = builder.build(in);
         	
            //获取SqlSession对象
            SqlSession sqlSession = factory.openSession();
    
            //创建需要插入的student对象
            Student student = new Student();
            student.setId(1003);
            student.setName("王五");
            student.setEmail("ddd@qq");
            student.setAge(35);
            
            //Mybatis动态代理
            StudentDao dao = sqlSession.getMapper(StudentDao.class);
            int ans = dao.insertStudent(student);
            System.out.println(ans);
        }
    }
    

    3.MyBatis框架Dao代理(※)

    3.1 实现步骤

    实现步骤见2.1和2.2。或者见下图

    3.2 实现原理

    动态代理。

    有关动态代理的内容见链接:动态代理

    https://www.cnblogs.com/jia0504/p/13811424.html

    3.3 MyBatis相关参数的理解

    (1)parameterType

    <?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.sysu.dao.StudentDao">
        
        <select id="selectStudentById" parameterType="int" resultType="com.sysu.entity.Student">
            select id,name,email,age from student where id = #{id}
        </select>
        
    </mapper>
    

    parameterType表示StudentDao接口中方法参数的数据类型。parameterType不是强制的,mybatis通过反射机制能够发现接口参数的数据类型。所以可以没有。一般我们也不写。

    例如StudentDao接口中存在方法:public Student selectStudentById(Integer id),则 parameterType="int"

    在sql映射文件中,可以通过#{“任意字符”}获取简单类型的一个参数的值。例如通过#{id}获取selectStudentById(Integer id)方法中传入的id值。
    实现原理如下:首先需要知道MyBatis就是对JDBC的一个封装
    (1) MyBatis创建Connection以及PreparedStatement对象
    	String sql = “select id,name,email,age from student where id = ?”
    	PreparedStatement pst = conn.preparedStatement(sql);
    	// 一个问好就相当于一个占位符,setInt传入第一个参数
    	pst.setInt(1,1001);
    	
    (2) 执行sql封装为Student对象。
        Resultset rs = ps.executeouery();student student = null;
        while(rs.next()){
        	//从数据库取表的一行数据,存到一个java对象属性中ltudent = new student();
        	student.setId(rs.getInt("id));
        	student.setName(rs.getstring( "name" ));
        	student.setEmail(rs.getstring( "email"));
        	student.setAge(rs.getInt("age"));
        }
        return sfudent;
    当我们在sql映射文件中写sql语句时,底层的实现原理就如(1)(2)两个步骤,所以可以认为MyBatis就是对JDBC进行了封装。
    

    (2)@Param命名参数

    在sql映射文件中,有两种常用的方法可以获取多个参数的值。

    • @Param命名参数获取多个参数的值

      使用方法:在dao接口声明的方法中加入@Param(“自定义参数名称”),然后在sql映射文件使用#{“自定义参数名称”}。

      例如dao接口存在selectMulitParam()方法:
      步骤一:public List selectMulitParam(@Param("myname") String name, @Param("myage") Integer age)
      步骤二:对应sql映射文件为:

    • 通过传递类型为Java对象的参数来获取多个参数的值(其实insert的sql语句就是采用这种方式)

    使用方法:在dao接口声明的方法中加入Java对象,然后在sql映射文件使用#{“对象的属性名”}。
    步骤一:public List<Student> selectMulitParam(Student)
    步骤二:对应sql映射文件为:
    <select>
    	select * from student where name=#{name} or age=#{age}
    </select>
    

    3.4 #和$的区别

    首先需要明白:在sql映射文件中无论是使用“#”还是“$",都能正常工作!!

    #:占位符,告诉mybatis使用实际的参数值代替。并使用PrepareStatement对象执行sql语句,#{"自定义字符"}代替 sql 语句的“?”

    这样做更安全,更迅速,通常也是首选做法。

    sql映射文件
    <select id="selectById" resultType = "com.sysu.entiy.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}
    

    $:主要用于替换表名或者列名。具体实例如下:

    1.dao接口文件中声明方法:
    List<Student> selectUse$Order(@Param("colName") String colName);
        
    2.sql映射文件写sql语句
    <select id="selectUse$Order" resultType = "com.sysu.entiy.Student">
        select * from student order by ${colName}
    </select>
    
    3.MyBatis动态代理实现与数据库的交互
    SqlSession sqlSession = MyBatisUtils.getSqlSesson();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    // 根据name这一列的属性值进行排序
    List<Student> students = dao.selectUse$Order("name")
    

    两者的区别如下:

    1. #使用?在sql语句中做占位符, 使用PreparedStatement执行sql,效率高。能避免sql注入,更安全。
    2. $不使用占位符,表示字符串的连接,使用Statement对象执行sql,效率低。有sql注入的风险,缺乏安全性。
    3. $主要用于替换表名或者列名,一般在数据需要根据某个列属性进行排序的场景下使用。
    

    3.5 MyBatis的输出结果

    MyBatis的输出结果为Java对象,MyBatis通过使用resultType以及resultMap两种参数让MyBatis明白sql语句执行结果需要转换的对象类型。

    (1) resultType

    表示sql语句的执行结果需要转换的Java对象类型。

    public Student selectStudentById(@Param("id") Integer id);
    
    <!-- resultType=Student,表示sql语句的执行结果需要转换为Student对象 -->
    <select id="selectStudentById" parameterType="int" resultType="com.sysu.entity.Student(Student类型的全限定名称)">
        select id,name,email,age from student where id = #{id}
    </select>
    
    • resultType的值可以看成是dao接口中方法的返回类型。它的值有两种:1. 类型的全限定名称(推荐)。 2. 类型的别名, 例如 java.lang.Integer别名是int
    • 实现原理:把同名列的值赋给resultType中指定对象的同名属性,例如:查询结果id列的值赋给Student中的id属性,name列的值赋给Student中的name属性。这一过程是通过对象的get、set方法实现的,因此对象中一定要实现get、set方法。
    public List<Student> selectStudents();
        
    <select id="selectStudents" parameterType="int" resultType="com.sysu.entity.Student">
        select id,name,email,age from student
    </select>
        
    这种情况下resultType不能等于List,因为列值id,name,email,age这些是Student对象的属性,而不是List对象的属性。
    

    (2) resultMap

    MyStudent类的定义
    class MyStudent{
    	Integer Myid;
    	String Myname;
    	String Myemail;
    	Integer Myage;
    }
    
    dao接口中定义的方法:public List<MyStudent> selectStudents();
        
    sql映射文件:
    <select id="selectStudents" parameterType="int" resultType="com.sysu.entity.MyStudent">
        select id,name,email,age from student
    </select>
    

    当列名(id,name,email,age)和对象中的属性名(Myid、Myname、Myemail、Myage)不一样时,使用resultType将会得到null的对象,解决方案:

    • 使用别名
    修改sql映射文件
    <select id="selectStudents" parameterType="int" resultType="com.sysu.entity.MyStudent">
        select id as Myid, name as Myname, email as Myemail, age as Myage from student
    </select>
    
    • 使用resultMap

    resultMap可以自定义sql执行结果的列名对象中的属性名之间映射关系。常用在列名和 java 对象属性名不一样的情况。

    使用方式: 
    1.在sql映射文件中定义resultMap,指定列名和属性的对应关系。
    <!-- 创建 resultMap
     id:自定义的唯一名称,在<select>使用
     type:期望转为的 java 对象的全限定名称或别名 
    -->
    <resultMap id="MyStudentMap" type="com.sysu.entity.MyStudent">
     	<!-- 主键字段使用 id -->
        <!-- 将id列的值映射至对象中的Myid属性 -->
     	<id column="id" property="Myid" />
     	<!--非主键字段使用 result-->
        <!-- 将name列的值映射至对象中的Myname属性 -->
     	<result column="name" property="Myname"/>
        <result column="email" property="Myemail"/>
     	<result column="age" property="Myage" />
    </resultMap>
    
    2.在中把 resultType 替换为 resultMap。
    <!--resultMap: resultMap 标签中的 id 属性值-->
    <select id="selectUseDiffResultMap" resultMap="MyStudentMap">
     	select id,name,email,age from student where name=#{queryName} or age=#{queryAge}
    </select>
    

    3.6 like模糊查询

    MyBatis有两种方式实现like模糊查询

    • 1. java代码中给查询数据加上“%” (最常用)
    接口方法:
    List<Student> selectLikeFirst(String name);
    
    sql映射文件(mapper文件):
    <select id="selectLikeFirst" resultType="com.sysu.entity.Student">
        <!-- #{}:表示dao接口中对应的方法需要传入一个参数 -->
     	select id,name,email,age from student where name like #{studentName}
    </select>
    
    测试方法:
    @Test
    public void testSelectLikeOne(){
        String name="%李%";
        List<Student> stuList = studentDao.selectLikeFirst(name);
        for(Student stu : stuList) ystem.out.println(stu);
    }
    
    • 2.在mapper文件sql语句的条件位置加上“%”
    接口方法:
    List<Student> selectLikeSecond(String name);
        
    mapper 文件:
    <select id="selectLikeSecond" resultType="com.sysu.entity.Student">
     	select id,name,email,age from student where name like "%" #{studentName} "%"
    </select>
        
    测试方法:
    @Test
    public void testSelectLikeSecond(){
         String name="李";
         List<Student> stuList = studentDao.selectLikeSecond(name);
         for(Student stu : stuList) ystem.out.println(stu);
    }
    

    4.MyBatis框架动态SQL(※)

    动态sql: sql的内容是变化的,可以根据条件获取到不同的sql语句。主要是where部分发生变化。MyBatis主要通过这三个常用标签实现动态sql:<if><where><foreach>

    4.1 if 标签

    <if>标签用于条件判断,当条件判断为true时,会将其包含的sql片段拼接到其所在的sql语句中。

    <if test = "条件">
    	部分sql语句
    </if>
    
    
    1.dao接口声明的方法如下:
    public List<Student> selectStudentIf(Student student);
        
    2.sql映射文件内容如下:
    <!-- 
    	<if test = "使用参数Java对象的属性值作为判断条件,所以要使用动态sql,dao接口方法中传入的参数必须是Java对象">
    -->
    <select id = "selectStudentIf" resultType = "com.sysu.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>
    
    3.test测试
    @Test
    public void testSelectStudentIf(){
    	SqlSession sqlSession = MyBatisUtils.getSqlSession();
        Student dao = sqlSession.getMapper(StudentDao.class);
        
        Student student = new Student();
        student.setName("abc");
        student.setAge(18);
        List<Student> students = dao.selectStudentIf(student);
        for(Student stu:students) System.out.println(stu);
    }
    此代码段的含义为:在数据中查找所有名字为“abc”或者年龄大于18的数据。
    

    4.2 where标签

    • <if>标签的中存在一个比较麻烦的地方:需要在 where 后手工添加 1=1 的子句。因为,若where后的所有条件均为 false,而 where 后若又没有 1 = 1 子句,则 SQL 中就会只剩下一个空的 where,SQL出错。所以,在where后,需要添加永为真子句1 = 1,以防止这种情况的发生。但当数据量很大时,会 严重影响查询效率。
    • 通过使用<where>标签可以避免产生此类问题,<where>标签通常用来包含多个<if>标签,当多个<if>标签中有一个成立的, <where>会自动增加一个where关键字,并去掉<if>标签中sql语句多余的and ,or等。当没有<if>标签成立,则不会添加where子句。
    <where>
    	<if test=""></if>
        <if test=""></if>
    </where>
    
    dao接口声明的方法:
    List<Student> selectStudentWhere(Student student);
    
    sql映射文件
    <select id="selectStudentWhere" resultType="com.sysu.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>
        
    测试方法:
    @Test
    public void testSelectWhere() throws IOException {
         SqlSession sqlSession = MyBatisUtils.getSqlSession();
         Student dao = sqlSession.getMapper(StudentDao.class);
             
         Student param = new Student();
         param.setName("abc");
         param.setAge(18);
         List<Student> studentList = studentDao.selectStudentWhere(param);
         for(Student stu:students) System.out.println(stu);
    }
    此代码段的含义为:在student表中查找所有名字为“abc”或者年龄大于18的数据。如果两个条件都不满足,则输出student表中的全部数据。
    

    4.3 foreach标签

    • <foreach>标签用于实现对于数组与集合的遍历,一般用于dao接口文件中声明的方法的传入参数为数组或者集合。
    • 主要用在sql的in语句中。 select * from student where id in (1001,1002,1003)
    使用语法:
    <foreach collection="" item="" open="" close="" separator="">
    	#{item的值}
    </foreach>
    
    collection:表示接口中的方法参数的类型,如果是数组使用array, 如果是list集合使用list,集合的大小用			list.size()表示。
    item:自定义的,表示数组和集合成员的变量
    open:循环开始的字符
    close:循环结束的字符
    separator:集合成员之间的分隔符
    因为foreach一般用于sql中的in语句,所以open="("	close=")"	separator=","
    

    遍历List<简单类型>

    需求:输出学生id为1002,1005,1006的学生信息。
    
    接口方法:
    List<Student> selectStudentForList(List<Integer> idList);
        
    sql映射文件
    <select id = "selectStudentForList" resultType = "com.sysu.entity.Student">
    	select id,name,email,age from student
        <if test="list != null and list.size() > 0">
        	where id in
            <foreach collection="list" item="stu" open="(" close=")" separator=",">
            	#{stu}
            </foreach>
        </if>
    </select>    
    
    测试方法:
    @Test
    public void testSelectForList() {
         SqlSession sqlSession = MyBatisUtils.getSqlSession();
         Student dao = sqlSession.getMapper(StudentDao.class);
        
         List<Integer> list = new ArrayList<>();
         list.add(1002);
         list.add(1005);
         list.add(1006);
         List<Student> studentList = studentDao.selectStudentForList(list);
         for(Student stu:students) System.out.println(stu);
    }
    

    遍历List<对象类型>

    需求:输出学生id为1002,1005的学生信息。
    
    接口方法:
    List<Student> selectStudentForList(List<Student> idList);
        
    sql映射文件
    <select id = "selectStudentForList" resultType = "com.sysu.entity.Student">
    	select id,name,email,age from student
        <if test="list != null and list.size() > 0">
        	where id in
            <foreach collection="list" item="stu" open="(" close=")" separator=",">
            	#{stu.id}
            </foreach>
        </if>
    </select>    
    
    测试方法:
    @Test
    public void testSelectForList() {
         SqlSession sqlSession = MyBatisUtils.getSqlSession();
         Student dao = sqlSession.getMapper(StudentDao.class);
        
         List<Student> list = new ArrayList<>();
         Student s1 = new Student();
         s1.setId(1002)
         list.add(s1);
         
         s1 = new Student();
         s1.setId(1005);
         list.add(s1);
    
         List<Student> studentList = studentDao.selectStudentForList(list);
         for(Student stu:students) System.out.println(stu);
    }
    

    4.4 sql标签

    • <sql>标签用于定义 SQL 片断,以便其它SQL标签可以复用定义好的片段。
    • 其它标签使用该 SQL 片断,需要使用<include>标签。
    • <sql>标签可以定义 SQL 语句中的任何部分,所以子标签可以放在动态 SQL 的任何位置。
    先定义:<sql id="自定义名称唯一"> 可以是sql语句、表名、字段名等 </sql>
    再使用:<include refid="id的值"/>
    
    接口方法:
    List<Student> selectStudentSqlFragment(List<Student> stuList);
        
    sql映射文件:
    <!--创建 sql 片段 id:片段的自定义名称-->
    <sql id="studentSql">
    	select id,name,email,age from student
    </sql>
        
    <select id="selectStudentSqlFragment" resultType="com.sysu.entity.Student">
         <!-- 引用 sql 片段 -->
         <include refid="studentSql"/>
         <if test="list !=null and list.size > 0 ">
             where id in
             <foreach collection="list" open="(" close=")" item="stuobject"separator=",">
             	#{stuobject.id}
             </foreach>
         </if>
    </select>
        
    测试方法:
    @Test
    public void testSelectForList() {
         SqlSession sqlSession = MyBatisUtils.getSqlSession();
         Student dao = sqlSession.getMapper(StudentDao.class);
        
         List<Student> list = new ArrayList<>();
         Student s1 = new Student();
         s1.setId(1002)
         list.add(s1);
         
         s1 = new Student();
         s1.setId(1005);
         list.add(s1);
    
         List<Student> studentList = studentDao.selectStudentForList(list);
         for(Student stu:students) System.out.println(stu);
    }
    借助sql标签输出学生id为1002,1005的学生信息。
    

    5.MyBatis配置文件(了解)

    MyBatis有两种配置文件:主配置文件以及sql映射文件(mapper文件)

    5.1 主配置文件

    <!--
        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>根标签,该标签通常包括两部分:
            <environments>:数据库的连接信息
            <mappers>:sql映射文件的位置(相对于main/java而言)
    -->
    
    <?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的值必须与其中一个的<environment id="">相同-->
        <environments default="development">
            <environment id="development">
                
                <transactionManager type="JDBC"/>
    <!--    transactionManager用于定义提交事务、回滚事务的方式。type有两种取值:
    		(1)JDBC:表示mybatis底层调用JDBC中的Connection对象进行事务的处理
    		(2)MANAGED:将mybatis的事务处理委托给其他容器(例如spring等)-->
                
                <dataSource type="POOLED">
    <!--    type:指定数据连接的类型
    		(1)POOLED:使用连接池
    		(2)UNPOOLED:不使用连接池,每次执行sql语句都新建连接,执行完sql语句后在关闭连接。-->
                    <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>
            <!--加载sql映射文件,方式一(主流):-->  
            <mapper resource="com/sysu/dao/StudentDao.xml"/>
            <!--方式二(了解):可以加载com.sysu.dao包中的所有sql映射文件-->  
            <packge name="com.sysu.dao"/>
        </mappers>
    </configuration>
    

    主配置文件一般放在resourcs目录下,且命名为xxx.xml。主配置文件的具体内容可以见2.1

    主配置文件特点:

    • 主配置文件中<configuration>之间的标签都是有序的,且<configuration>为根标签

      • <property>:指定属性配置文件的位置

      • <typeAliases>:配置别名

      • <plugins>:配置插件

      • <environments>:定义数据源

      • <mappers>:定义sql映射文件的位置

    • 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"
    

    属性配置文件的书写

    数据库的属性配置文件: 把数据库连接信息放到一个单独的文件中。 和mybatis主配置文件分开。目的是便于修改,保存,处理多个数据库的信息。

    (1) 在resources目录中定义一个属性配置文件,xxxx.properties,例如 jdbc.properties。在属性配置文件中进行数据的定义,格式是key = value。
    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql//.....
    jdbc.username=root
    jdbc.password=123456
    
    (2) 在mybatis的主配置文件中,使用<property>指定属性配置文件的位置,然后在需要使用的地方利用${key}进行值的引入。
    

    5.2 sql映射文件

    详细内容见2.1即可。

  • 相关阅读:
    DAS存储未死,再次欲获重生
    Minimum edit distance(levenshtein distance)(最小编辑距离)初探
    AC自己主动机
    手动脱UPX 壳实战
    edge中断分析
    ubuntu默认的Python版本号修改
    Linux 下 pushd,popd,cd- 用法
    目标检测算法的历史及分类
    openjtag 的硬件连接踩坑历程
    ubuntu 16.04 python版本切换(python2和python3)
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/14869026.html
Copyright © 2011-2022 走看看