Mybatis基础(六)

Mybatis基础(六)

数据库多环境切换

  1. 切换 environment (指定实际使用的数据库)

    • db.properties

      #oracle
      oracle.driver=oracle.jdbc.OracleDriver
      oracle.url=jdbc:oracle:thin:@127.0.0.1:1521:ORCL
      oracle.username=scott
      oracle.password=tiger
      
      #mysql
      mysql.driver=com.mysql.jdbc.Driver
      mysql.url=jdbc:mysql://localhost:3306/mydb?allowMultiQueries=true
      mysql.username=root
      mysql.password=root
      
    • conf.xml

      <configuration>
          <!-- 引用db.properties配置文件 -->
          <properties resource="db.properties"/>
          <!--default指定环境 -->
          <environments default="devOracle">
              <!--oracle -->
              <environment id="devOracle">
                  <transactionManager type="JDBC" />
                  <!-- 配置数据库连接信息 -->
                  <dataSource type="POOLED">
                      <property name="driver"  value="${oracle.driver}" />
                      <property name="url" value="${oracle.url}" />
                      <property name="username" value="${oracle.username}" />
                      <property name="password" value="${oracle.password}" />
                  </dataSource>
              </environment>
      
              <!--mysql -->
              <environment id="devMysql">
                  <transactionManager type="JDBC" />
                  <!-- 配置数据库连接信息 -->
                  <dataSource type="POOLED">
                      <property name="driver" value="${mysql.driver}" />
                      <property name="url" value="${mysql.url}" />
                      <property name="username" value="${mysql.username}" />
                      <property name="password" value="${mysql.password}" />
                  </dataSource>
              </environment>
          </environments>
      </configuration>
      
      • 注意事项

    如果mapper.xml的 sql标签 仅有 一个 不带databaseId的标签,则改标签 会自动适应当前数据库。
    如果 既有不带databaseId的标签,又有带databaseId的标签,则程序会优先使用带databaseId的标签。
    ~~~

  2. 配置 Provider别名(数据库环境的别名)

    • conf.xml中配置

      <configuration>
          <!-- 配置数据库支持类 -->
          <databaseIdProvider type="DB_VENDOR">
              <property name="MySQL" value="mysql" />
              <property name="Oracle" value="oracle" />
          </databaseIdProvider>
      </configuration>
      
  3. studentMapper.xml写不同数据库的SQL语句

    <!--mysql -->
    <select id="queryStudentByNo" resultType="com.yanqun.entity.Student"
            parameterType="int" databaseId="mysql">
        select * from student where stuNo=#{stuNo}
    </select>
    
    <!--oracle -->
    <select id="queryStudentByNo" resultType="com.yanqun.entity.Student"
            parameterType="int" databaseId="oracle">
        select * from student where stuNo=#{stuNo}
    </select>
    
    <!-- 不指定databaseId,就是当前默认指定的环境(和 default 指定的环境一致) -->
    <select id="queryStudentByNo" resultType="com.yanqun.entity.Student" parameterType="int">
        select * from student where stuNo=#{stuNo}
    </select>
    
  4. 在xxxMappe.xml增删改标签中配置databaseId = “Provider别名”,来进行使用(如上所示)


注解方式的增删改查

  • 适用场景

    注解方式只适用于简单的增删改查,复杂的增删改查,还是得使用配置文件的方式。
    
  • 本质

    注解的核心是反射机制,底层通过动态代理的方式,根据注解来找到对应的东西(类或SQL等),
    把一些配置信息、属性注入到对应的对象中。
    
  • 注解开发的优点和缺点

    • 优点

      方便、快捷,提高开发效率。
      
    • 缺点

      可读性低,不利于后期维护;
      不适合做复杂的增删改查(复杂的表和类的映射关系等)。
      

增加数据

  1. 将sql语句写在接口的方法上@Insert("") ;

    public interface StudentMapper {
        @Insert("insert into student(stuNo,sname,sage) values(1,'zs',18) where stuNo = #{stuNo}")
        Student queryStudentByNo (int stuNo);
    }
    
  2. 将接口的全类名写入conf.xml核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中

    <configuration>
        <!-- 在配置文件(conf.xml)中注册SQL映射文件(studentMapper接口)-->
        <mappers>
            <mapper class="com.yanqun.mapper.StudentMapper"/>
        </mappers>
    </configuration>
    

删除数据

  1. 将sql语句写在接口的方法上@Delete("") ;
  2. 将接口的全类名写入conf.xml核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中

修改数据

  1. 将sql语句写在接口的方法上@Update("") ;
  2. 将接口的全类名写入conf.xml核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中

查询数据

  1. 将sql语句写在接口的方法上@Select("") ;

    public interface StudentMapper {
        @Select("select * from student where stuNo = #{stuNo}")
        Student queryStudentByNo (int stuNo);
    }
    
  2. 将接口的全类名写入conf.xml核心配置文件的标签中,让MyBatis知道sql语句此时是存储在接口中

    <configuration>
        <!-- 在配置文件(conf.xml)中注册SQL映射文件(studentMapper接口)-->
        <mappers>
            <!--  <mapper resource="com/yanqun/mapper/studentMapper.xml" />-->
            <mapper class="com.yanqun.mapper.StudentMapper" />
            <!-- 批量注册 
            <package name="com.yanqun.mapper"/> -->
        </mappers>
    </configuration>
    

