day01-mybatis随堂笔记

day01-mybatis笔记

今日内容:

mybatis框架的CRUD基本操作

一、框架(了解):

​ 建筑学上:框架楼,只需要搭建骨架,里面的墙后期再去维护(工人)

​ 软件开发上:骨架,由开源的组织研发的一个方便于程序员开发的一个骨架,程序员只需要在骨架之内进行维护操作,直接使用骨架(框架)

​ 所学的框架的底层全部是反射机制

二、常用的框架

五种开源 框架:

​ mybatis(代替jdbc)

​ hibernate(代替jdbc,在企业开发中已经不用了)

​ spring(核心框架,贯穿其他优秀的框架)

​ springmvc(代替servlet)

​ struts2(代替servlet)

常用的框架组合:

​ ssm(spring+springmvc+mybatis)

​ 主要应用的场景:互联网项目(互联网电商,互联网金融)

​ ssh(s2sh,ss2h)(spring+struts2+hibernate)

​ 主要应用的场景:传统项目(学生管理系统,)目前来说政府项目

​ 互联网项目和传统项目区分:

​ 根据并发量来的,传统项目几乎没有并发量

三、三层架构(了解):

​ 表现层

​ web阶段: servlet

​ 框架阶段:springmvc

​ 业务层

​ web阶段:service

​ 框架阶段:spring

​ 数据访问层

​ web阶段:dao

​ 框架阶段:mybatis(持久层) mapper

四、mybatis概括(了解):

问题:

​ 1.为什么学习mybatis

​ 框架是已经编写好的,我们在开发过程中只需要使用这些框架

​ 使用mybatis的好处:大大的减轻了程序员的工作负荷。

​ 避免了jdbc几乎所有的手动编写的代码和获取结果集

​ ORM(对象关系映射): 分为ORM工具和ORM框架

​ ORM工具:springjdbcTemplate和dbutils

​ ORM框架:

​ mybatis(半自动框架) 需要写一部分sql

​ hibernate(全自动框架) 不需要写sql, hql

​ ORM思想:

​ 其实就是javabean(实体类)关联映射数据库表,实体类其实就是数据库表字段的一个映射

​ 实体类其实就是数据库表的虚构的一个类,运行在内存中,数据库表示在硬盘中

​ 总结:持久层框架都是延续了ORM思想,换句话说使用框架,离不开实体类

​ 2.怎么学习mybatis

​ 3.mybatis是什么?

​ MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。码云gitee oschina(开源中国)

​ MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

掌握的信息:

​ 第一。mybatis可以使用xml或者注解两种形式进行开发

​ 第二。原生类型(int ,double,float,long,…),POJO(javaBean对象(domain))

​ 第三。使用mybatis不在去写冗余的jdbc代码

​ 4.怎么使用mybatis?

五、mybatis入门(掌握):

1.准备工作:

​ idea配置maven局部设置和全局设置

mybatis只需要对数据库进行CRUD操作,只需要创建jar工程

注意事项:

​ 1.每一个框架中都会有一个自己的核心配置文件,mybatis的核心配置文件sqlMapConfig.xml

​ 2.实体类映射文件xxMapper.xml(xxDao.xml)xx则表示实体类的名称

第一步,创建数据库表

CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime default NULL COMMENT '生日',
  `sex` char(1) default NULL COMMENT '性别',
  `address` varchar(256) default NULL COMMENT '地址',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


第二步,导入依赖

 <dependencies>
        <!--mybatis的核心jar包-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--日志依赖-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
    </dependencies>

第二步,环境配置(xml版)

​ 注意:mybatis的框架中有两个配置文件

在配置文件中第一行必须要加入该配置文件的约束

​ 从使用mybatis之后,那么意味着dao只有接口没有实现类,用实体类映射文件来完成dao接口的实现

​ 第一,编写domain

public class User implements Serializable{

    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

​ 第二,编写Dao

public interface IUserDao {

   
}

​ 第三,核心配置文件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>
 <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
</configuration>

​ 第四,实体类映射文件xxMapper.xml(xxDao.xml)

注意:目前来说实体类映射文件的名字要和dao接口的名称一致

<?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">
<!--表示映射
    namespace表示命名空间,属性值等于当前dao接口的全限名称
-->
<mapper namespace="com.itheima.dao.IUserDao">
        
</mapper>

2.入门查询操作

第一步,编写dao接口

//全查
    public  List<User> findAll();

第二步,编写IUserDao.xml

