04.SSM框架集~Mybatis(二)

04.SSM框架集~Mybatis(二)

本文是上一篇文章的后续,详情点击该链接

       在上一篇文章中,我们简单介绍了一下Mybatis,和Mybatis的最基本使用。那么今天我们就来学习一下Mybatis基于代理模式的开发和动态SQL

Mapper代理:

       前面已经使用Mybatis完成了对Student表的最基本操作,实现了MyBatis的入门。

但是却存在如下缺点:

       1:不管是selectList()、selectOne()、selectMap(),都是通过SQLSession对象的API完成增删改查,都只能提供一个查询参数。如果要多个参数,需要封装到JavaBean或者Map中,并不一定永远是一个好办法。

       2:返回值类型较固定

       3:只提供了映射文件,没有提供数据库操作的接口,不利于后期的维护扩展。在MyBatis中提供了另外一种成为Mapper代理(或称为接口绑定)的操作方式。在实际开发中也使用该方式。

       下面我们就是要Mapper代理的方式来实现对Student表的CRUD操作吧。相比而言,增加了接口StudentMapper。但是却会引起映射文件和测试类的变化。

首先我们回到mybatis.xml,修改配置
    <mappers>
        <!--  通过包扫描的形式加载所有的接口和映射文件  -->
        <package name="com.alvin.mapper"/>
    </mappers>

       这样一来,不管将来新增了多少个mapper映射文件,只要都在这个包下,就无需重复去写

       (关于SqlSessionUtil类以及一些配置和jar包,详情请点击最上方链接,看我上一篇文章的内容。)

优点:

       有接口 模块之间有规范了

       参数的处理多样了,接口中的方法参数列表由我们自己决定

       通过代理模式由mybatis提供接口的实现类对象 我们不用写实现类了

使用Mapper代理方式实现查询

       需求:查询全部学生信息

准备接口和mapper映射文件
public interface StudentMapper {
    //查询全部学生信息
    List<Student> FindAll();
}
<?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.alvin.mapper.StudentMapper">
    <!--  这里的id必须和对应的方法名相同  -->
    <select id="FindAll" resultType="student">
        select * from student;
    </select>
</mapper>

       接口的名字必须和映射文件名字相同!

