MyBatis框架入门(二)

目录

6.深入理解参数

6.1 parameterType

6.2 传入一个简单参数

6.3 多个参数---使用@Param

6.4 多个参数---使用对象

6.5 多个参数---按位置

6.6 多个参数---使用Map

6.7 #和$

7.封装MyBatis输出结果

7.1 resultType的使用

7.2 resultMap的使用

7.3 列名和属性名不同的两种解决方式

7.4 模糊查询like两种方式


6.深入理解参数

   把数据传入到mapper文件的sql语句中。

6.1 parameterType

   parameterType:接口中方法参数的类型,值是java数据类型的完全限定名或者是mybatis定义的别名。这个属性是可选的,因为Mybatis可以推断出具体传入语句的参数,默认值为未设置(unset)。接口中方法的参数从java代码转入到mapper文件的sql语句。

   parameterType不是强制的,mybatis可以通过反射机制能够发现接口参数的数据类型。

public interface StudentDao {
    public Student selectStudentById(Integer id);
}
<select id="selectStudentById" parameterType="java.lang.Integer" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{id}
</select>
public class TestMyBatis {
    @Test
    public void testSelectStudentById(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student = dao.selectStudentById(1002);
        System.out.println(student);
    }
}

6.2 传入一个简单参数

   mybatis把java的基本数据类型及其包装类和String类型叫做简单类型。

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

   使用#{}之后,mybatis执行sql是使用的jdbc中的PreparedStatement对象。由mybatis执行下面的代码:

        ①mybatis创建Connection、PreparedStatement对象;

                String sql = "select id,name,email,age from studeng where id=?";

                PreparedStatement ps = conn.preparedStatement(sql);

                ps.setInt(1,1001);

        ②执行sql封装为"com.bjpowernode.domain.Student"这个类的对象;

                ResultSet rs = ps.executeQuery();

                Student student = null;

                while(rs.next()){

                        //从数据库取表的一行数据,存到一个java对象属性中

                        student = new Student();

                        student.setId(rs.getInt("id"));

                        student.setName(rs.getInt("name"));

                        student.setEmail(rs.getInt("email"));

                        student.setAge(rs.getInt("age"));

                }

                return student;//给了dao方法调用的返回值

6.3 多个参数---使用@Param

   使用@Param("自定义参数名称"),放在形参的前面。

public interface StudentDao {
    /**
     * 多个参数:命名参数,在形参的前面加入@Param("自定义参数名称")
     */
    List<Student> selectMultiParam(@Param("myname") String name,@Param("myage") Integer age);
}
<!--多个参数,使用@Param命名-->
<select id="selectMultiParam" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
public class TestMyBatis {
    @Test
    public void testSelectMulitParam(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = dao.selectMultiParam("李四",20);
        for(Student student : students){
            System.out.println(student);
        }
        sqlSession.close();
    }
}

6.4 多个参数---使用对象

   使用java对象传递参数,java的属性值就是sql需要的参数值,每一个属性就是一个参数。

   语法格式:#{属性名,javaType=类型名称,jdbcType=数据类型}

        javaType:指java中的属性数据类型

        jdbcType:指数据库中的数据类型

        这种语法格式很少使用。

   我们使用简化方式:#{属性名},javaType、jdbcType的值mybatis可以通过反射获取,不用自己手动提供。

package com.bjpowernode.vo;

public class QueryParam {

    private String paramName;
    private Integer paramAge;

    public String getParamName() {
        return paramName;
    }

    public void setParamName(String paramName) {
        this.paramName = paramName;
    }

    public Integer getParamAge() {
        return paramAge;
    }

    public void setParamAge(Integer paramAge) {
        this.paramAge = paramAge;
    }

    @Override
    public String toString() {
        return "QueryParam{" +
                "paramName='" + paramName + '\'' +
                ", paramAge=" + paramAge +
                '}';
    }
}
public interface StudentDao {
    /**
     * 多个参数,使用java对象作为接口中方法的参数
     */
    List<Student> selectMultiObject(QueryParam param);

    List<Student> selectMultiStudent(Student student);
}

<!--
<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{paramName,javaType=java.lang.String,jdbc=VARCHAR}} or
                                                    age=#{paramAge,javaType=java.lang.Integer,jdbc=INTEGER}}