   <!--全查
            select标签表示查询标签,
            id属性表示当前标签的名称,属性值等于当前dao接口中相对应方法的方法名称
            相当于在dao实现类中去重写dao接口中的方法
            resultType表示结果类型,
                属性值
                    如果说返回值是List类型必须等于list集合中的泛型
                     如果说返回值是实体类类型的话,必须等于返回值
        -->
        <select id="findAll" resultType="com.itheima.domain.User">
            SELECT  * FROM user
        </select>

第三步,注意,在sqlMapConfig.xml中必须加入关系映射

 <!--核心配置文件去关联实体类映射文件-->
    <mappers>
        <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
    </mappers>

第四步,测试类

    public static void main(String[] args) throws IOException {
        //1.读取配置文件,生成字节输入流,目的是为了连接数据库
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
         SqlSession sqlSession = factory.openSession();
        //4.获取dao的代理对象(动态代理对象)
       IUserDao userDao = sqlSession.getMapper(IUserDao.class);
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

报错信息:

​ 实体类映射文件没有被映射到(注册到)

解决方案:

​ 在sqlMapConfig.xml中加入映射关联

报错2:

​ 当前IUserDao.xml中出现了非法参数

3.新增操作

第一步,编写dao接口

  //新增
    public void insertUser(User user);

第二步,编写IUserDao.xml

     <!--新增
               mybatis中赋值的时候需要使用#{}形式
               注意:#{参数},参数写什么取决当前接口的参数类型
               如果说参数类型是实体类类型的话,那么#{参数}参数必须要和实体类中的相对应的属性名称一致
               注意:新增,修改和删除,以及查询的时候如果说需要参数,可以不去在标签只能加上parameterType,如果不加,mybatis
               会自动去当前对应的dao接口方法中去匹配类型,建议还是要加上该属性
               parameterType参数类型,属性值目前来说必须是全限名称
        -->
              <insert id="insertUser" parameterType="com.itheima.domain.User">
                  INSERT  INTO  user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
              </insert>

第三步,测试类

   private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    @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{
        //提交事务
        sqlSession.commit();
        //6.释放资源
        sqlSession.close();
        in.close();
    }
     /**
     * 测试保存操作
     */
    @Test
    public void insertUser(){
        User user = new User();
        user.setUsername("二狗子1");
        user.setAddress("天上人间");
        user.setSex("男");
        user.setBirthday(new Date());
        //5.执行保存方法
        userDao.insertUser(user);

    }

[外链图片转存失败(img-oJC5rv9w-1565187691849)(C:\Users\45502\Desktop\assets\1559114946769.png)]

4.修改操作

第一步,编写IUserDao

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

第二步,编写IUserDao.xml

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

第三步,编写测试类

    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(56);
        user.setUsername("隔壁老王");
        user.setAddress("隔壁的隔壁");
        user.setSex("女");
        user.setBirthday(new Date());

        //5.执行保存方法
        userDao.updateUser(user);
    }

[外链图片转存失败(img-NkwJJnTd-1565187691851)(C:\Users\45502\Desktop\assets\1559115789667.png)]

5.删除操作

第一步,编写IUserDao

void deleteUser(Integer userId);

第二步,编写IUserDao.xml

 <!-- 删除用户
                 如果说参数类型是原生类型,你可以直接写原生类型,而不需要全限名称
                 如果说参数类型是原生类型的话,那么sql语句中的参数可以随意起
        -->
        <delete id="deleteUser" parameterType="int">
                delete from user where id = #{id}
        </delete>

第三步,编写测试类

 /**
     * 测试删除操作
     */
    @Test
    public void testDelete(){
        //5.执行删除方法
        userDao.deleteUser(56);
    }

6.单一查询操作

第一步,编写IUserDao

User findById(int id);

第二步,编写IUserDao.xml

  <!--单一查询-->
    <select id="findById" parameterType="int" resultType="user">
        select * from user where id=#{id}
    </select>

第三步,编写测试类

 /*单一查询*/
    @Test
    public void testfindId(){
        User user = userDao.findById(1);
        System.out.println(user);
    }

7.模糊查询操作

第一步,编写IUserDao

 //模糊查询
    List<User> findByName(String name);

第二步,编写IUserDao.xml

<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="com.itheima.domain.User">
	select * from user where username like #{name}
</select>

第三步,编写测试类