增删改的返回值问题

  1. 返回值可以是 voidIntegerLongBoolean

  2. 如何操作:只需在接口中,修改方法的返回值即可。

    Integer addStudent (Student students);
    

事务的提交方式

手动提交

 sessionFactory.openSession();
 session.commit(); //手动提交

自动提交(慎用)

//自动提交:每个DML(增删改)语句,事务自动提交
sessionFactory.openSession(true);

不同数据库的自增问题

MySQL(支持自增)

  1. 只需要配置两个属性即可:useGeneratedKeys=“true” keyProperty=“stuNo”

    <insert id="addStudent" parameterType="com.yanqun.entity.Student"  databaseId="mysql" useGeneratedKeys="true" keyProperty="stuNo">
        insert into student(stuName,stuAge,graName)
        values(#{stuName},#{stuAge},#{graName})
    </insert>
    
  2. 小结

    keyProperty对应的是Java对象的属性名,
    useGeneratedKeys(主键生成策略)的作用是允许 JDBC 支持自动生成主键,需要驱动支持。
    useGeneratedKeys如果设置为 true 则这个设置强制使用自动生成主键,
    尽管一些驱动不能支持但仍可正常工作(比如 Derby)。
    

Oracle(不支持自增)

oracle不支持自增 :通过序列模拟实现
  1. 方式一:before(推荐)

    • 在数据库中创建一个用于模拟自增的序列

      create sequence myseq
      		increment by 1 -- 步长为 1
      		start with 1; -- 从 1 开始自增
      
    • 通过 <insert>的子标签 <selectKey>实现

      <!-- 增加一个学生 oracle -->
      <insert id="addStudent" parameterType="com.yanqun.entity.Student"  databaseId="oracle">
          <!-- keyProperty对应的是Java对象的属性名 -->
          <selectKey keyProperty="stuNo" resultType="Integer" order="BEFORE">
              <!-- myseq 为 数据库中模拟自增的序列;dual为 Oracle 的一个临时表,里面存放的是序列 -->
              select myseq.nextval from dual
          </selectKey>
      
          insert into student(stuno,stuName,stuAge,graName)
          values(#{stuNo} , #{stuName},#{stuAge},#{graName})
      </insert>
      
    • 在执行SQL语句之前,先在 <selectKey>中查询下一个序列(自增后的值),

    • 然后再将此值传入keyProperty="stuNo"属性(对象的属性,也就是将数据回写到对象的属性中),最后在真正执行时 使用该属性值。

  2. 方式二:after

    • 在数据库中创建一个用于模拟自增的序列(若已创建,则无需再建)

      create sequence myseq
      		increment by 1 -- 步长为 1
      		start with 1; -- 从 1 开始自增
      
    • 通过 <insert>的字标签 <selectKey>和序列自带的两个属性:nextval:序列中下一个值
      currval: 当前值实现

      <insert id="addStudent" parameterType="com.yanqun.entity.Student"  databaseId="oracle">
          <selectKey keyProperty="stuNo" resultType="Integer" order="AFTER">
              select myseq.currval from dual
          </selectKey>
      
          insert into student(stuno,stuName,stuAge,graName)
          values(myseq.nextval , #{stuName},#{stuAge},#{graName})
      </insert>
      
    • 先执行插入的SQL语句,自增的值从nextval(下一个序列、自增后的值)中去取,

    • 然后在 <selectKey>中查询数据库中当前的序列值,再将此值传入keyProperty="stuNo"属性,将数据回写到对象的属性中。


多个输入参数的问题

输入参数为多个时,不用写 parameterType

  1. 处理方式一:将多个参数封装为一个对象(前面基础部分知识点)

  2. 处理方式二:在xxxMapper.xml的SQL中,用 [ arg0, arg1, arg2, arg3 或 param1, param2, param3, param4 ]

    <!-- 输入参数为多个时,不用写 parameterType -->
    <insert id="addStudent" databaseId="mysql">
        insert into student(stuno,stuName,stuAge,graName)
        values(#{arg0},#{arg1},#{arg2},#{arg3})
    </insert>
    
  3. 处理方式三:在变量前面使用@Param(“SQL中参数的名字”) 指定sql中参数的名字(推荐,也叫命名参数)

    • 接口方法
    //接口
    //可以在接口中通过@Param("sNo") 指定sql中参数的名字
    public abstract Integer addStudent(@Param("sNo") Integer stuNo, @Param("sName")String stuName, @Param("sAge")Integer stuAge, @Param("gName")String graName);
    
    • xxxMapper.xml
    <insert...>
        insert into student(stuno,...)
        values(#{sNo}, ...)
    </insert>
    

输入参数为多个且有对象和基本类型(常用于修改)

  • 接口方法

    //输入参数为多个,既有简单类型,又有复杂类型(对象)
    Integer addStudent(@Param("sNo")Integer stuNo, @Param("stu")Student student);
    
  • xxxMapper.xml

    <insert id="addStudent" databaseId="oracle">
        insert into student(stuno,stuName,stuAge,graName)
        values(#{sNo}, #{stu.stuName}, #{stu.stuAge}, #{stu.graName})
    </insert>
    
    • 小结

      用 @Param("SQL中参数的名字") 来指定SQL中参数的名字,
      即:SQL中参数的名字要和 @Param("xxx") 中的名字保持一致。
      一般建议所有参数都加上这个。
      
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunnyboy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值