MyBatis框架02

一、Mybatis完成CURD

1.1CURD的R

1.1.1 CRUD的R1

1)在Mapper接口里添加findAll方法

public interface EmployeeMapper {
    List<Employee> findAll();
}

2)在SQL映射文件中添加对应的配置

<select id="findAll" resultType="student">
   select * from emp
</select>

3)执行方法,测试

@Test
public void test3() throws IOException {
   
   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();

   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
   List<Student> students = mapper.findAll();
  
   for (Student student : students) {
      System.out.println(student);
   }

   sqlSession.close();
}

1.1.2 MyBatis获取参数的方式

如果接口里的方法带有参数,那么Mybatis的Sql语句是如何获取参数的呢?Mybatis提供了两种参数占位符,分别是 #{}${}

1)#{}:

相当于JDBC中的问号(?)占位符,是为SQL语句中的参数值进行占位,大部分情况下都是使用#{}占位符;并且当#{}占位符是为字符串或者日期类型的值进行占位时,在参数值传过来替换占位符的同时,会进行转义处理(在字符串或日期类型的值的两边加上单引号);

在mapper文件中: 
	select * from employee where name=#{name}
在程序执行时替换成:	   
	select * from employee where name=?

2)${}

是为SQL片段(字符串)进行占位,将传过来的SQL片段直接拼接在 ${} 占位符所在的位置,不会进行任何的转义处理。(由于是直接将参数拼接在SQL语句中,因此可能会引发SQL注入攻击问题)

需要注意的是:使用 ${} 占位符为SQL语句中的片段占位时,即使只有一个占位符,需要传的也只有一个参数,也需要将参数先封装再传递!mybatis3.5.x后可以不封装。

1.1.3 CRUD的R2

1)在接口里添加findById方法

Student findById(int id);

2)在Sql映射文件中添加对应的配置

<select id="findById" resultType="com.sldl.pojo.Student" resultMap="a">
   select * from student where id = #{id}
</select>

3)测试

@Test
    public void test4() throws IOException {
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);

        SqlSession sqlSession = factory.openSession();

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        Student student = mapper.findById(1);
        System.out.println(student);

        sqlSession.close();
    }

1.2 CRUD的CUD

1.2.1 MyBatis事务

<transactionManager type="JDBC"/>

在核心配置文件中,我们配置了数据源的事务管理方式,要么是JDBC,要么是MANAGED。

  • JDBC: 即利用java.sql.Connection对象完成对事务的提交(commit())、回滚(rollback())等。

  • MANAGED: MyBatis自身不会去实现事务管理,而是让程序的容器如(SPRING)来实现对事务的管理。

MyBatis在进行数据库的增删改(CUD)操作时,就涉及到了事务这个概念。

  • openSession(): 默认开启事务,进行增删改操作后需要使用sqlSession.commit(); 手动提交事务。(推荐使用)

  • openSession(true): 向方法中传入true,表示设置自动提交事务。(不推荐)

1.2.2 CRUD的D

1)在Mapper接口里添加修改方法

void updateEmployee(Employee e);

2)在Sql映射文件中添加对应的update配置

<!--修改员工信息-->
    <update id="updateStudent" parameterType="student">
        update student set
            name = #{name},
            age = #{age},
            gender = #{gender},
            id_card = #{idcard},
            address = #{address}
        where id = #{id}
    </update>

3)测试

  @Test
    public void test5() throws IOException {

        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        SqlSession sqlSession = factory.openSession();

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

        //新创建一个Student类型
        Student s =new Student(1,"张三一",22,"女","220102000011112222", "北京");

        mapper.updateStudent(s);

        //提交操作
        sqlSession.commit();
        //关闭
        sqlSession.close();
    }

1.2.3 CRUD的C

1)在StudentMapper.java里添加如下方法

void addStudent(Student s);

2)在StudentMapper.xml里添加对应的insert配置

<!--添加学生功能-->
<insert id="addStudent" parameterType="student">
    insert into student values (null, #{name},#{age},#{gender},#{idcard},#{address})
</insert>

3)测试

