zoukankan      html  css  js  c++  java
  • mybatis学习——基于代理 Dao 实现 CRUD 操作

    使用要求: 

      1、持久层接口和持久层接口的映射配置必须在相同的包下 

      2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名 

      3、SQL 语句的配置标签<select>,<insert>,<delete>,<update>的 id 属性必须和持久层接口的 方法名相同。

    在持久层接口中添加 findById 、saveUser、updateUser、deleteUser、findByName、findTotal方法

    public interface IUserDao {
        /**
         * 根据id查询
         */
        User findById(Integer uid);
        /**
         * 保存用户
         */
        void saveUser(User user);
        /**
         * 更新用户
         */
        void updateUser(User user);
        /**
         * 根据id删除用户
         */
        void deleteUser(Integer uid);//这里的返回值类型是void还是int,影响不大,同上
        /**
         * 根据名称模糊查询
         */
        List<User> findByName(String username);
        /**
         * 查询总记录条数
         */
        int findTotal();
    
    }

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

    <?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.churujianghudezai.dao.IUserDao">
        <!--这里的id值直接和接口里的方法名对应-->
        <!--根据id查询-->
        <select id="findById" parameterType="int" resultType="com.churujianghudezai.domain.User">
            select * from user where id = #{uid}
        </select>
    
        <!--保存用户,并返回保存后该用户对应的id-->
        <insert id="saveUser" parameterType="com.churujianghudezai.domain.User">
            <!--配置时保存获取插入的id
             AFTER:此语句在插入语句之后执行 (可不写)
             keyColumn="id":keyColumn用于指定数据库表user中的主键(可不写)
             keyProperty="id": 此语句返回值要传递给当前方法参数中的id属性 (com.churujianghudezai.domain.User的id属性)(不可省)
             resultType=“int”: 此语句执行后的返回类型是 int
             keyProperty和resultType必不可少,且要相互对应才行-->
            <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
                select last_insert_id();
            </selectKey>
            insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
        </insert>
    
        <!--更新用户,这里以更新用户名为例-->
        <update id="updateUser" parameterType="com.churujianghudezai.domain.User">
            update user set username=#{username} where id=#{id}
        </update>
    
        <!--删除用户-->
        <delete id="deleteUser" parameterType="int">
            delete from user where id = #{id}
        </delete>
    
        <!--根据名称模糊查询-->
        <select id="findByName" resultType="com.churujianghudezai.domain.User" parameterType="String">
            select * from user where username like #{username}/* 此处也可以写成 like '%${value}%' */
        </select>
    
        <!--查询总记录条数-->
        <select id="findTotal" resultType="int">
            select count(*) from user
        </select>
    
    </mapper>

    细节: 

    resultType 属性:  

      用于指定结果集的类型。 当结果类型为实体类时,这就要求该类中的属性名与数据库表中字段名保持一致(可以不区分大小写)(请看下一章博客内容:mybatis参数深入)

    parameterType 属性:

      用于指定传入参数的类型,需要注意的是:

       1.若参数类型写成User类,那么该参数名得要写成该类中对应的属性名,如:

             parameterType="com.churujianghudezai.domain.User"      update user set username=#{username} where id=#{id} 这里id不能写成userid、uid,username不能写成name等

        它用的是 ognl 表达式。 

        ognl 表达式:它是 apache 提供的一种表达式语言,全称是:Object Graphic Navigation Language  对象图导航语言   它是按照一定的语法格式来获取数据的。  

        (语法格式就是使用  #{对象.对象}的方式 :#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用 getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user. 而直接写 username。)

       2.若参数类型是基本数据类型或String,则参数名可以随意起,如:

        parameterType="int"      select * from user where id = #{uid}   这里参数类型定义的是int,不是User,所以该参数名可以随便起,如userid等

        (因为这条是查询语句,有返回结果,且该结果类型为user类,这就要求该类中属性名与数据表中字段名一致)

    sql 语句中使用#{}字符:  

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

    #{}与${}的区别: 
      #{}表示一个占位符号  通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换, #{}可以有效防止 sql 注入。 #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类 型值,#{}括号中可以是 value 或其它名称。

      ${}表示拼接 sql 串  通过${}可以将 parameterType 传入的内容拼接在 sql中且不进行 jdbc 类型转换, ${}可以接收简 单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,${}括号中只能是 value。

    在测试类添加测试

    public class MybatisCRUDTest {
        private InputStream in;
        private SqlSessionFactory factory;
        private SqlSession session;
        private IUserDao userDao;
    
        @Test
        public void testFindOne(){
            //6.执行操作
            User user = userDao.findById(41);
            System.out.println(user);
        }
    
        @Test
        public void testSaveUser(){
            User user = new User();
            user.setUsername("赵本山");
            user.setSex("男");
            user.setBirthday(new Date());
            user.setAddress("辽宁铁岭");
            System.out.println("保存操作之前:"+user.getId());
            userDao.saveUser(user);
            //在dao操作完成后,直接调用getId()就可获得用户保存后对应的自增id
            System.out.println("保存操作完成,获得的id为"+user.getId());
        }
    
        @Test
        public void testUpdateUser(){
            User user = userDao.findById(59);
            user.setUsername("小飞侠");
            userDao.updateUser(user);
            user = userDao.findById(59);
            System.out.println(user);
        }
    
        @Test
        public void testDeleteUser(){
            userDao.deleteUser(58);
        }
    
        @Test
        public void testFindByName(){
            /*xml文件中使用%${value}%方式配置时,这里的参数只要写成 “王” 即可*/
            List<User> users = userDao.findByName("%王%");
            for (User user:users){
                System.out.println(user);
            }
        }
    
        @Test
        public void testFindTotal(){
            int num = userDao.findTotal();
            System.out.println(num);
        }
    
        @Before//在测试方法执行前执行
        public void init() throws Exception{
            //1.读取配置文件
            in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.创建构建者对象
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            //3.创建SqlSession工厂对象
            factory = builder.build(in);
            //4.创建SqlSession对象
            session = factory.openSession();
            //5.创建Dao的代理对象
            userDao = session.getMapper(IUserDao.class);
        }
    
        @After//测试方法执行完成之后执行
        public void destroy() throws Exception{
            //7.提交事务
            session.commit();
            //8.释放资源
            session.close();
            in.close();
        }
    }

    Mybatis 与 JDBC 编程的比较

    1.数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

      解决:  在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。

    2.Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

       解决:  将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。

    3.向sql语句传参数麻烦,因为sql语句的where 条件不一定,可能多也可能少,占位符需要和参数对应。

      解决:  Mybatis自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的 类型。

    4.对结果集解析麻烦,sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对 象解析比较方便。

      解决:  Mybatis自动将 sql执行结果映射至 java 对象,通过statement中的resultType 定义输出结果的 类型。

  • 相关阅读:
    近来无聊 写了一个google音乐的下载器
    HTML编辑器 HtmlArea
    Html编辑器 TinyMCE
    IE浏览器自定义地址协议 通过B/S程序中打开C/S程序
    html 元素的 onpropertychange 事件
    asp.net 服务器控件防止重复提交表单
    用 BindingSource 绑定窗体中控件不失去焦点无法更新数据源的问题
    动态创建大量 html dom 元素时提升性能
    很黄的日期格式化。。。
    Asp.net 导出 .html,.txt 等格式的文件
  • 原文地址:https://www.cnblogs.com/churujianghudezai/p/12211547.html
Copyright © 2011-2022 走看看