20201118黄春跃

20201118黄春跃

知识点

基于代理 Dao 实现 CRUD 操作

根据 ID 查询

在持久层接口中添加 findById 方法

在用户的映射配置文件中配置

<select id="findAll" resultMap="userMap">
    select * from userinfo]
</select>

resultType 属性:用于指定结果集的类型。
parameterType 属性:用于指定传入参数的类型

{}:它代表占位符,相当于原来 jdbc 部分所学的 ? ,都是用于执行语句时替换实际的数据。具体

的数据是由#{}里面的内容决定的。#{}中是变量
如果此方法只有一个参数,占位符可以写成#{value},也可以写成变量名#{id}

在测试类添加测试

保存操作

在持久层接口中添加新增方法
int saveUser(UserInfoModel user);
在用户的映射配置文件中配置
<insert id="saveUser" parameterType="com.itlaobing.mybatis.model.UserInfoModel" >
        insert into userinfo(id,username,password,name,gender,birthday,phone,email)values(#{id},#{username},#{password},#{name},#{gender},#{birthday},#{phone},#{email})
</insert>

parameterType 属性:代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的
全名称。
sql 语句中使用#{}字符:它代表占位符,相当于原来 jdbc 部分所学的 ? ,都是用于执行语句时替
换实际的数据。具体的数据是由#{}里面的内容决定的。

{}中内容的写法:由于我们保存方法的参数是 一个 UserInfoModel 对象,此处要写

UserInfoModel 对象中的属性名称。它用的是 ognl 表达式。

添加测试类中的测试方法
@Test
    public void testSave(){
    UserInfoModel user = new UserInfoModel();
    user.setId("11");
    user.setUsername("aaa");
    user.setPassword("123123");
    user.setName("韩立");
    user.setGender(1);
    user.setBirthday(new Date());
    user.setPhone("138xxxxxxxx");
    user.setEmail("123@qq.com");
    System.out.println("保存操作之前:"+user);
    //5.执行保存方法
    int row = userDao.saveUser(user);
    System.out.println("保存操作之后:"+user);
    System.out.println("影响行数:" + row);

运行后。。。

但是,我们打开 Mysql 数据库发现并没有添加任何记录,为什么呢?

因为mybatis默认自动提交事务是关闭的,因此,我们在实现增删改时一定要去控制事务的提交,那么
在mybatis 中如何控制事务提交呢?使用session.commit()方法
在测试用例中添加如下代码:

    //提交事务
    session.commit();
    //7.释放资源
    session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

新增用户 id 的返回值

新增用户后,同时还要返回当前新增用户的 id 值,如果 id 是由数据库的自动增长来实现的,所以就相
当于我们要在新增后将自动增长 auto_increment 的值返回。

在持久层接口中添加新增方法
int saveUserTest(Model2 user);
在用户的映射配置文件中配置
<insert id="saveUserTest" parameterType="com.itlaobing.mybatis.model.Model2" useGeneratedKeys="true" keyProperty="id">
        insert into test(name)values (#{name})
</insert>

useGeneratedKeys : 表示是否返回主键
keyProperty = "xxx" 将值赋给哪个属性,这个属性是方法参数中的

添加测试类中的测试方法
@Test
public void saveUserTest() {
    Model2 user = new Model2();

    user.setName("黄十");

    int row = userDao.saveUserTest(user);
    System.out.println("影响行数:" + row);
    session.commit();
    System.out.println(user);//在事务提交后在查看,不然id就是null
    //7.释放资源
    session.close();
    try {
        in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

用户更新

在持久层接口中添加更新方法
int updateUser(UserInfoModel user);
在用户的映射配置文件中配置
<update id="updateUser" parameterType="com.itlaobing.mybatis.model.UserInfoModel">
        update userinfo set username = #{username},password = #{password},birthday = #{birthday},gender = #{gender} where id = #{id}
    </update>
加入更新的测试方法
@Test
public void testUpdateUser() {
    UserInfoModel user = userDao.findById("11");
    user.setUsername("bbb");
    user.setPassword("159753");
    int rows = userDao.updateUser(user);
    System.out.println(rows);
    session.commit();
    //7.释放资源
    session.close();
    try {
        in.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

更新前:

更新后(执行测试方法后)

用户删除

在持久层接口中添加删除方法
int deleteUser(String id);
在用户的映射配置文件中配置
<delete id="deleteUser" parameterType="String">
        delete from userinfo where id = #{id}
    </delete>

加入删除的测试方法
@Test
    public void testDeleteUser() {
        int res = userDao.deleteUser("12");
        System.out.println(res);
        session.commit();
        //7.释放资源
        session.close();
        try {
            in.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

删除前:

删除后(执行测试方法后)

用户模糊查询

在持久层接口中添加模糊查询方法
List<Model2> findByName(String username);
在用户的映射配置文件中配置
<select id="findByName" parameterType="String" resultType="com.itlaobing.mybatis.model.Model2">
    <!-- 方法一select * from test where username like #{username} -->
        select * from test where name like '%${value}%'
    </select>

我们在上面将原来的#{}占位符,改成了\({value}。注意如果用模糊查询的这种写法,那么\){value}的写
法就是固定的,不能写成其它名字

测试代码:
@Test
    public void testFindByName() {
        //方法一对应的查询方法 List<UserInfoModel> users = userDao.findByName("%黄%");
        List<Model2> user = userDao.findByName("黄");
        for(Model2 u : user){
            System.out.println(u);

        }
    }

对比数据库:

#{}与${}的区别

{}表示一个占位符号

通过#{}可以实现 preparedStatement 向占位符 ? 中设置值,自动进行 java 类型和 jdbc 类型转
换,#{}可以有效防止 sql 注入。 #{}可以接收基本类型值或 pojo 属性值。 如果 parameterType
传输单个基本类型值,#{}括号中可以是 value 或其它名称。
\({}表示拼接 sql 串
通过\){}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换, \({}可以接收基
本类型值或 pojo 属性值,如果 parameterType 传输单个基本类型值,\){}括号中只能是 value。

查询使用聚合函数

在持久层接口中添加模糊查询方法
int findTotal();
在用户的映射配置文件中配置
<select id="findTotal" resultType="int">
    select count(*) from test
</select>
加入聚合查询的测试方法
@Test
public void testFindTotal(){
    int total = userDao.findTotal();
    System.out.println(total);
}

传递 pojo 包装对象

VO有两种说法,一是ValueObject,二是View Object,它的作用是把某个指定页面的所有数据封装起
来,一个VO对象中可以对应数据库中的多张表。PO(persistant object)是持久对象,PO类与表对
应,PO类中的属性与表的列对应。

编写VO
package com.itlaobing.model;
import lombok.Data;
@Data
public class QueryVo {
  private UserInfoModel user;
}
编写持久层接口
 List<UserInfoModel> findByVo(QueryVo vo);
持久层接口的映射文件
<select id="findByVo" resultType="com.itlaobing.mybatis.model.UserInfoModel" parameterType="com.itlaobing.mybatis.model.QueryVo">
        select * from userinfo where username like #{user.username}
    </select>
测试包装类作为参数
@Test
    public void testFindByQueryVo() {
    QueryVo vo = new QueryVo();
    UserInfoModel user = new UserInfoModel();
    user.setUsername("%a%");
    vo.setUser(user);
    List<UserInfoModel> users = userDao.findByVo(vo);
    for(UserInfoModel u : users) {
        System.out.println(u);
        }
    }

总结:

晚自习把今天敲的代码从头到尾看了一下,然后看了些数据库的基础知识

评论