JAVA框架——MyBatis总结(二)(草稿)参数传入问题,结果返回问题,实体之间的关系问题,模糊查询,动态sql问题

一、参数传入问题

1.一个简单参数

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。

接口方法

Student selectById(Integer id);

mapper 文件

<select id="selectById" resultType="com.aiit.domain.Student">
 select * from student where id=#{id}
</select>

#{id} , id 是自定义的变量名称,和方法参数名无关

测试方法

@Test
public void testSelectById(){
//一个参数
 Student student = studentDao.selectById(1001);
 System.out.println("查询 id 是 1001 的学生:"+student);
}

2.多个参数

方式一:使用@Param

当 Dao 接口方法多个参数,需要通过名称使用参数。

在方法形参前面加入@Param(“自定义参数名”)

接口方法

 /*
    * 多个参数:命名参数,在形参定义的前面加入@param("自定义参数名称")
    * */
    List<Student> selectMulitParam(@Param("myname") String name,@Param("myage") Integer age);

mapper文件

 <select id="selectMulitParam"  resultType="com.aiit.domain.Student">
   select * from student where name=#{myname} or age=#{myage};
</select>

测试方法:

@Test
    public void testSelectMultParam(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        List<Student> students = studentDao.selectMulitParam("宋进锋", 20);
        students.forEach(student -> System.out.println(student));

        sqlSession.close(); }
}

方式二:使用JAVA对象

我们可以书写一个装饰类,里面存放的是我们需要传入的属性

public class QueryParam {
    private String paramName;
    private Integer paramAge;
}

接口方法

	/*
    * 多个参数.使用jave对象作为接口中的方法参数
    * */
    List<Student> selectMultiObject(QueryParam queryParam);

mapper.xml文件

以下由两种写法

    多个参数:使用java对象的属性值,作为参数实际值
    使用对象方法,#{属性名} javaType=类型名称,jdbcType=数据类型
    javaType:指java中属性数据类型
    jdbcType:在数据库中的数据类型
    例如:#{paramName,javaType="java.lang.String",jdbcType=VARCHAR}

    我们使用简化方式:#{属性名}  javaType jdbcType的值mybatis反射能获取。不用提供
<select id="selectMultiObject" resultType="com.aiit.domain.Student">
        select * from student where name=#{paramName,javaType="java.lang.String",jdbcType=VARCHAR}
        or #{paramAge,javaType="java.lang.Integer",jdbcType=INTEGER};
</select>
    <select id="selectMultiObject" resultType="com.aiit.domain.Student">
        select * from student where name=#{paramName}
        or #{paramAge};
    </select>

测试方法

@Test
    public void testSelectMultObject(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        QueryParam param = new QueryParam();
        param.setParamName("张三");
        param.setParamAge(22);
        List<Student> students = studentDao.selectMultiObject(param);
        students.forEach(student -> System.out.println(student));

        sqlSession.close(); }

该处一定要学会灵活运行,我们传入的对象可以是一个Student类,然而他们参数可以是Student类里面的name和age属性

方式三:按照位置传入参数(不推荐)

接口方法

/*
    *  多个参数-简单类型,按照位置传入参数
    *  mybatis 3.4之前,使用#{0} ,#{1}
    *  mybatis 3.4之后,使用#{arg0} ,#{arg1}
    * */
    List<Student> selectMultiPosition(String name,Integer age);

mapper.xml文件

 <select id="selectMultiPosition" resultType="com.aiit.domain.Student">
        select * from student where name=#{arg0}
        or #{arg1};
    </select>

方式四:使用map集合传入参数(不推荐)

接口方法

  /*
    *  多个参数,使用Map存放多个值
    * */
    List<Student> selectMulitByMap(Map<String, Object>map);

测试方法

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

        Map<String, Object> data = new HashMap<>();
        data.put("myname","张三");
        data.put("myage",28);
        List<Student> students = studentDao.selectMulitByMap(data);
        students.forEach(student -> System.out.println(student));

        sqlSession.close(); }
}

mapper.xml配置文件

<select id="selectMultiPosition" resultType="com.aiit.domain.Student">
    select * from student where name=#{myname}
    or #{myage};
</select>

3.# 和 $

1.使用#,可以替换成?

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

#的结果: select id,name, email,age from student where id=?

2.使用$,可以替换成字符串拼接

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

$ 的结果:select id,name, email,age from student where id=1001
也可以写成如下:

String sql="select id,name, email,age from student where id=" + "1001";

# 和 $区别

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

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

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

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

  5. $:可以替换表名或者列名(select * from user order by name)这里的name可以进行值得更改

举例SQL注入问题

如果我们参数传过来的值为:

List<Student> students = dao.selectUser("'李四';drop table student");

因为$是一种字符串的拼接方式,那么当我们传入这种参数的时候,会发生两个语句

select * from student where name ='李四';drop table student;

此时会导致我们的数据库里面删除,用户在输入这些语句的时候,会造成我们的数据库的隐患。

二、结果返回问题

1、resultType结果类型

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

  • resultType结果类型的它值

    • 类型的全限定名称
    • 类型的别名, 例如 java.lang.Integer别名是int
    • 当我们返回值是集合,只要返回的值是< T >当中的泛型即可

案例

接口文件

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

Integer queryCountStudent();

Mapper.xml文件

 <select id="selectMultiParam"  resultType="com.aiit.domain.Student">
       select * from student;
