本文内容:
1、关于Mybatis核心配置文件的三个标签environments、databaseIdProvider、mappers将会在本文中进行使用
environments:数据库连接环境的切换
databaseIdProvider:支持多数据库厂商
mappers:映射文件
2、Mybatis的CRUD操作:
①根据批量注册接口的形式进行操作
②根据注册映射文件的形式进行操作
3、Mybatis通过insert从而获取主键
①获取mysql中的自增主键
②获取oracle中的非自增主键
本节开篇先学习一个Mybatis核心配置文件(mybatis-config.xml)中的标签<mappers></mappers>
1、该标签是什么?有什么用?
①首先该标签是在Mybatis的核心配置文件中的标签
②该标签是一个映射器,用来映射SQL语句到核心配置文件;Mybatis最大的优点就是将SQL语句全部给抽取了出来,单独放置,但是他不是孤立的,所以这里就需要将SQL映射文件映射到核心配置文件中。
2、剖析组成
<mappers>
<mapper resource=""/>
<mapper class=""/>
<mapper url=""/>
<package name=""/>
</mappers>
mappers标签 的属性组成如上:
作用:
resource:引用类路径下的sql映射文件
eg:
<mapper resource="org/trg/mybatis/Dao/Employee.xml"/>
url:引用网路路径或者磁盘路径下的sql映射文件
eg:
<mapper url="file:///mybatis/mappers/Employee.xml"/>
class: 注册接口
class:引用(注册)接口,
1、有sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
2、没有sql映射文件,所有的sql都是利用注解写在接口上;(了解)
package:批量注册 将包内的所有映射器接口全部注册为映射器
eg:
<package name="com.trg.mybatis.Dao"/>
注意:在进行批量注册的时候前提是要按照如下的包路径放置文件(这里不是说一定要将文件名设置成这样,而是文件名必须要相同,包名也必须相同,为了工程美观性,所以讲配置文件要放置在resource源文件夹下)
此时,必须要将Mybatis的SQL映射文件中的namespace按照如下配置
<mapper namespace="com.trg.mybatis.Dao.EmployeeMapper"></mapper>
第一种:批量注册接口映射的方式
EmployeeMapper.java接口文件中:
package com.trg.mybatis.Dao;
import com.trg.javaBean.Employee;
/*
*这里的接口返回值类型可以是Integer、Long、BoBooLean、void类型
*
*/
public interface EmployeeMapper {
// 查询
Employee getEmpById(int emp);
// 增加
Integer insert(Employee emp);
// 删除
Integer delete(int i);
// 更新
Integer update(Employee emp);
}
EmployeeMapper.xml :SQL映射文件中
<?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.trg.mybatis.Dao.EmployeeMapper">
<!-- 根据id查询 -->
<select id="getEmpById" resultType="emp" >
SELECT
id,
last_name as lastname,
email,
sex
FROM employee
WHERE id = #{id}
</select>
<!-- 查询 -->
<select id="selectEmp" resultType="emp" >
SELECT
id,
last_name as lastname,
email,
sex
FROM employee
</select>
<!-- 增加 -->
<insert id="insert" parameterType="com.trg.mybatis.Dao.EmployeeMapper" >
INSERT INTO employee(last_name,email,sex)
VALUES (
#{lastname},
#{email},
#{sex}
)
</insert>
<!-- 更新 -->
<update id="update" parameterType="com.trg.mybatis.Dao.EmployeeMapper">
UPDATE employee
SET
last_name = #{lastname},
email = #{email},
sex = #{sex}
WHERE id = #{id}
</update>
<!-- 删除 -->
<delete id="delete" parameterType="com.trg.mybatis.Dao.EmployeeMapper">
DELETE FROM employee
WHERE id=#{id}
</delete>
</mapper>
测试类:
@Test
public void test4() throws Exception{
//Mybatis的核心配置文件
String resource = "mybatis-config.xml";
//这里通过Resources类来加载Mybatis的核心配置文件当然也可以使用类加载器来加载
InputStream inputStream = Resources.getResourceAsStream(resource);
//类加载器进行加载Mybatis的核心配置文件
//InputStream inputStream = MybatisTest.class.getClassLoader().getResourceAsStream(resource);
//创建一个sqlSession工厂
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
//创建一个SqlSession ,比较关键,主要我们用这个来执行我们在SQL映射文件中写的SQL语句
SqlSession opsession = sqlSessionFactory.openSession();
try {
// 获取接口反射类,从而可以调用接口对应的方法
EmployeeMapper mapper = opsession.getMapper(EmployeeMapper.class);
// insert添加--这里通过Javabean的构造器直接添加,因为我对id设置了自增的形式,所以不做插入
Employee emps = new Employee(null,"trg","trg@123.com","nv");
Integer num = mapper.insert(emps);
//update 修改
// Employee emps1 = new Employee(2,"trg","trg@123.com","man");
// Integer num = mapper.update(emps1);
// delete删除
// Integer num = mapper.delete(4);
if(num>0){
System.out.println("操作成功!");
} else {
System.err.println("操作失败! ");
}
//提交事务
opsession.commit();
} finally {
//用完之后,必须要关闭资源
opsession.close();
}
}
注意:
sqlSessionFactory.openSession():手动提交数据
sqlSessionFactory.openSession(true):自动提交数据
测试结果:
上面的测试结果只是一个insert操作,别的操作就不展示了
以上的测试都是在Mybatis-config.xml中批量注册映射接口后进行测试的
第二种:注册sql映射文件的方式
1、在核心配置文件中注册SQL的映射文件
<mapper resource="com/trg/mybatis/Dao/EmployeeMapper.xml"/>
2、SQL映射文件内容同上
3、编写测试类
@Test
public void test1() throws Exception{
//Mybatis的核心配置文件
String resource = "mybatis-config.xml";
//这里通过Resources类来加载Mybatis的核心配置文件当然也可以使用类加载器来加载
InputStream inputStream = Resources.getResourceAsStream(resource);
//类加载器进行加载Mybatis的核心配置文件
//InputStream inputStream = MybatisTest.class.getClassLoader().getResourceAsStream(resource);
//创建一个sqlSession工厂
SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
//创建一个SqlSession ,比较关键,主要我们用这个来执行我们在SQL映射文件中写的SQL语句
SqlSession openSession = sqlSessionFactory.openSession(true);
try {
// 1、根据id进行单挑查询
// Employee employee = openSession.selectOne("getEmpById", 1);
// 2、查询全部结果
List<Employee> employees = openSession.selectList("selectEmp");
//System.out.println(employee);
System.out.println(employees);
// 3、新增
// 先将值添加到Javabean中
// Employee emps = new Employee(null, "Tom", "注册文件@qq.com", "man");
//然后进行插入操作
// Integer num = openSession.insert("insert", emps);
// 4、更新update
// Employee emps = new Employee(12, "Tom", "Tom@qq.com", "man");
// Integer num = openSession.update("update", emps);
// 5、删除
Integer num = openSession.delete("delete","12");
if(num>0){
System.out.println("操作成功!");
} else {
System.err.println("操作失败! ");
}
} finally {
openSession.close();
}
}
4、进行测试通过
注意的几点
1》 测试的时候所创建的值要符合数据库要求,这里主要是指类型的要求和字符长度的限制
2》 要注意注册接口的方式和注册映射文件的区别
① 注册接口有单独的接口映射类,这里要明白是怎么将SQL映射文件和接口的绑定,
②注册时候的区别:
注册映射文件
<mapper resource="com/trg/mybatis/Dao/EmployeeMapper.xml"/>
注册接口的方式
<mapper class="com.trg.mybatis.Dao.EmployeeMapper"/>
注册接口的方式一般推荐使用批量注册,如下:
<package name="com.trg.mybatis.Dao"/>
③注意在测试的时候传值的区别,接口的方式只传一个值,但是映射文件的方式的话是还要写上对应的SQL语句的id
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
知识点---获取主键的值
1)获取自增主键的值,相对于mysql数据库
useGeneratedKeys="true" 使用自增主键获取主键值策略
keyProperty="true" 指定对应的主键属性,也就是Mybatis获取到主键以后,将这个个封装到JavaBean的那个属性
<insert id="insert" parameterType="com.trg.mybatis.Dao.EmployeeMapper"
useGeneratedKeys="true" keyProperty="id">
INSERT INTO employee(last_name,email,sex)
VALUES (
#{lastname},
#{email},
#{sex}
)
</insert>
通过接口映射测试
Employee emps = new Employee(null,"trg","trg@123.com","nv");
Integer num = mapper.insert(emps);
System.out.println(emps.getId());
测试结果如下:
2)获取非自增主键的值,相对于oracle数据库
首先要将我们项目中的数据库切换成oracle数据库
1>将mybatis-config.xml配置文件中的默认数据库修改成对应的oracle的
设置default="dev_oracle"
<environments default="dev_oracle">
<environment id="dev_mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<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>
<environment id="dev_oracle">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="${orcl.driver}" />
<property name="url" value="${orcl.url}" />
<property name="username" value="${orcl.username}" />
<property name="password" value="${orcl.password}" />
</dataSource>
</environment>
</environments>
2> 在SQL映射文件中--现在想要使用的语句就是insert语句,因为我们要通过insert的方式获取非自增主键的值,所以要在需要调用的insert中添加一个属性databaseId="oracle",将其指定为oracle数据库,当然前提条件是要在核心配置文件中配置如下:
<!-- 5、databaseIdProvider:支持多数据库厂商的;
type="DB_VENDOR":VendorDatabaseIdProvider
作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),mybatis就能根据数据库厂商标识来执行不同的sql;
MySQL,Oracle,SQL Server,xxxx
-->
<databaseIdProvider type="DB_VENDOR">
<!-- 为不同的数据库厂商起别名 -->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
通过以上两个步骤,已经将数据库连接到oracle了
**********这个时候开始通过在oracle中插入一条数据从而获取非自增主键的测试了
第一种方法:
SQL映射文件
<insert id="insert_oracle" parameterType="com.trg.mybatis.Dao.EmployeeMapper" databaseId="oracle">
<!--
selectKey:从oracle数据库中查询序列
keyProperty="id" :这里是将查询到的结果封装成Javabean的属性id
order="AFTER" :优先级 BEFORE 该selectKey在插入之前运行
resultType="Integer" :这里查询之后以什么形式返回
-->
<selectKey keyProperty="id" order="BEFORE" resultType="Integer">
SELECT SEQ_EMPLOYEE_ID.Nextval FROM dual
</selectKey>
INSERT INTO employee(id,last_name,email,sex)
VALUES (
#{id},
#{lastname},
#{email},
#{sex}
)
</insert>
test测试类:
// 3、新增
// 先将值添加到Javabean中
Employee emps = new Employee(null, "Tom", "lo@qq.com", "man");
//然后进行插入操作
Integer num = openSession.insert("insert_oracle", emps);
System.out.println("I am Primary"+" = "+emps.getId());
测试结果如下:
分析:看SQL语句就知道,该种方法主要是先查询序列,然后将序列进行封装到Javabean的属性id,然后下面的SQL在进行插入的时候,获取到Javabean中的属性id,这样便完成插入操作
第二种:
<insert id="insert_oracle" parameterType="com.trg.mybatis.Dao.EmployeeMapper" databaseId="oracle">
<!--
selectKey:从oracle数据库中查询序列
keyProperty="id" :这里是将查询到的结果封装成Javabean的属性id
order="AFTER" :优先级 BEFORE 该selectKey在插入之前运行
resultType="Integer" :这里查询之后以什么形式返回
-->
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
<!-- SELECT SEQ_EMPLOYEE_ID.Nextval FROM dual -->
SELECT SEQ_EMPLOYEE_ID.currval FROM dual
</selectKey>
INSERT INTO employee(id,last_name,email,sex)
VALUES (
SEQ_EMPLOYEE_ID.Nextval,
#{lastname},
#{email},
#{sex}
)
</insert>
测试类同上
测试结果:
分析对比:
上面两个结果所造成的原因是由于sql映射文件中的orade属性所导致的,它决定了到底先执行哪一条语句;
SEQ_EMPLOYEE_ID.Nextval:下一个值
SEQ_EMPLOYEE_ID.currval:当前值
针对序列只做第二种方法分析:
首先我们的SQL执行顺序是先执行插入的,然后再执行查询序列的;
在做插入的时候,我们先插入数据,然后根据SEQ_EMPLOYEE_ID.Nextval序列自动生成主键值插入到数据库中,这个时候序列已经加1了,然后我们要是获取当前的记录的主键值,那么就需要使用SEQ_EMPLOYEE_ID.currval,通过将其封装到Javabean属性的id,那么在测试查询的时候就会查询到这个id了