@Test
public void test6() throws IOException {

   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();

   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

   //新创建一个Student类型
   Student s =new Student("老七",22,"女","220102000011113333", "深圳");

   mapper.addStudent(s);

   //提交操作
   sqlSession.commit();
   //关闭
   sqlSession.close();
}

1.2.4 CRUD的D

1)在接口StudentMapper.java里添加如下方法

void delStudent(int id)

2)在映射文件StudentMapper.xml里完善delete标签

<delete id="delStudent">
   delete from student where id = #{id}
</delete>

3)测试

@Test
public void test7() throws IOException {
   //获取SqlSession对象
   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();

   //获取代理对象
   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

   //调用删除方法 删除id为1的记录
   mapper.delStudent(1);

   //增删改的事务会自动开启,因此需要手动提交
   sqlSession.commit();
   sqlSession.close();
}

1.3 多条件CRUD

上面的案例中,接口里方法的形参个数都是1个;如果方法形参是两个或者两个以上时,MyBatis又该如何获取获取参数呢?

Mybatis提供了好几种方式,可以获取多个参数的值

第一种: 使用arg0,arg1…或者param1,param2…来按照参数顺序获取对应的值

//2个或者2个以上的参数
Employee findByCondition1(String username,String password)

接口里的方法与Sql映射文件中的语句进行映射后,并且在调用方法期间,Mybatis会默认将所有传入到方法中的实际参数封装到一个Map对象中,实际参数作为value,按照从左到右的顺序,分别绑定到key名为arg0,arg1…或者param1,param2…上。

因此我们在获取参数时,可以这样写

select...from...where username = #{arg0} and password = #{arg1} .....
或者
select...from...where username = #{param1} and password = #{param2} .....

第二种:Map作为参数

map 集合:只需要保证 SQL 中的参数名和 map 集合的键的名称对应上,即可设置成功

List<Student> findByCondition2(Map<String,Object> map);

第三种:实体类作为参数

实体类封装参数:只需要保证 SQL 中的参数名和实体类属性名对应上,即可设置成功

List<Student> findByCondition1(Student student);

第四种:使用@Param注解命名参数

散装参数:需要使用 @Param (" SQL 中的参数占位符名称")

List<Student> findByCondition1(@Param("id") int id, @Param("name") String name, @Param("address") String address);

2)在StudentMapper.xml里添加对应的select配置

<select id="findByCondition1" resultType="com.shuilidianli.pojo.Student">
   select * from student where id=#{id} and name=#{name} and address=#{address}
</select>

3)测试

 @Test
    public void test1() throws IOException {
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
        SqlSession sqlSession = factory.openSession();

        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//        List<Student> byCondition1 = mapper.findByCondition1(1, "张三一", "北京");
        Student student = new Student(1,"张三一",-1,null,null,"北京");
//        List<Student> byCondition1 = mapper.findByCondition1(student);
        Map<String,Object> map = new HashMap<>();
        //map.put("id",1);
        map.put("name","张三一");
        map.put("address","北京");
        List<Student> byCondition1 = mapper.findByCondition1(map);
        System.out.println(byCondition1);
    }

1.4 动态SQL

SQL语句会随着用户的输入和外部条件的变化而变化,我们称之为动态SQL。MyBatis对动态SQL有很强大的支持。

1.4.1 where/if标签

if标签,是根据test属性中的布尔表达式的值,从而决定是否执行包含在其中的SQL片段。如果判断结果为true,则执行其中的SQL片段;如果结果为false,则不执行其中的SQL片段

 

存在的问题:第一个条件不需要逻辑运算符。

案例演示:

在接口StudentMapper.java里添加如下方法

List<Student> findByCondition(Map map);

在映射文件StudentMapper.xml里配置如下

第一种方案:使用恒等式让所有条件格式都一样

<select id="findByCondition1" >
        select *
        from student
        where 1 = 1
        <if test="id != null">
            and id = #{id}
        </if>
        <if test="name != null and name != '' ">
            and name = #{name}
        </if>
        <if test="address != null and address != '' ">
            and address = #{address}
        </if>
    </select>

