zoukankan      html  css  js  c++  java
  • Mybatis(3)-基于代理Dao实现CRUD操作

    1、根据id查询

      我们根据上述步骤可以搭建Mybatias环境,我们在搭建好的基础上来进行代理DAO实现增删改查的操作。

      (1)在持久层接口添加findById方法

    /**
         * 根据id查询用户
         * @param userId
         * @return
         */
        User findById(Integer userId);

      (2)在用户配置文件中配置

    <!-- resultType 属性:用于指定结果集的类型;parameterType 属性:用于指定传入参数的类型;sql 语句中使用#{}字符:它代表占位符,相当于原来 
            jdbc 部分所学的?,都是用于执行语句时替换实际的数据。 -->
        <select id="findById" resultType="com.xhbjava.domain.User"
            parameterType="int">
            select * from user where id = #{uid}
        </select>

     (3)编写Junit测试类并添加测试代码

    package com.xhbjava.test;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    import com.xhbjava.dao.IUserDao;
    import com.xhbjava.domain.User;
    
    /**
     * 测试类
     * 
     * @author Mr.wang
     * @date 2020年1月7日
     */
    public class MybatisJunitTest {
        InputStream in = null;
        SqlSessionFactory factory = null;
        SqlSession session = null;
        IUserDao userDao = null;
    
        @Test
        public void testFindOne() {
            // 6.执行查询操作
            User user = userDao.findById(1);
            System.out.println(user);
        }
    
        @Before
        public void init() throws IOException {
            // 1.读取配置文件
            in = Resources.getResourceAsStream("SqlMapConfig.xml");
            // 2.创建构建者
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            // 3.创建session工厂
            factory = builder.build(in);
            // 4.创建session对象
            session = factory.openSession();
            // 5.创建Dao的代理对象
            userDao = session.getMapper(IUserDao.class);
        }
    
        @After // 在测试方法执行完成之后执行
        public void destroy() throws Exception {
            session.commit();
            // 7.释放资源
            session.close();
            in.close();
        }
    
    }

    2、保存操作

    (1)持久层接口中添加保存方法

      

    /**
         * 保存用户
         * @param user
         * @return
         */
        int saveUser(User user);
    (2)在用户的映射配置文件中配置保存方法
    <!-- 保存操作 -->
        <insert id="saveUser" parameterType="com.xhbjava.domain.User">
            insert into
            user(username,birthday,sex,address)
            values(#{username},#{birthday},#{sex},#{address})
    
        </insert>

      关于细节:

      #{}中内容的写法,由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称它用的是 ognl 表达式。语法格式 #{对象.对象},#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.而直接写 username。

    (3)测试类中添加测试方法

    @Test
        public void testSave() {
            User user = new User();
            user.setUsername("张三");
            user.setAddress("北京");
            user.setSex("男");
            user.setBirthday(new Date());
            userDao.saveUser(user);
            System.out.println("保存:"+user);
        }

      测试发现id=null,那我们要显示id,需要做以下处理。

       由于id是数据库自增实现,所以我们需要在新增后将自动增长长 auto_increment 的值返回。

    <insert id="saveUser" parameterType="USER">
    <!-- 配置保存时获取插入的 id -->
    <selectKey keyColumn="id" keyProperty="id" resultType="int">
    select last_insert_id();
    </selectKey>
    insert into user(username,birthday,sex,address) 
    values(#{username},#{birthday},#{sex},#{address})
    </insert>

    3、用户更新

      (1)在持久层接口中添加更新方法

    /**
         * 更新用户
         * 
         * @param user
         * @return
         */
        int updateUser(User user);

    (2)在用户的映射配置文件中配置更新方法

    <!-- 更新用户 -->
    <update id="updateUser" parameterType="com.itheima.domain.User">
    update user set username=#{username},birthday=#{birthday},sex=#{sex},
    address=#{address} where id=#{id}
    </update>

    (3)添加测试方法

    @Test
    public void testUpdateUser()throws Exception{
    //1.根据 id 查询
    User user = userDao.findById(52);
    //2.更新操作
    user.setAddress("北京市顺义区");
    int res = userDao.updateUser(user);
    System.out.println(res);
    }

    (4)执行测试方法

    4、用户删除

    (1)在持久层接口中添加删除方法

           /**
         *根据用户id删除用户
         * @param userid
         * @return
         */
        int deleteUser(Integer userid);    

    (2)在用户映射配置文件中配置

            <!-- 删除用户操作 -->
        <delete id="deleteUser" parameterType="java.lang.Integer">
            delete from user where id = #{uid}
        </delete>    

    (3)测试类中添加删除测试方法

    @Test
        public void testDeleteUser(){
            int res = userDao.deleteUser(5);
            System.out.println(res);
        }

    5、用户模糊查询

    (1)持久层接口中添加模糊查询方法

    /**
         * 根据用户名模糊查询
         * 
         * @param name
         * @return
         */
        List<User> findUserByName(String name);

    (2)在用户映射文件中添加配置

            <!-- 根据姓名模糊查询 -->
        <select id="findUserByName" resultType="com.xhbjava.domain.User" parameterType="String">
            select * from user where username like #{username}
        </select>

    (3)测试方法中添加测试

            @Test
        public void testFindUserByName() {
            List<User> users = userDao.findUserByName("张%");
            for(User user:users) {
                System.out.println(user);
            }
        }    

    (4)执行测试单元

    模糊查询另一种配置方式

    (5)在用户映射文件中修改配置

    <!-- 根据姓名模糊查询 -->
        <select id="findUserByName" resultType="com.xhbjava.domain.User" parameterType="String">
            <!-- select * from user where username like #{username} -->
            select * from user where username like '%${value}%'
        </select>

    (6)测试类中修改代码

    @Test
        public void testFindUserByName() {
            List<User> users = userDao.findUserByName("张");
            for(User user:users) {
                System.out.println(user);
            }
        }

    (7)#{}与${}的区别

    #{}表示一个占位符号,将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号;#方式能够很大程度防止sql注入,$方式无法防止Sql注入。${}表示拼接 sql 串,$将传入的数据直接显示生成在sql中;$方式一般用于传入数据库对象,例如传入表名和列名,还有排序时使用order by动态参数时需要使用$ ,ORDER BY ${columnName};一般能用#的就别用$,若不得不使用“${xxx}”这样的参数,要手工地做好过滤工作,来防止sql注入攻击。在MyBatis中,“${xxx}”这样格式的参数会直接参与SQL编译,从而不能避免注入攻击。但涉及到动态表名和列名时,只能使用“${xxx}”这样的参数格式。所以,这样的参数需要我们在代码中手工进行处理来防止注入。

    6、查询使用聚合函数

    (1)在持久层接口中添加查询方法

    /**
         * 查询总记录数
         * @return
         */
        int findTotal();

    (2)在用户映射文件中配置

    <!-- 查询总记录数 -->
        <select id="findTotal" resultType="int">
            select count(*) from user
        </select>

    (3)添加测试方法并测试

           @Test
        public void testFindAll() {
            int res = userDao.findTotal();
            System.out.println(res);
        }
     
  • 相关阅读:
    巧用nginx屏蔽对用户不可见的文件
    关于之前我的主页页面加载很慢的问题
    学习Entity Framework 中的Code First
    理解POCO
    浅谈依赖注入
    从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构
    ASP.NET Identity V2
    泛型约束
    C# Serializable
    C#可扩展编程之MEF学习笔记(一):MEF简介及简单的Demo
  • 原文地址:https://www.cnblogs.com/xhbJava/p/12197684.html
Copyright © 2011-2022 走看看