</select>
-->

<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{paramName} or age=#{paramAge}
</select>

<select id="selectMultiStudent" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{name} or age=#{age}
</select>
public class TestMyBatis {
    @Test
    public void testSelectMulitObject(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        QueryParam queryParam = new QueryParam();
        queryParam.setParamName("李四");
        queryParam.setParamAge(20);
        List<Student> students = dao.selectMultiObject(queryParam);
        for(Student student : students){
            System.out.println(student);
        }
        sqlSession.close();
    }

    @Test
    public void testSelectMulitStudent(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student = new Student();
        student.setName("李四");
        student.setAge(20);
        List<Student> students = dao.selectMultiStudent(student);
        for(Student stu : students){
            System.out.println(stu);
        }
        sqlSession.close();
    }
}

6.5 多个参数---按位置

public interface StudentDao {
    /**
     * 多个参数-简单类型的,按位置传值
     * mybatis.3.4之前,使用#{0},#{1}
     * mybatis.3.4之后,使用#{arg0},#{arg1}
     */
    List<Student> selectMultiPosition(String name,Integer age);
}
<!--多个参数使用位置-->
<select id="selectMultiPosition" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{arg0} or age=#{arg1}
</select>
public class TestMyBatis {
    @Test
    public void testSelectMulitPosition(){
        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();
    }
}

6.6 多个参数---使用Map

public interface StudentDao {
    /**
     * 多个参数,使用Map存放多个值
     */
    List<Student> selectMultiMap(Map<String,Object> map);
}
<!--多个参数,使用Map,使用语法#{map的key}-->
<select id="selectMultiMap" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{myName} or age=#{myAge}
</select>
public class TestMyBatis {
    @Test
    public void testSelectMulitMap(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Map<String,Object> data = new HashMap<>();
        data.put("myName","李四");
        data.put("myAge",20);
        List<Student> students = dao.selectMultiMap(data);
        for(Student stu : students){
            System.out.println(stu);
        }
        sqlSession.close();
    }
}

6.7 #和$

   #占位符。告诉mybatis使用实际的参数值代替,并且使用PreparedStatement对象执行sql语句,#{...}代替了sql语句的"?"。这样做可以避免sql注入现象,更安全,更迅速,通常也是首选做法。

   $字符串替换。告诉mybatis使用$包含的"字符串"替换所在位置。使用Statement对象把sql语句和${}的内容连接起来。可能存在sql注入现象。主要用在替换表名、列名、不同列排序等操作。

<!--
     $替换列名
-->
<select id="selectUse$Order" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student order by ${colName}
</select>

   #和$的区别

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

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

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

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

        ⑤$可以替换表名或者列名

7.封装MyBatis输出结果

7.1 resultType的使用

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

   1.返回简单类型:可以返回mybatis定义的类型的别名,或者返回类的全限定名称。建议使用全限定名称。

int countStudent();
<!--返回简单类型,mybatis定义的类型的别名或全限定名称都可以-->
<!--<select id="countStudent" resultType="int">-->
<select id="countStudent" resultType="java.lang.Integer">
    select count(*) from student
</select>
@Test
public void testRetunInt(){
    int count = studentDao.countStudent();
    System.out.println("学生总人数:"+ count);
}

   2.返回对象类型

public Student selectStudentById(Integer id);
<select id="selectStudentById"  resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where id=#{id}
</select>
@Test
public void testSelectStudentById(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    Student student = dao.selectStudentById(1002);
    System.out.println(student);
}

   执行过程:

        ①mybatis执行sql语句,然后mybatis调用类的无参构造方法,创建对象;

        ②mybatis把ResultSet中的列值赋给同名的对象属性。

   可以定义自定义类型的别名

        ①在mybatis主配置文件中定义,使用<typeAlias>定义别名;

        ②可以在resultType中使用自定义的别名。

        比如自定义了一个类ViewStudent。最好还是使用全限定名称,最准确。

