zoukankan      html  css  js  c++  java
  • MyBatis-Day2

    第1章 回顾mybatis的自定义再分析和环境搭建

    自定义开发流程图

     回顾mybatis环境搭建步骤

    第一步:创建 maven 工程 

    新建普通java工程day02_mybatis,在下面新建maven模块day02_eesy_01mybatisCRUD

    第二步:导入坐标

    出的问题,写dependency无提示信息,报红是点击右侧提示选update就有了。然后还是写了以后红波浪,就clean和reimport刷新解决,没有改VM先让它找本地对应有的,明明本地有为啥不自动去找!!

    dependency用了log4j日志工具要把log4j.properties放到res下

    第三步:编写必要代码实体类和持久层接口

     User.java 和 IUserDao接口

    第四步:编写 SqlMapConfig.xml

    需要拷贝一下头部信息粘贴

    第五步:编写映射配置文件IUseDao.xml

    也需要拷贝一下头部信息粘贴

     <!--id映射查询所有方法  resultType="com.xxw.domain.User"写把结果类型-->
    <select id="findAll" resultType="com.xxw.domain.User">
        select * from user;
    </select>

    第六步:编写测试类 MybatisTest

    使用了@Test替代昨天的main方法(就方法名上@Test无需main了直接写就是,每个@Test可以直接运行

    /**
    * 测试查询所有方法(用代理类生成IUserDao接口的的代理对象)
    */
    @Test
    public void testFindAll() throws Exception {
    InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);//builder生成工厂
    SqlSession sqlSession = factory.openSession();//工厂生产sqlSession对象
        IUserDao userDao = sqlSession.getMapper(IUserDao.class);//session获取接口的代理类
    List<User> users = userDao.findAll();

    for(User user:users){
    System.out.println(user);
    }
    sqlSession.close();
    in.close();
    }

    运行查找所有数据输出成功,昨天的环境又重新搭建成功

    第2章 基于代理 Dao 实现 CRUD 操作 

    就还是使用上面那个maven模块day02_eesy_01mybatisCRUD

     开始在中增加对数据库增删改查的方法

    先写一个增加用户保存到数据库的方法,对应的IUserDao接口类增加saveUser抽象方法

    /**
    * 保存用户 插入一条数据
    * @param user
    */
    void saveUser(User user);

    对应的IUserDao.xml增加匹配方法的sql语句

    <!-- 映射保存用户方法 参数类型就是插入数据的类型。插入是一条实体类的数据#号{}号 里面写每一个插入数据实体类对象的属性-->
    <insert id="saveUser" parameterType="com.xxw.domain.User">
        insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
    </insert>

    然后在测试类MybatisTest用@Test注解测试saveUser方法

    由于又要重复获取IUserDao接口代理类的代码操作和释放资源操作(和testFindAll时一样),所以把这两部分代码封装一下并借助@before和@after实现每一个@test之前之后都执行这两部分代码。

    public class MybatisTest {
    
        private InputStream in;
        private SqlSession sqlSession;
        private IUserDao userDao;
    
        @Before//用于在测试方法执行之前执行(把那些重复的构建工厂获取代理的代码放到@before里面)
        public void init()throws Exception{
            //1.读取配置文件,生成字节输入流
            in = Resources.getResourceAsStream("SqlMapConfig.xml");
            //2.获取SqlSessionFactory
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
            //3.获取SqlSession对象
            sqlSession = factory.openSession();
            //4.获取dao的代理对象
            userDao = sqlSession.getMapper(IUserDao.class);
        }
    
        @After//用于在测试方法执行之后执行(重复的释放资源操作)
        public void destroy()throws Exception{
            //提交事务!不然sava没有提交就会自动回滚
            sqlSession.commit();
            //6.释放资源
            sqlSession.close();
            in.close();
        }
    
        /**
         * 测试查询所有
         */
        @Test
        public void testFindAll(){
            //5.执行查询所有方法
            List<User> users = userDao.findAll();
            for(User user : users){
                System.out.println(user);
            }
        }
    
        /**
         * 测试保存操作
         */
        @Test
        public void testSave(){//特别注意:执行方法后要进行提交事务的操作。
            User user = new User();
            user.setUserName("modify User property");
            user.setUserAddress("北京市顺义区");
            user.setUserSex("男");
            user.setUserBirthday(new Date());
            //5.执行保存方法
            userDao.saveUser(user);
        }
    
    }
    MybatisTest.java

    运行结果:表格后面插入了一条49号数据,id是自增的

    更新某条用户数据方法

    IUserDao.xml

    <!--也是和插入一样传入了参数所以要写参数类型-->

    <update id="updateUser" parameterType="com.xxw.domain.User">
    update user set username=#{userName},address=#{userAddress},sex=#{userAex},birthday=#{userBirthday} where id=#{userId}
    </update>

    测试类MybatisTest
    @Test
    public void testUpdate(){

    User user = new User();
    user.setUserId(49);
    user.setUserName("xxw user");
    user.setUserAddress("北京市海淀区");
    user.setUserSex("女");
    user.setUserBirthday(new Date());
    //5.执行更新方法
    userDao.updateUser(user);

    }

    运行结果:49号被重新更新数据了(保存插入只能在最末尾,更新可以任意id更新

    根据id删除某条数据

    IUserDao接口

    /**
    * 根据Id删除用户
    * @param userId
    */
    void deleteUser(Integer userId);

    IUserDao.xml
    <!--根据id删除用户 sql语句中id的#{}里面只是一个占位符,传啥都行反正参数只有一个啥都是该参数-->
    <delete id="deleteUser" parameterType="java.lang.Integer">
    delete from user where id = #{uid}
    </delete>
    测试类MybatisTest
    /**
    * 测试删除操作
    */
    @Test
    public void testDelete(){

    //5.执行删除方法
    userDao.deleteUser(43);

    }

    运行结果:43号数据被删除

    根据id查询用户数据

    IUserDao.xml

    <!--根据id查询用户有传入参数,也有返回值 都要写清楚类型-->
    <select id="findById" parameterType="INT" resultType="com.xxw.domain.User">
    select * from user where id = #{uid}
    </select>
    测试类MybatisTest
    /**
    * 测试根据id查询用户信息操作
    */
    @Test
    public void testFindOne(){
    //5.执行查询一个方法
    User user = userDao.findById(49);
    System.out.println(user);
    }

    运行结果:49号数据查找成功

    根据用户名模糊查询

    IUserDao接口

    /**
    * 根据名称模糊查询用户信息
    * @param username
    * @return
    */
    List<User> findByName(String username);

    IUserDao.xml
    <!--根据名称模糊查询 与id查询的区别是用like代替等号-->
    <select id="findByName" parameterType="string" resultType="com.xxw.domain.User">
    select * from user where username like #{name}
    --     select * from user where username like '%${value}%' 这样写也可以
    </select>
    测试类MybatisTest
    /**
    * 测试模糊查询操作
    */
    @Test
    public void testFindByName(){
    //5.执行查询一个方法
    List<User> users = userDao.findByName("%王%");
    //        List<User> users = userDao.findByName("王"); 这样用对应上面那样写
    for(User user : users){
    System.out.println(user);
    }
    }

    运行结果:成功把数据库中用户名中带王自的行数据查找出来

    聚合函数

    查询总用户数

    IUserDao接口

    /**
    * 查询总用户数
    * @return
    */
    int findTotal();
    
    
    IUserDao.xml
    <select id="findTotal" resultType="int">
    select count(id) from user;
    </select>
    测试类MybatisTest
    /**
    * 测试查询总记录条数
    */
    @Test
    public void testFindTotal(){
    //5.执行查询一个方法
    int count = userDao.findTotal();
    System.out.println(count);
    }

    运行结果:6条

    MybatisCRUD-保存操作的细节-获取保存数据的ID

    sql:select last_insert_id();

    IUserDao.xml
    <!-- 映射保存用户方法 参数类型就是插入数据的类型。插入是一条实体类的数据#号{}号 里面写实体类对象的属性-->
    <insert id="saveUser" parameterType="com.xxw.domain.User">
    <!--增加配置插入操作后,获取插入数据的id-->
    <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER">
    select last_insert_id();
    </selectKey>
    insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday});
    </insert>
    测试类MybatisTest
    /**
    * 测试保存操作
    */
    @Test
    public void testSave(){//特别注意:执行方法后要进行提交事务的操作。
    User user = new User();
    user.setUserName("modify User property");
    user.setUserAddress("北京市顺义区");
    user.setUserSex("男");
    user.setUserBirthday(new Date());
    System.out.println("保存操作之前:"+user);//保存前id是null!!!
    //5.执行保存方法
    userDao.saveUser(user);
    System.out.println("保存操作之后:"+user);//运行结果:插入用户保存后有了该条保存的id!!!!

    第3章 Mybatis 的参数深入

    Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo的属性名称。

    (感觉有点像jsp里的el表达式直接写属性名取值...长得都类似...

    听不太懂,求助同学的博客...

    ParameterType可以传递:

    1.简单类型,int,String等

    2.pojo对象(即javabean)?所以pojo类就是实体类的意思!

    使用ognl表达式解析对象字段的值。如:#{pojo属性名称}

    OGNL表达式:object graphic navigation language,对象图导航语言。通过对象的取值方法来获取数据,在写法上把get省略了。如:user.username。

    开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。 Pojo 类中包含 pojo。 需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中。 (多个查询条件用一个查询条件参数vo对象)

    IUserDao接口

        /**
    * 根据queryVo中的条件查询用户
    * @param vo
    * @return
    */
    List<User> findUserByVo(QueryVo vo);
    }

    3.pojo包装对象

     1.main/java/domain中创建一个QueryVo类,定义一个user类的私有属性,并生成getters&setters:

    public class QueryVo {//查询条件类 是包装User实体类而来
    private User user;

    public User getUser() {
    return user;
    }
    public void setUser(User user) {
    this.user = user;
    }
    }

     2.IUserDao.xml增加

    <!-- 根据queryVo的条件查询用户 参数是一个查询条件类,是包装实体类而成,即把实体类做成属性-->
    <select id="findUserByVo" parameterType="com.xxw.domain.QueryVo" resultType="com.xxw.domain.User">
    select * from user where username like #{user.userName}
    用途就是like这儿可以放表的其他属性?就是用什么属性查数据的时候只需要改这里不需要再去接口写方法?或者别的表别的属性也只需改这儿?个人理解
    </select>

     3.MybatisTest中写测试

        /**
    * 测试使用QueryVo作为查询条件
    */
    @Test
    public void testFindByVo(){
    QueryVo vo = new QueryVo();
    User user = new User();
    user.setUserName("%王%");//百分号是为了模糊
    vo.setUser(user);
    //5.执行查询一个方法
    List<User> users = userDao.findUserByVo(vo);
    for(User u : users){
    System.out.println(u);
    }
    }
    }

    运行结果:模糊查询出3条名字包含王的User类数据

    第4章 Mybatis 的输出结果封装 (结果集的深入)

    由于我的实体类属性名与数据库不匹配,只有userName属性和数据库username列由于window不区分大小写可以被查出来,其他三个属性查出来打印的值都是null...

    User{userId=null, userName='老王', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='小二王', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='传智播客', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='老王', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='小马宝莉', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='xxw user', userAddress='null', userSex='null', userBirthday=null}

    User{userId=null, userName='modify User property', userAddress='null', userSex='null', userBirthday=null}

    但是增删改不影响,在数据库中操作不需要返回数据库中,实体类的属性和数据库列名不一样也可以。

    如何解决查询find出的问题呢?

    1.sql语句中对实体类属性取别名

    比如在IUserDao.xml改findAll的sql:select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;

    2.Mybatis提供一种在IUserDao.xml中配置查询结果的列名和实体类的属性吗的对应关系

     <!--配置 查询结果的列名和实体类的属性名的对应关系 -->
    <resultMap id="userMap" type="com.xxw.domain.User">
    <!-- 主键字段的对应 -->
    <id property="userId" column="id"></id>
    <!--非主键字段的对应-->
    <result property="userName" column="username"></result>
    <result property="userAddress" column="address"></result>
    <result property="userSex" column="sex"></result>
    <result property="userBirthday" column="birthday"></result>
    </resultMap>

    然后resultType不要了改成resultMap

         <!--id映射查询所有方法  resultType="com.xxw.domain.User"写把结果类型-->
    <select id="findAll" resultMap="userMap">改这里!!
    -- select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user;
    select * from user;
    </select>

    其他查询操作也都只要改为resultMap="userMap"就可以,这对于查询操作较多的操作起来方便一些,但效率没有起别名只用改sql高。

    (当然效率最高的还是是实体类类名与数据库列名写成一样的。。。

    第5章 Mybatis 传统 DAO 层开发(编写dao的实现类)[了解] 

    之前学javaweb时用的都是写实现类。Dao一个接口一个实现类,Service层一个接口一个实现类。

    第6章 SqlMapConfig.xml主配置文件的配置

    最开始是这样的

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!--这是mybatis的主配置文件-->
        <!--配置环境-->
        <environments default="mysql">
            <!--配置mysql的环境-->
            <environment id="mysql">
                <!--配置事务类型-->
                <transactionManager type="JDBC"></transactionManager>
                <!--配置数据源(连接池)-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver"></property>
                    <property name="url" value="jdbc:mysql://localhost:3306/eesy"></property>
                    <property name="username" value="root"></property>
                    <property name="password" value="root"></property>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <!--xml配置映射文件-->
            <mapper resource="com/xxw/dao/IUserDao.xml"></mapper>
        </mappers>
    </configuration>
    View Code

    properties标签

    加入<properties>就把配置连接数据库的基本信息的带<property> 标签的都复制到<properties>里面去,然后给原来的value用${}引用

    用处就是可以把<properties>里面的带<property> 标签的内容放到外面放一个jdbcConfig.properties文件里。这个SqlMapConfig.xml里面就只剩<property>原来的value用${}引用就可以。

    typeAliases标签 ---解释Integer的写法

    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
    <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名后IUserDao.xml就不再区分大小写 -->
    <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>

    </typeAliases>

    IUserDao.xml中的parameterType="com.xxw.domain.User"就可以=“user"其中user不分大小写

    还可以直接改包

    <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
    <package name="com.xxw.domain"></package> 替代<typeAlias>那个放在</typeAliases>里面

    mappers标签的子标签:package

    同理,这个mappers里的package

    <mappers>
    <!--xml配置映射文件-->
    <!--<mapper resource="com/xxw/dao/IUserDao.xml"></mapper>-->
    <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
    <package name="com.itheima.dao"></package>
    </mappers>

    但是弹幕说映射配置文件路径和名称一定要和java对上,不然报错;还有起别名容易导致日志乱码

    添加上述三个标签后的SqlMapConfig.xml代码

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <!-- 配置properties
           可以在标签内部配置连接数据库的信息。也可以通过属性引用外部配置文件信息
           resource属性: 常用的,短一些。。。
               用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。
           url属性:
               是要求按照Url的写法来写地址
               URL:Uniform Resource Locator 统一资源定位符。它是可以唯一标识一个资源的位置。
               它的写法:
                   http://localhost:8080/mybatisserver/demo1Servlet
                   协议      主机     端口       URI
               URI:Uniform Resource Identifier 统一资源标识符。它是在应用中可以唯一定位一个资源的。
       -->
        <!--<properties url="file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.properties">-->
        <properties resource="jdbcConfig.properties">
            <!-- <property name="driver" value="com.mysql.jdbc.Driver"></property>
             <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis"></property>
             <property name="username" value="root"></property>
             <property name="password" value="1234"></property>-->
        </properties>
    
        <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
        <typeAliases>
            <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就再区分大小写 -->
            <!--<typeAlias type="com.xxw.domain.User" alias="user"></typeAlias>-->
            <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
            <package name="com.itheima.domain"></package>
        </typeAliases>
    
        <!--这是mybatis的主配置文件-->
        <!--配置环境-->
        <environments default="mysql">
            <!--配置mysql的环境-->
            <environment id="mysql">
                <!--配置事务类型-->
                <transactionManager type="JDBC"></transactionManager>
                <!--配置数据源(连接池)-->
                <dataSource type="POOLED">
                    <property name="driver" value="${jdbc.driver}"></property>
                    <property name="url" value="${jdbc.url}"></property>
                    <property name="username" value="${jdbc.username}"></property>
                    <property name="password" value="${jdbc.password}"></property>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <!--xml配置映射文件-->
            <!--<mapper resource="com/xxw/dao/IUserDao.xml"></mapper>-->
            <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class了 -->
                <package name="com.xxw.dao"></package>
        </mappers>
    </configuration>
    View Code
  • 相关阅读:
    HDU1506 Largest Rectangle in a Histogram(算竞进阶习题)
    洛谷P1073 最优贸易
    CH2101 可达性统计(算竞进阶习题)
    BZOJ1012 最大数maxnumber
    POJ 3764 The XOR Longest Path
    洛谷P4513 小白逛公园
    外边距叠加问题
    读JS高性能总结——DOM编程(一)
    DOM修改元素的方法总结
    DOM查找元素的方法总结
  • 原文地址:https://www.cnblogs.com/gezi1007/p/12835823.html
Copyright © 2011-2022 走看看