   //模糊查询
    @Test
    public void testdemo1(){
        //5.执行删除方法
        List<User> users = userDao.findByName("%王%");
        for (User user : users) {
            System.out.println(user);
        }
    }

注意:#{}和${}区别:

​ 。#{}表示利用的预处理的执行对象PreparedStatment,专门用来防止sql注入攻击(建议使用)

​ 。${}表示利用的statement对象,容易造成sql注入攻击(不建议使用)

8.新增之后立刻获取id操作

注意:使用场景,一般应用于电商项目中购物车中添加完购物车之后,要马上把当前购物车信息id添加到另外一张表中作为关联使用。

第一步,编写IUserDao

 //新增
    public void insertUser(User user);

第二步,编写IUserDao.xml

 <!--新增
               mybatis中赋值的时候需要使用#{}形式
               注意:#{参数},参数写什么取决当前接口的参数类型
               如果说参数类型是实体类类型的话,那么#{参数}参数必须要和实体类中的相对应的属性名称一致
               注意:新增,修改和删除,以及查询的时候如果说需要参数,可以不去在标签只能加上parameterType,如果不加,mybatis
               会自动去当前对应的dao接口方法中去匹配类型,建议还是要加上该属性
               parameterType参数类型,属性值目前来说必须是全限名称
        -->
              <insert id="insertUser" parameterType="com.itheima.domain.User">
                      /*
                        selectKey表示查询主键的标签,一般应用于新增中,
                      keyProperty表示实体类中主键属性名称
                      keyColumn表示数据库表中的主键字段名称
                      resultType表示当前sql语句中的返回值类型
                      order表示当前sql语句插入的时机,
                      AFTER表示执行完新增sql语句之后开始执行该sql语句
                      BEFORE表示执行完新增sql语句之前开始执行该sql语句
                      */
                  <selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
                          SELECT LAST_INSERT_ID();
                  </selectKey>
                  INSERT  INTO  user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
              </insert>

第三步,编写测试类

 /**
     * 测试保存操作
     */
    @Test
    public void insertUser(){
        User user = new User();
        user.setUsername("二狗子1");
        user.setAddress("天上人间");
        user.setSex("男");
        user.setBirthday(new Date());
        System.out.println(user.getId());
        //5.执行保存方法
        userDao.insertUser(user);
        System.out.println(user.getId());
    }

9.传递 pojo 包装对象作为参数操作

第一步,编写QueryVo

/*
包装类对象
 */
public class QueryVo {
    private User user;

第二步,编写IUserDao

   //模糊查询
    List<User> findByNameVo(QueryVo vo);

第三步,编写IUserDao.xml

 <!-- 根据名称模糊查询queryVo
                如果说参数类型是包装对象的话,那么sql语句中#{参数},参数等于包装对象里的属性名称.属性名称
         -->
        <select id="findByNameVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User">
                select * from user where username like #{user.username}
        </select>

第四步,编写测试类

 //模糊查询2
    @Test
    public void testdemo2(){
        QueryVo queryVo=new QueryVo();
        User user=new User();
        user.setUsername("%王%");
        queryVo.setUser(user);
        //5.执行删除方法
        List<User> users = userDao.findByNameVo(queryVo);
        for (User user2 : users) {
            System.out.println(user2);
        }
    }

问题:表示IUserDao.xml中标签中的id属性值有重复的

10.实体类属性名称和数据库表字段名称不一致的操作

​ 注意:如果实体类属性名称和数据库表字段名称一致的话,mybatis会映射不到

​ 建议大家名称要一致。

​ 不一致的解决方案:

第一步,创建一个实体类,属性名称和数据库表字段名称不一致

public class User2 implements Serializable{

    private Integer uId;
    private String uUsername;
    private Date uBirthday;
    private String uSex;
    private String uAddress;

第二步,创建一个IUser2Dao