public class Test {
    public static void main(String[] args){
        //查询全部学生信息
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        // 帮助我们生成一个接口下的实现类对象的
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 接收数据
        List<Student> list = studentMapper.FindAll();
        //关闭sqlSession
        sqlSession.close();
        //遍历结果
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

关于Mapper代理的增删查改操作

创建好接口:
public interface StudentMapper {
    //查询全部学生信息
    List<Student> FindAll();

    //增加学生信息
    int Insert(Student student);

    //删除学生信息
    int delete(String son);

    //修改学生信息
    int change(Student student);
    
    //查询单个学生信息
    Student FindByOn(String son);
}

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="com.alvin.mapper.StudentMapper">
    <!--  这里的id必须和对应的方法名相同  -->
    <select id="FindAll" resultType="student">
        select * from student;
    </select>

    <!--  增,删,改 返回值默认为int,所以这里就没有resultType参数  -->
    <insert id="Insert">
                                <!--  这里的参数名建议最好和实体类里面的变量对应! -->
        insert into student value(#{son},#{realname},#{password},#{classname},#{score});
    </insert>

    <!--  修改学生信息 -->
    <update id="change">
        update student  set realname = #{realname}, password = #{password},classname = #{classname},score = #{score} where son = #{son};
    </update>

    <!--  删除学生信息 -->
    <delete id="delete">
        delete from student where son = #{son}
    </delete>

    <!--  查找学生信息 -->
    <select id="FindByOn" resultType="student">
        select * from student where son = #{son};
    </select>

</mapper>

Java代码
public class Test {
    public static void main(String[] args){
        //Insert();
       // Del();
        //FindAll();
        //Update();
        Find();
    }

    //查询全部学生信息
    public static void FindAll(){
        //查询全部学生信息
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        // 帮助我们生成一个接口下的实现类对象的
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 接收数据
        List<Student> list = studentMapper.FindAll();
        //关闭sqlSession
        sqlSession.close();
        //遍历结果
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

    //新增学生信息
    public static void Insert(){
                                    //当执行增删改时,就需要提交True,否则无法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //需要新增的信息
        Student student = new Student("666666","黄贵根","666666","信息工程学院",533.0);
        //调用新增
        int n = studentMapper.Insert(student);
        //关闭sqlSession
        sqlSession.close();
        //处理结果
        String str = n > 0 ? "新增成功!" : "新增失败!";
        System.out.println(str);
    }

    //修改学生信息
    public static void Update(){
        //当执行增删改时,就需要提交True,否则无法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //需要修改的信息
        Student student = new Student("666666","黄贵根","123456","信息工程学院",600.0);
        //调用修改
        int n = studentMapper.change(student);
        //关闭sqlSession
        sqlSession.close();
        //处理结果
        String str = n > 0 ? "修改成功!" : "修改失败!";
        System.out.println(str);
    }

    //删除学生信息
    public static void Del(){
        //当执行增删改时,就需要提交True,否则无法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //调用删除
        int n = studentMapper.delete("666666");
        //关闭sqlSession
        sqlSession.close();
        //处理结果
        String str = n > 0 ? "删除成功!" : "删除失败!";
        System.out.println(str);
    }

    //查找学生信息
    public static void Find(){
        //查询操作则无需提交
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //调用查询
        Student student  = studentMapper.FindByOn("154787");
        //关闭sqlSession
        sqlSession.close();
        //处理结果
        String str = student != null ? student.toString() : "没找到!";
        System.out.println(str);
    }
}

模糊查询:

接口:
    //模糊查询
    List<Student> getByName( String realname);
Mapper映射
   <!-- 模糊查询  -->
    <select id="getByName"  resultType="student" >
        select * from student where realname like concat('%',#{realname},'%')
    </select>
Java代码
public static void main(String[] args) {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //查询姓名包含张的学生
        List<Student> students = mapper.getByName("张");
        //遍历
        Iterator iterator = students.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        sqlSession.close();
    }

       好了,关于Mapper代理这一块的基本知识,暂时先学到这里,现在让我们来了解一下动态SQL

动态SQL

       经常遇到很多按照很多查询条件进行查询的情况,比如智联招聘的职位搜索,比如OA系统中的支出查询等。其中经常出现很多条件不取值的情况,在后台应该如何完成最终的SQL语句呢?

       如果采用JDBC进行处理,需要根据条件是否取值进行SQL语句的拼接,一般情况下是使用StringBuilder类及其append方法实现,还是有些繁琐的。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

       MyBatis在简化操作方法提出了动态SQL功能,将使用Java代码拼接SQL语句,改变为在XML映射文件中截止标签拼接SQL语句。相比而言,大大减少了代码量,更灵活、高度可配置、利于后期维护。

       MyBatis中动态SQL是编写在mapper.xml中的,其语法和JSTL类似,但是却是基于强大的OGNL表达式实现的。

       MyBatis也可以在注解中配置SQL,但是由于注解功能受限,尤其是对于复杂的SQL语句,可读性很差,所以较少使用。

Where和IF标签

       通过if处理用户多变的查询条件

接口
public interface StudentMapper {
	//登录实现
    Student Login(Student student);
}
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="com.alvin.mapper.StudentMapper">
    <select id="Login" resultType="student">

        select * from student
        <where>
            <if test="son != null">
                and son= #{son}
            </if>
            <if test="realname != null and realname != ''">
                and realname= #{realname}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
            <if test="classname != null ">
                and classname = #{classname}
            </if>
            <if test="score != null ">
                and score = #{score}
            </if>
        </where>
    </select>
</mapper>
Java代码
public static void Login(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student();
        //输入账号和密码
        student.setSon("666666");
        student.setPassword("666666");
        Student stu = mapper.Login(student);
        //处理结果
        String string = stu != null ? "登陆成功!欢迎您: " + stu.getRealname() : "登陆失败!";
        System.out.println(string);
    }

Choose When标签

在刚刚的标签里面进行修改

<?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.alvin.mapper.StudentMapper">
    <select id="Login" resultType="student">

        select * from student
        <where>
        <choose>
                <when test="son != null">
                    and son= #{son}
                </when>
                <when test="realname != null and realname != ''">
                    and realname= #{realname}
                </when>
                <when test="password != null and password != ''">
                    and password = #{password}
                </when>
                <when test="classname != null ">
                    and classname = #{classname}
                </when>
                <when test="score != null ">
                    and score = #{score}
                </when>
        </choose>
        </where>
    </select>
</mapper>

       特点:前面的when条件成立 后面的 when就不再判断了

Set标签

修改案例

接口
 int update(Student student);
Mapper映射
 <update id="update" >
        update student
        <set>
            <if test="realname != null and realname != ''">
                realname= #{realname},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="classname != null ">
                classname = #{classname},
            </if>
            <if test="score != null ">
                score = #{score},
            </if>
        </set>
        where  son = #{son}
    </update>
Java
public static void Update(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student();
        //修改后的数据
        Student stu = new Student("666666","黄贵根","654321","信息工程学院",666.0);
        int n = mapper.update(stu);
        //处理结果
        String string = n > 0 ? "修改成功!" : "修改失败!";
        System.out.println(string);
        //关闭
        sqlSession.close();
    }

Trim标签

处理set

<update id="update" >
        <!--prefix      要增加什么前缀
        prefixOverrides 要去除什么前缀
        suffix          要增加什么后缀
        suffixOverrides 要去除什么后缀
        set 和where是   trim的一种特殊情况
        -->
        update student
        <trim prefix="set" suffixOverrides=",">
            <if test="realname != null and realname != ''">
                realname= #{realname},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="classname != null ">
                classname = #{classname},
            </if>
            <if test="score != null ">
                score = #{score},
            </if>
        </trim>
        where  son = #{son}
    </update>
处理where
    <select id="Login" resultType="student">
        select * from student
        <trim prefix="where" prefixOverrides="and">
            <if test="son != null">
                and son= #{son}
            </if>
            <if test="realname != null and realname != ''">
                and realname= #{realname}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
            <if test="classname != null ">
                and classname = #{classname}
            </if>
            <if test="score != null ">
                and score = #{score}
            </if>
        </trim>
    </select>

Sql片段标签

案例: 根据指定字段查询

接口
    List<Student> FindAll();
Mapper
    <!--  将字段包含 -->
    <sql id="data">
        son,realname,password,classname,score
    </sql>
    <!--  调用 -->
    <select id="FindAll" resultType="student">
        select <include refid="data"/> from student;
    </select>

Java

    public static void main(String[] args) {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> list = studentMapper.FindAll();
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

       好了!今天我们就学到这里吧,我们下期再见~

猜你喜欢

转载自blog.csdn.net/qq_41424688/article/details/106614171
今日推荐