2. MyBatis基本的CRUD操作
2.1 准备工作(继续使用前面的库表和代码)
可以引入配置文件db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf-8
name=root
password=
修改config.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>
<!-- 引用db.properties配置文件 -->
<properties resource="db.properties"/>
<!--environments指定数据源环境,default指的是使用哪个数据源 -->
<environments default="development">
<!--environment定义数据源的信息 -->
<environment id="development">
<!-- type="JDBC"表示事务由jdbc连接管理,type="MANAGED"表示事务由容器来管理 -->
<transactionManager type="JDBC" />
<!-- type="POOLED"表示使用连接池, type="UNPOOLED"表示不使用连接池 -->
<dataSource type="POOLED">
<!-- value属性值引用db.properties配置文件中配置的值 -->
<property name="driver" value="${driver}" />
<property name="url" value="${url}" />
<property name="username" value="${name}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/demo/mapping/DeptMapper.xml" />
</mappers>
</configuration>
2.2 别名与自定义别名
2.2.1 内置别名
对常用的 java 类型,已经内置了一些别名支持。这些别名都是不区分大小写的。(详细参看用户手册)
2.2.2 自定义别名
在myBatis的主配置文件config.xml给com.demo.entity.Dept类创建别名Dept,后继的DeptMapper.xml配置文件中可以使用别名
<configuration>
<!-- 引用db.properties配置文件 -->
<properties resource="db.properties"/>
<!-- 通过别名简化对类的使用 -->
<typeAliases>
<typeAlias type="com.demo.entity.Dept" alias="Dept" />
</typeAliases>
<!--environments指定数据源环境,default指的是使用哪个数据源 -->
<environments default="development">
2.3 MyBatisUtil工具类
image.pngpackage com.demo.util;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
private static final ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sessionFactory;
private static String CONFIG_FILE_LOCATION = "config.xml";
static {
try {
buildSessionFactory();
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}
}
private MyBatisUtil() {
}
/**
* Returns the ThreadLocal Session instance. Lazy initialize
* the <code>SessionFactory</code> if needed.
*
* @return Session
* @throws Exception
*/
public static SqlSession getSession() throws Exception {
SqlSession session = (SqlSession) threadLocal.get();
if (session == null) {
if (sessionFactory == null) {
buildSessionFactory();
}
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
/**
* build session factory
*
*/
public static void buildSessionFactory() {
Reader reader = null;
try {
reader = Resources.getResourceAsReader(CONFIG_FILE_LOCATION);
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (Exception e) {
System.err.println("%%%% Error Creating SessionFactory %%%%");
e.printStackTrace();
}finally{
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
/**
* Close the single session instance.
*
*/
public static void closeSession(){
SqlSession session = (SqlSession) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
}
/**
* return session factory
*
*/
public static SqlSessionFactory getSessionFactory() {
return sessionFactory;
}
}
2.3 CRUD操作
2.3.1 新增操作
配置文件DeptMapper.xml使用别名, DeptDaoImpl.java新增方法使用工具类。
修改配置文件DeptMapper.xml(使用别名):
</resultMap>
<!-- 添加一第记录 ; 定义插入的sql语句,通过命名空间+id方式被定位 -->
<insert id="insertDept" parameterType="Dept">
<!-- #{} 用来获取传过来的参数 -->
insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress})
</insert>
</mapper>
修改DeptDaoImpl.java新增方法(使用MyBatisUtil.java工具类):
package com.demo.dao.imp;
import org.apache.ibatis.session.SqlSession;
import com.demo.entity.Dept;
import com.demo.util.MyBatisUtil;
public class DeptDaoImpl {
SqlSession session;
/**
* 用于插入数据到dept表。
* @param dept 部门信息
* @return 表示受影响的行数
*/
public int save(Dept dept){
int i =0;
try {
session = MyBatisUtil.getSession();
i = session.insert("com.demo.entity.DeptMapper.insertDept", dept);
//提交事务
session.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.rollback();
}finally{
try {
MyBatisUtil.closeSession();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return i;
}
}
修改测试代码,DeptTest.java
package com.demo.test;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.imp.DeptDaoImpl;
import com.demo.entity.Dept;
public class DeptTest {
private static DeptDaoImpl deptDaoImpl;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
//在整个类初始化之后调用,一般用来做测试准备工作
deptDaoImpl = new DeptDaoImpl();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
//在整个类结束之前调用,一般作测试的清理工作
deptDaoImpl = null;
}
@Test
public void test() {
Dept dept = new Dept();
dept.setDeptName("财务部");
dept.setDeptAddress("沈阳浑南");
System.out.println("受影响 的行数:"+deptDaoImpl.save(dept));
}
}
测试效果:
image.png image.png
2.3.2 修改操作
修改配置文件deptMapper.xml,添加
<!-- 根据部门编号修改部门信息 -->
<update id="updateDept" parameterType="dept">
update dept set dept_name=#{deptName},dept_address=#{deptAddress}
where dept_id = #{deptId}
</update>
修改DeptDaoImpl.java,添加update方法:
//修改部门信息
public int update(Dept dept){
int i = 0 ;
try {
session = MyBatisUtil.getSession();
i = session.update("com.demo.entity.DeptMapper.updateDept",dept);
session.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.rollback();
}finally{
try {
MyBatisUtil.closeSession();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return i;
}
修改DeptTest.java,添加testUpdate方法:
@Test
public void testUpdate() {
Dept dept = new Dept();
dept.setDeptId(6);
dept.setDeptName("后勤部");
dept.setDeptAddress("沈阳沈北");
System.out.println("受影响 的行数:"+deptDaoImpl.update(dept));
}
测试效果:
image.png image.png
2.3.3 删除操作
修改配置文件deptMapper.xml,添加
<!--根据部门编号删除部门 -->
<delete id="deleteDept" parameterType="integer" >
delete from dept where dept_id = #{deptId}
</delete>
修改DeptDaoImpl.java,添加delete方法:
//根据部门编号删除部门
public int delete(Integer id){
int i = 0 ;
try {
session = MyBatisUtil.getSession();
i = session.delete("com.demo.entity.DeptMapper.deleteDept",id);
session.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
session.rollback();
}finally{
try {
MyBatisUtil.closeSession();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return i;
}
修改DeptTest.java,添加testDelete方法:
@Test
public void testDelete() {
System.out.println("受影响 的行数:"+deptDaoImpl.delete(6));
}
测试效果:
image.png image.png
2.3.4 查询操作(返回单条记录)
配置deptMapper.xml文件的resultMap元素及SQL查询语句
<!-- 表字段和实体属性命名一致时可以不配置 -->
<resultMap id="deptResultMap" type="Dept">
......
</resultMap>
......
<!—返回单条记录,表字段和对应实体属性命名一致时可以不使用resultMap属性配置,直接使用resultType="返回的全类名或别名",建议使用前者;查询结果为所有字段时,也可以用*表示 -->
<!-- 查询单个部门信息 -->
<select id="selectDept" parameterType="integer" resultMap="deptResultMap" >
select dept_id,dept_name,dept_address from dept where dept_id = #{deptId}
</select>
修改DeptDaoImpl.java,添加selectOne方法:
//根据部门编号查询单个部门
public Dept selectOne(Integer id){
Dept dept =null;
try {
session = MyBatisUtil.getSession();
dept = session.selectOne("com.demo.entity.DeptMapper.selectDept",id);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
MyBatisUtil.closeSession();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return dept;
}
修改DeptTest.java,添加testDelete方法:
@Test
public void testSelectOne() {
System.out.println("部门信息:"+deptDaoImpl.selectOne(2));
}
测试效果:
image.png
2.3.5 查询操作(返回多条记录)
修改配置文件deptMapper.xml,添加
<!-- 根据部门地址查询多个部门信息 -->
<!-- 如果返回的是list,resultMap指定的值是list集合里元素的类型-->
<select id="selectList" parameterType="string" resultMap="deptResultMap" >
select dept_id,dept_name,dept_address from dept where dept_address like #{deptAddress}
</select>
修改DeptDaoImpl.java,添加selectList方法:
//根据部门地址查询多个部门
public List<Dept> selectList(String deptAddress){
List<Dept> depts =null;
try {
session = MyBatisUtil.getSession();
depts = session.selectList("com.demo.entity.DeptMapper.selectList",deptAddress);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
MyBatisUtil.closeSession();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return depts;
}
修改DeptTest.java,添加testSelectList方法:
@Test
public void testSelectList() {
List<Dept> depts = deptDaoImpl.selectList("%北%");
for (Dept dept : depts) {
System.out.println("部门信息:"+dept);
}
}
测试效果:
image.png
2.4 使用MyBatis对表执行CRUD操作——基于注解的实现
image.png1、定义sql映射的接口
DeptMapper接口的代码如下:
package com.demo.dao;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.demo.entity.Dept;
public interface DeptMapper {
//使用@Insert注解指明add方法要执行的SQL
@Insert("insert into dept(dept_name,dept_address) values(#{deptName},#{deptAddress})")
public int add(Dept dept);
//使用@Delete注解指明deleteById方法要执行的SQL
@Delete("delete from dept where dept_id = #{deptId}")
public int deleteById(int id);
//使用@Update注解指明update方法要执行的SQL
@Update("update dept set dept_name=#{deptName},dept_address=#{deptAddress} where dept_id = #{deptId}")
public int update(Dept dept);
//使用@Select注解指明getById方法要执行的SQL
@Select("select * from dept where dept_id = #{deptId}")
@Results({
@Result(id = true,column = "dept_id",property="deptId"),
@Result(column="dept_name",property="deptName"),
@Result(column="dept_address",property="deptAddress")
})
public Dept getById(int id);
//使用@Select注解指明getAll方法要执行的SQL
@Select("select * from dept")
@Results({
@Result(id = true,column = "dept_id",property="deptId"),
@Result(column="dept_name",property="deptName"),
@Result(column="dept_address",property="deptAddress")
})
public List<Dept> getAll();
}
需要说明的是,我们不需要针对UserMapperI接口去编写具体的实现类代码,这个具体的实现类由MyBatis帮我们动态构建出来,我们只需要直接拿来使用即可。
2、在conf.xml文件中注册这个映射接口
<mappers>
<!-- 注册UserMapper映射接口-->**
<mapper class="com.demo.dao.DeptMapper"/>**
</mappers>**
测试类代码:TestAnnotation.java
package com.demo.test;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.demo.dao.DeptMapper;
import com.demo.entity.Dept;
import com.demo.util.MyBatisUtil;
public class TestAnnotation {
@BeforeClass
public static void setUpBeforeClass() throws Exception {
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
}
@Test
public void testAdd() throws Exception{
SqlSession sqlSession = MyBatisUtil.getSession();
//得到DeptMapper接口的实现类对象,DeptMapper接口的实现类对象由sqlSession.getMapper(DeptMapper.class)动态构建出来
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDeptName("策划部");
dept.setDeptAddress("铁岭");
int add = mapper.add(dept);
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.commit();
sqlSession.close();
System.out.println(add);
}
@Test
public void testUpdate() throws Exception{
SqlSession sqlSession = MyBatisUtil.getSession();
//得到DeptMapper接口的实现类对象,DeptMapper接口的实现类对象由sqlSession.getMapper(DeptMapper.class)动态构建出来
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDeptId(14);
dept.setDeptName("董事会");
dept.setDeptAddress("大连");
int add = mapper.update(dept);
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.commit();
sqlSession.close();
System.out.println(add);
}
@Test
public void testDelete() throws Exception{
SqlSession sqlSession = MyBatisUtil.getSession();
//得到DeptMapper接口的实现类对象,DeptMapper接口的实现类对象由sqlSession.getMapper(DeptMapper.class)动态构建出来
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
//执行删除操作
int retResult = mapper.deleteById(15);
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.commit();
sqlSession.close();
System.out.println(retResult);
}
@Test
public void testGetDept() throws Exception{
SqlSession sqlSession = MyBatisUtil.getSession();
//得到DeptMapper接口的实现类对象,DeptMapper接口的实现类对象由sqlSession.getMapper(DeptMapper.class)动态构建出来
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
//执行查询操作,将查询结果自动封装成Dept返回
Dept dept = mapper.getById(2);
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.close();
System.out.println(dept);
}
@Test
public void testGetAll() throws Exception{
SqlSession sqlSession = MyBatisUtil.getSession();
//得到DeptMapper接口的实现类对象,DeptMapper接口的实现类对象由sqlSession.getMapper(DeptMapper.class)动态构建出来
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
//执行查询操作,将查询结果自动封装成List<Dept>返回
List<Dept> list = mapper.getAll();
//使用SqlSession执行完SQL之后需要关闭SqlSession
sqlSession.close();
System.out.println(list);
}
}
显示效果
新增效果
image.png
更新效果
image.png
修改效果
image.png
查询效果,按照查询
image.png
查全表
image.png