<!--自定义别名-->
<typeAliases>
    <!--
        第一种方式:
            可以指定一个类型一个自定义别名
            type:自定义类型的全限定名称
            alias:别名(短小,容易记忆)

        <typeAlias type="com.bjpowernode.domain.Student" alias="stu"></typeAlias>
        <typeAlias type="com.bjpowernode.vo.ViewStudent" alias="vstu"></typeAlias>
    -->

    <!--
        第二种方式:
            <package> name是包名,这个包中的所有类,类名就是别名(类名不区分大小写)
    -->
        <package name="com.bjpowernode.domain"/>
        <package name="com.bjpowernode.vo"/>
</typeAliases>
<!--selectStudentReturnViewStudent-->
<!--<select id="selectStudentReturnViewStudent" resultType="vstu">-->
<select id="selectStudentReturnViewStudent" resultType="viewstudent">
    select id,name,email,age from student where id=#{sid}
</select>

   3.返回Map。sql的查询结果作为Map的key和value。推荐使用Map<Object,Object>。注意:Map作为接口返回值,sql语句的查询结果最多只能有一条记录,大于一条记录是错误的。如果要查找多条记录,其实就相当于返回了一个集合,集合内元素的类型是Map<Object,Object>。

//定义方法返回Map
Map<Object,Object> selectMapById(Integer id);
<!--
    返回Map
        1)列名是map的key,列值是map的value
        2)只能最多返回一行记录,多于一行会发生异常
-->
<select id="selectMapById" resultType="java.util.HashMap">
    select id,name from student where id=#{id}
</select>
@Test
public void testSelectMap(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    Map<Object,Object> map = dao.selectMapById(1001);
    System.out.println(map);
}

7.2 resultMap的使用

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

   使用方式:

        ①先定义resultMap,指定列名和属性名的对象关系;

        ②在<select>中把resultType替换为resultMap。

/**
* 使用resultMap定义映射关系
*/
List<Student> selectAllStudents();
<!--
    使用resultMap
        1)先定义resultMap
        2)在select标签,使用resultMap来引用1定义的。
-->
<!--
    定义resultMap
        id:自定义名称,表示你定义的这个resultMap
        type:java类型的全限定名称
-->
<resultMap id="studentMap" type="com.bjpowernode.domain.Student">
    <!--列名和java属性的关系-->
    <!--
        主键列,使用id标签
        column:列名
        property:java类型的属性名
    -->
    <id column="id" property="id"/>
    <!--非主键列使用result-->
    <result column="name" property="name"/>
    <result column="email" property="email"/>
    <result column="age" property="age"/>
</resultMap>
    
<select id="selectAllStudents" resultMap="studentMap">
    select id,name,email,age from student
</select>
@Test
public void testSelectAllStudents(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Student> students = dao.selectAllStudents();
    for(Student student : students){
        System.out.println(student);
    }
    sqlSession.close();
}

7.3 列名和属性名不同的两种解决方式

   1.使用resultMap。

   2.使用列别名,将别名取为java对象的属性名。

   推荐使用第一种方式。

7.4 模糊查询like两种方式

   1.在java代码中指定like的内容。(推荐方式)

//第一种模糊查询,在java代码中指定like的内容
List<Student> selectLikeOne(String name);
<!--第一种like,java代码中指定like的内容,推荐这种方式-->
<select id="selectLikeOne" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name like #{name}
</select>
@Test
public void testSelectLikeOne(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Student> students = dao.selectLikeOne("李%");//java代码中指定
    for(Student student : students){
        System.out.println(student);
    }
    sqlSession.close();
}

   2.在mapper文件中进行字符串拼接。其中#{}两边的空格必须有

//第二种模糊查询,name就是"李"值,在mapper中拼接 like "%" 李 "%"
List<Student> selectLikeTwo(String name);
<!--第二种like,在mapper文件中拼接like的内容-->
<select id="selectLikeTwo" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name like "%" #{name} "%"
</select>
@Test
public void testSelectLikeTwo(){
    SqlSession sqlSession = MyBatisUtils.getSqlSession();
    StudentDao dao = sqlSession.getMapper(StudentDao.class);
    List<Student> students = dao.selectLikeTwo("李");
    for(Student student : students){
        System.out.println(student);
    }
    sqlSession.close();
}

PS:根据动力节点课程整理,如有侵权,联系删除。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值