笔记大纲
-
映射文件简介
-
MyBatis—CRUD功能实现与分析(重点)
-
数据bean-Employee
-
Mapper接口(CRUD方法)
-
Mapper映射文件(EmployeeMapper.xml)
-
主配置文件(mybaits-conf.xml)–<映射器>
-
测试类
-
-
如何获取数据库主键值问题
-
映射文件配置属性获取主键值
-
使用JDBC实现插入数据库后获取主键值
-
1.映射文件简介
MyBatis 的真正强大在于它的映射语句,映射器的XML文件变的相对简单,主要针对SQL语句进行构建。
SQL映射文件有几个顶级元素需要了解下:
元素 | 说明 |
---|---|
cache | 给定命名空间的缓存配置 |
cache-ref | 其他命名空间缓存配置的引用 |
resultMap | 最复杂、最强大元素,用来描述如何从数据库结果集中来加载对象 |
parameterMap(过时) | 老式风格的参数映射,内联参数是首选,这个元素可能在将来被移除,这里不会记录 |
sql | 可被其他语句引用的可重用语句块 |
insert | 映射插入语句 |
update | 映射更新语句 |
delete | 映射删除语句 |
select | 映射查询语句 |
在xml
文件中组件键Alt+/
可以查看:
2.MyBatis—CRUD功能实现与分析
涉及事务操作(增删改)注意:
MyBatis中的事务是默认关闭的!获得
session
时通过sqlSessionFactory.openSession(true)
,即方法包含有参,则不需要手动提交,通过sqlSessionFactory.openSession()
,则需要手动提交!
项目结构
2.1.数据bean-Employee
package com.codinglin.mybatis.beans;
public class Employee {
private Integer id;
private String lastName;
private String email;
private String gender;
public Employee() {
super();
}
//构造函数
public Employee(Integer id, String lastName, String email, String gender) {
super();
this.id = id;
this.lastName = lastName;
this.email = email;
this.gender = gender;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email=" + email + ", gender=" + gender + "]";
}
}
2.2.Mapper接口
package com.codinglin.mybatis.mapper;
import com.codinglin.mybatis.beans.Employee;
public interface EmployeeMapper {
/*
* 根据员工id获取员工信息
*/
Employee getEmployeeById(Integer id);
/*
* 根据员工id添加员工信息
* 如果需要返回值,常用的类型Integer|Long|Boolean
*/
void insertEmployee(Employee emp);
/*
* 根据员工id删除员工信息
*/
void deleteEmployee(Integer id);
/*
* 根据员工id修改员工信息
*/
void updateEmployee(Employee emp);
}
2.3.Mapper映射文件(EmployeeMapper.xml)
以下五点需要注意:
(1)
id
:表示映射文件中SQL语句片段,必须唯一;(2)
resultType
:返回结果类型(要将数据查询的结果封装成什么类型,resultType属性就应该定义成什么类型);(3)
parameterMap
:指定传递的参数类型,可以使用别名,也可以省略,MyBatis会自动推断出参数的类型;
(4)接收参数时,使用#{对象的属性名}
格式;
(5)在映射文件中,不要以“;
”结束语句。
<?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.codinglin.mybatis.mapper.EmployeeMapper">
<!-- 【1】查询员工 -->
<select id="getEmployeeById" resultType="com.codinglin.mybatis.beans.Employee">
select id ,last_name lastName ,email ,gender from employee_table where id = #{id}
<!-- select * from tbl_employee where id = #{id} -->
</select>
<!-- 【2】新增员工 -->
<insert id="insertEmployee" >
insert into employee_table(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>
<!--【3】删除员工 -->
<delete id="deleteEmployee">
delete from employee_table where id=#{id}
</delete>
<!--【4】更新员工 -->
<update id="updateEmployee">
update employee_table set last_name=#{lastName},email=#{email},gender=#{gender} where id =#{id}
</update>
</mapper>
2.4.主配置文件(mybaits-conf.xml)
Mapper映射器: 用来在mybatis初始化的时候,告诉mybatis需要引入哪些Mapper映射文件!
(1)mapper单个注册SQL映射文件
①resource:去类路径(字节码输出处)下加载文件
②url:引入网路或磁盘路径下的文件
③class:引入的Mapper接口(全限类名)存在SQL映射文件 , 要求Mapper接口与 SQL映射文件同名同位置比如上面项目工程处紫色套圈处处理!
没有SQL映射文件 , 使用注解
@mapper
在接口的方法上写SQL语句。(2)mapper批量注册SQL映射文件
</mappers>
<package name="com.codinglin.XXX.mapper" />
</mappers>
<?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">
<!-- Mybatis主配置文件 /全局配置文件-->
<configuration>
<!-- 数据库连接环境的配置@开发库 -->
<environments default="development">
<environment id="development">
<!-- 指定事务控制类-->
<transactionManager type="JDBC" />
<!-- 数据源,通过连接池的方式-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis_db" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper映射器, 引入SQL映射文件,Mapper映射(单个接口注册)-->
<!-- <mapper resource="EmployeeMapper.xml" /> -->
<!-- mapper接口 与mapper文件一定要在同包下!!!!-->
<!-- <mapper class="com.codinglin.mybatis.mapper.EmployeeMapper" /> -->
<!-- 批量接口注册 -->
<package name="com.codinglin.mybatis.mapper" />
</mappers>
</configuration>
2.5.测试类
这里对
sqlSession
进行了集中的封装,用@Before
、@After
分别进行了初始化和销毁的处理,降低代码的冗余度,旨在在单元测试方法执行前后执行这些操作。Junit这里使用的版本是4.0!
package com.codinglin.mybatis.test;
//导入包文件省略.........
public class TestMybatis_CRUD {
private SqlSession sqlSession;
//在所有单元测试方法执行之前执行
@Before
public void init() throws Exception {
//定义配置文件
String resource ="mybatis-conf.xml";
//建立读取文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//获取sqlSession,如果不加参数,事务需要手动提交
sqlSession = sqlSessionFactory.openSession();
//sqlSessionFactory.openSession(true);//创建sqlSession事务自动提交的
//事务只是在增删改的操作上
}
/*
* (1)测试添加
*/
@Test
public void testInsert() throws Exception {
//获取接口的代理实现类的实例
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
//通过有参构造创建对象
Employee employee=new Employee(null,"小仓女神","8888@qq.com","女");
//调用添加方法
employeeMapper.insertEmployee(employee);
sqlSession.commit();
}
/*
* (2)测试删除
*/
@Test
public void testDelete() throws Exception {
//获取接口的代理实现类的实例
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
employeeMapper.deleteEmployee(3);
sqlSession.commit();
}
/*
* (3)测试更新
*/
@Test
public void testUpdate() throws Exception {
//获取接口的代理实现类的实例
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee(4,"小泽女侠","544545@163.com","女");
employeeMapper.updateEmployee(employee);
sqlSession.commit();
}
/*
* (4)测试查询
*/
@Test
public void testSelect() throws Exception {
//获取接口的代理实现类的实例
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee=employeeMapper.getEmployeeById(1);
System.out.println(employee);
}
//在所有单元测试方法先执行结束之后执行
@After
public void destory() {
sqlSession.close();
}
}
运行结果:
3.如何获取数据库主键值问题
我们知道MySQL数据库是支持主键自增,而Oracle数据库是不支持主键自增的!
应用场景:(字段id是主键)先向员工表中新增一条数据,然后将新增的数据查询出来。
3.1.映射文件配置属性获取主键值
(1)测试类中新增方法
@Test
public void testKeyValue() {
//获取接口的代理对象类的实例
EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
Employee employee = new Employee(null,"亚瑟","1225155@13.com","男");
employeeMapper.insertEmployee(employee);
sqlSession.commit();
Employee employeeById = employeeMapper.getEmployeeById(employee.getId());
System.out.println("======测试,数据新增提交后再查询信息====="+employeeById);
}
(2)运行效果
可以看见,提交更新成功后,再根据主键去查询,Employee信息为空!按道理说,数据提交成功,数据就已经写入到数据库表中,再去查询,应该能查询到的,怎么回事呢?
(3)常见解决方案
对SQL映射文件,对应的新增方法添加属性!
设置
useGeneratedKeys="true"
:允许JDBC支持自动生成主键,需要驱动兼容。 (在执行添加记录之后可以获取到数据库自动生成的主键ID)设置` keyProperty=“id”
原SQL元素配置属性:
<insert id="insertEmployee" >
insert into employee_table(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>
现SQL元素配置属性:
<insert id="insertEmployee" parameterType="com.codinglin.mybatis.beans.Employee" useGeneratedKeys="true" keyProperty="id">
insert into employee_table(last_name,email,gender) values(#{lastName},#{email},#{gender})
</insert>
运行效果:
3.2.使用JDBC实现插入数据库后获取主键值
(1)测试类中新增方法
@Test
public void testJDBCInsertAndReturnKey() throws Exception{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/mybatis_db";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url, user, password);
//创建statement对象
String sql = "insert into employee_table (last_name,email,gender) values(?,?,?)";
PreparedStatement ps = connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
ps.setString(1, "jdbc测试");
ps.setString(2, "20190909@163.com");
ps.setString(3, "nan");
//执行SQL
int num = ps.executeUpdate();
System.out.println("执行新增操作的result:" + num);
//处理结果集
ResultSet rs = ps.getGeneratedKeys();
if(rs.next()) {
int key = rs.getInt(1);
System.out.println("新增的数据在数据库表的主键是:"+key);
}
//释放资源
connection.close();
}
(2)运行结果
☝上述分享来源个人总结,如果分享对您有帮忙,希望您积极转载;如果您有不同的见解,希望您积极留言,让我们一起探讨,您的鼓励将是我前进道路上一份助力,非常感谢!我会不定时更新相关技术动态,同时我也会不断完善自己,提升技术,希望与君同成长同进步!
☞本人博客:https://coding0110lin.blog.csdn.net/ 欢迎转载,一起技术交流吧!