    //全查
    public  List<User2> findAll();

第三步,创建一个IUser2Dao.xml

<?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.itheima.dao.IUser2Dao">
        <!--
            resultMap标签表示结果集类型,
            id属性表示当前标签的名称,不可重复
            type表示表示当前结果集对应的类型,属性值等于domain类的全限名称
        -->
        <resultMap id="userResultMap" type="com.itheima.domain.User2">
            <!--表示主键映射关系的标签
                property表示实体类中的属性名称
                column表示数据库表中的主键名称
                javaType表示当前实体类中属性名称的类型,可以不写
                jdbcType表示当前数据库表字段的类型,可以不写
            -->
            <id property="uId" column="id" javaType="Integer" jdbcType="INTEGER"></id>
            <result property="uUsername" column="username"></result><!--非主键映射-->
            <result property="uBirthday" column="birthday"></result><!--非主键映射-->
            <result property="uSex" column="sex"></result><!--非主键映射-->
            <result property="uAddress" column="address"></result><!--非主键映射-->
        </resultMap>

        <!--
            在查询中有两个结果集属性:
                1.resultType,
                    属性值很自由,可以是实体类对应的全限名称,还可以是类的类地址(int,long)
                2.resultMap
                    属性值必须等于reusltMap标签的id属性值
            注意:在同一个select标签中不可以同时出现resultMap和resultType属性
        -->
        <select id="findAll" resultMap="userResultMap">
            SELECT  * FROM user
        </select>

</mapper>

第四步,测试

    /**
     * 测试查询所有
     */
    @Test
    public void findAll(){
        //5.执行查询所有方法
        List<User2> users = user2Dao.findAll();
        for(User2 user : users){
            System.out.println(user);
        }

    }

表示当前结果集中没有包含userResultMap1这个集合

[外链图片转存失败(img-vmYuDhgY-1565187691855)(C:\Users\45502\Desktop\assets\1559125451565.png)]

11.properties标签的使用

​ 主要是为了分离代码,解决了一部分代码的耦合,一般应用于jdbc.properties

第一步,在当前项目中resources包下创建一个jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy_mybatis
jdbc.username=root
jdbc.password=123

第二步,修改sqlMapConfig.xml

  <!--
        引入外部的资源文件
        resource表示获取类路径下的properties文件
    -->
    <properties resource="jdbc.properties"></properties>
    
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的环境-->
        <environment id="mysql">
            <!-- 配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源(连接池) -->
            <dataSource type="POOLED">
                <!-- 配置连接数据库的4个基本信息 -->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

12.typeAliases和package标签的使用

修改sqlMapConfig.xml

  <!--
        别名库设置
    -->
    <typeAliases>
        <!--一对一的别名设置,
            type表示别名所对应的的类型
            alias表示别名
        -->
       <!-- <typeAlias type="com.itheima.domain.User2" alias="user2"></typeAlias>
        <typeAlias type="com.itheima.domain.User" alias="user"></typeAlias>-->
        <!--
            表示包扫描的形式
            name属性表示实体类所在的路径地址
            当前包路径下的所有的类都可以扫描到,使用的时候别名不区分大小写,建议大家使用类名
        -->
        <package name="com.itheima.domain"></package>
    </typeAliases>
    
     <!--核心配置文件去关联实体类映射文件-->
    <mappers>
        <!--
           映射,resource表示路径,属性值必须是.xml文件所在的路径
           注意:如果使用mapper形式去关联映射实体类映射文件,那么dao接口和实体类映射文件的名称可以不一致
           因为是直接映射到.xml文件
        -->
       <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
        <mapper resource="com/itheima/dao/IUser2Dao.xml"></mapper>
        <!--
            表示扫描的是dao接口所在的包路径地址,当前包下的所有的接口类都可以被扫描到
            那么dao接口和实体类映射文件的名称必须一致,因为包扫描是扫描的dao接口
        -->
       <!-- <package name="com.itheima.dao"></package>-->
    </mappers>

main.User" alias=“user”>–>


 <!--核心配置文件去关联实体类映射文件-->
<mappers>
    <!--
       映射,resource表示路径,属性值必须是.xml文件所在的路径
       注意:如果使用mapper形式去关联映射实体类映射文件,那么dao接口和实体类映射文件的名称可以不一致
       因为是直接映射到.xml文件
    -->
   <mapper resource="com/itheima/dao/IUserDao.xml"></mapper>
    <mapper resource="com/itheima/dao/IUser2Dao.xml"></mapper>
    <!--
        表示扫描的是dao接口所在的包路径地址,当前包下的所有的接口类都可以被扫描到
        那么dao接口和实体类映射文件的名称必须一致,因为包扫描是扫描的dao接口
    -->
   <!-- <package name="com.itheima.dao"></package>-->
</mappers>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值