</select>
 <select id="queryCountStudent"  resultType="int">
       select count(*) from student;
</select>

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

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

  • 可以在resultType中使用自定义别名
  • 也可以使用package标签

主配置文件

<typeAliases>
        <!--方式一-->
        <typeAlias type="com.aiit.domain.Student" alias="Student"></typeAlias>
        <!--方式二-->
        <package name="com.aiit.domain"/>
    </typeAliases>

mapper文件

 <select id="selectStudentById"  resultType="Student">
       select * from student where id=#{id};
    </select>

推荐使用全包名的方式,不适用取别名的方式,因为如果我们使用了相同类名的属性,会进行报错

三、ResultMap

概念:其为结果映射,指定列名和java对象的属性对应关系

功能:
1.自定义列值赋值给哪个属性

2.当列名和属性值不一样,一定要使用ResultMap

接口方法

/*
*   使用resultMap定义映射关系
* */
List<Student> selectAllStudents();

mapper.xml文件

 <resultMap id="studentMap" type="com.aiit.domain.Student">
        <!--列名和java属性的关系-->
        <!--主键列,使用id标签
                       column:列名
                       property:java类型的属性名
        -->
        <id column="id" property="id"/>
        <!--非主键列,使用result-->
        <result column="name" property="name"/>
    </resultMap>
    <select id="selectAllStudents" resultMap="studentMap">
        select * from student;
    </select>

注意

  • resultMap标签中id<select>中的resultMap属性的值必须保持一致

  • resultMap中的主键列使用id属性,

  • column:列名

  • property:java类型的属性名

  • 除id之外的属性,使用result标签

四、实体之间的关系

一对一

一对多

五、模糊查询

接口方法

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

mapper.xml文件

<!--第一种like方式-->
    <select id="selectLikeOne" resultType="com.aiit.domain.Student">
        select * from student where name like #{name}
    </select>

测试方法

  @Test
    public void testSelectLikeOne(){

        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao studentDao = sqlSession.getMapper(StudentDao.class);
        String name="%张%";
        List<Student> students = studentDao.selectLikeOne(name);
        students.forEach(student -> System.out.println(student));
        sqlSession.close();
    }

六、动态sql

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

动态sql的实现,使用的是mybatis提供的标签, <if> ,<where>,<foreach>

< if > 标签

1.语法

<if test="判断java对象的属性值">
            部分sql语句
</if>

2.案例

接口方法

List<Student> selectStudentIf(Student student);

mapper.xml文件

 <!--if-->
    <!--<if:test "判断java对象的属性值 语法:属性=XXX值"-->
    <select id="selectStudentIf" resultType="com.aiit.domain.Student">
        select * from student
        where
        <if test="name !=null and  name !=''">
            name =#{name}
        </if>
        <if test="age > 0">
            and age >#{age}
        </if>
    </select>

测试方法:

@Test
    public void testSelectStudentIf(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        StudentDao dao = sqlSession.getMapper(StudentDao.class);
        Student student = new Student();
        student.setName("李四");
        student.setAge(20);
        List<Student> students = dao.selectStudentIf(student);
        students.forEach(s -> System.out.println(s));
        sqlSession.close();
    }

< where >标签

1.概述

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

2.案例

接口方法

List<Student> selectStudentWhere(Student student);

mapper.xml文件

<!--where标签-->
    <select id="selectStudentWhere" resultType="com.aiit.domain.Student">
        select * from student
        <where>
        <if test="name !=null and  name !=''">
            name =#{name}
        </if>
        <if test="age > 0">
            and age >#{age}
        </if>
        </where>
    </select>

where标签可以自动过滤一些有误的sql语句

< foreach>标签

1.概述
<foreach> 循环java中的数组,list集合的。 主要用在sql的in语句中

2.案例

七、代码片段

<sql/>标签用于定义 SQL 片断,以便其它 SQL 标签复用。而其它标签使用该 SQL 片断,需要使用<include/>子标签。该标签可以定义 SQL 语句中的任何部分,所以<include/>子标签可以放在动态 SQL的任何位置

案例

<mapper namespace="com.aiit.dao.StudentDao">
    <!--定义sql片段-->
    <sql id="studentsql">
        select  * from student
    </sql>
    <!--if-->
    <!--<if:test "判断java对象的属性值 语法:属性=XXX值"-->
    <select id="selectStudentIf" resultType="com.aiit.domain.Student">
        <include refid="studentsql"></include>
        where
        <if test="name !=null and  name !=''">
            name =#{name}
        </if>
        <if test="age > 0">
            and age >#{age}
        </if>
    </select>
</mapper>

八、PageHelper

基于 PageHelper 分页:

(1) maven 坐标

<dependency>
 <groupId>com.github.pagehelper</groupId>
 <artifactId>pagehelper</artifactId>
 <version>5.1.10</version>
</dependency>

(2)PageHelper 对象

查询语句之前调用 PageHelper.startPage 静态方法。

除了 PageHelper.startPage 方法外,还提供了类似用法的 PageHelper.offsetPage 方法。

需要进行分页的 MyBatis 查询方法前调用 PageHelper.startPage 静态方法即可,紧跟在这个方法后的第一个 MyBatis 查询方法会被进行分页。

@Test
public void testSelect() throws IOException {
//获取第 1 页,3 条内容
PageHelper.startPage(1,3);
 List<Student> studentList = studentDao.selectStudents();
 studentList.forEach( stu -> System.out.println(stu));
}

九、逆向工程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值