第二种方案:使用<where>标签替换where关键字。 注意:where标签会将第一个条件之前的连接符自动去掉

<select id="findByCondition1" >
   select *
   from student
   /* where 1 = 1*/
   <where>
      <if test="id != null">
         and id = #{id}
      </if>
      <if test="name != null and name != '' ">
         and name = #{name}
      </if>
      <if test="address != null and address != '' ">
         and address = #{address}
      </if>
   </where>
</select>

1.4.2 choose/when标签

 

choose(when,otherwise):类似于java的switch-case-default, 只要满足一个when,choose就结束了,如果都不满足,就会执行otherwise。

1)在接口StudentMapper里添加如下方法

List<Student> findByCondition1(Map map);

2)在sql映射文件StudentMapper.xml里添加如下内容

<select id="findByCondition1" >
   select *
   from student
   where
   <choose><!-- 类似于switch-->
      <when test=" id != null"><!-- 类似于case-->
         id = #{id}
      </when>
      <when test=" name != null and name != '' ">
         name = #{name}
      </when>
      <when test=" address != null and address != ''">
         address = #{address}
      </when>
      <otherwise><!-- 类似于default-->
         1 = 1
      </otherwise>
   </choose>
</select>

3)测试

@Test
public void test9() throws IOException {
   //获取SqlSession对象
   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();

   //获取代理对象
   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

   //创建一个map对象
   Map<String,Object> map = new HashMap<>();
   //        map.put("id",2);
   //        map.put("name","小明");
   //        map.put("address","长春朝阳区");

   /*选择map中的一个条件进行查询,*/
   List<Student> students = mapper.findByCondition1(map);

   for (Student student : students) {
      System.out.println(student);
   }

   sqlSession.close();
}

1.4.3 set/if标签

当进行修改时,有些字段可能有选择的进行修改,这时我们就可以使用<set>标签 配合<if>标签来完成操作。set标签会自动将最后一个条件的逗号去掉。

1)在接口StudentMapper里添加如下方法

//修改学生信息
void modifyStudent(Map map);

2)在StudentMapper.xml里添加如下内容

<update id="modifyStudent">
   update student
   <set>
      <if test="name !=null  and name != ''">
         name = #{name},
      </if>
      <if test="age != null and age != '' ">
         age = #{age},
      </if>
      <if test="gender != null and gender != '' ">
         gender = #{gender},
      </if>
      <if test="idcard != null and idcard != '' ">
         idcard = #{idcard},
      </if>
      <if test="address != null and address != '' ">
         address = #{address},
      </if>
   </set>
   where id = #{id}
</update>

3)测试

@Test
public void test10() throws IOException {
   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();
   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

   Map<String,Object> info = new HashMap<>();
   //存储id为2的信息
   info.put("id",2);
   info.put("name","王小二");
   info.put("gender","女");
   info.put("age",23);
   info.put("address","净月区");

   mapper.modifyStudent(info);

   sqlSession.commit();
   sqlSession.close();

}

1.4.4 foreach标签

<foreach>标签的使用, 比如进行集合查询等操作

1)在接口StudentMapper里添加如下方法

List<Student> findByIds(List list);

2)在StudentMapper.xml里添加如下内容

<select id="findByIds" resultType="com.sldl.pojo.Student">
   select *
   from student
   where id in
   <foreach collection="list" separator="," open="(" close=")" item="id">
      #{id}
   </foreach>
</select>

3)测试

@Test
public void test11() throws IOException {
   InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
   SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(stream);
   SqlSession sqlSession = factory.openSession();
   StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

   List<Integer> ids = new ArrayList<>();
   ids.add(1);
   ids.add(2);
   ids.add(3);
   ids.add(4);
   ids.add(5);

   List<Student> byIds = mapper.findByIds(ids);
   for (Student byId : byIds) {
      System.out.println(byId);
   }

   sqlSession.close();

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值