Mybatis入门概述及第一个Mybatis实例实现增删改查
林炳文Evankaka原创作品。转自https://blog.****.net/Evankaka/article/details/45647401
一、简介
1.什么是MyBatis
MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除 了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java 对象)映射成数据库中的记录。(类似Hibernate)
MyBatis本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。它支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
2. MyBatis和Hibernate比较
1)hibernate是全自动,而mybatis是半自动。hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql。而mybatis仅有基本的字段映射,对象数据以及对象实际关系仍然需要通过手写sql来实现和管理。
2)hibernate数据库移植性远大于mybatis。hibernate通过它强大的映射结构和hql语言,大大降低了对象与数据库(oracle、mysql等)的耦合性,而mybatis由于需要手写sql,因此与数据库的耦合性直接取决于程序员写sql的方法,如果sql不具通用性而用了很多某数据库特性的sql语句的话,移植性也会随之降低很多,成本很高。
3)hibernate拥有完整的日志系统,mybatis则欠缺一些。hibernate日志系统非常健全,涉及广泛,包括:sql记录、关系异常、优化警告、缓存提示、脏数据警告等;而mybatis则除了基本记录功能外,功能薄弱很多。
4)mybatis相比hibernate需要关心很多细节。hibernate配置要比mybatis复杂的多,学习成本也比mybatis高。但也正因为mybatis使用简单,才导致它要比hibernate关心很多技术细节。mybatis由于不用考虑很多细节,开发模式上与传统jdbc区别很小,因此很容易上手并开发项目,但忽略细节会导致项目前期bug较多,因而开发出相对稳定的软件很慢,而开发出软件却很快。hibernate则正好与之相反。但是如果使用hibernate很熟练的话,实际上开发效率丝毫不差于甚至超越mybatis。
5)sql直接优化上,mybatis要比hibernate方便很多。由于mybatis的sql都是写在xml里,因此优化sql比hibernate方便很多。而hibernate的sql很多都是自动生成的,无法直接维护sql;虽有hql,但功能还是不及sql强大,见到报表等变态需求时,hql也歇菜,也就是说hql是有局限的;hibernate虽然也支持原生sql,但开发模式上却与orm不同,需要转换思维,因此使用上不是非常方便。总之写sql的灵活度上hibernate不及mybatis。 6)Hibernate有更好的二级缓存机制,可以使用第三方缓存。而MyBatis的二级缓存机制不佳。
Mybatis的功能架构分为三层
1) API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
2) 数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
3) 基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
二、使用范例
1、打开MYsql,新建一个表。
-
use test;
-
create table t_employeer(
-
employeer_id int not null primary key AUTO_INCREMENT ,
-
employeer_name varchar(50) default null,
-
employeer_age int default null,
-
employeer_department varchar(100) default null,
-
employeer_worktype varchar(100) default null
-
)
2、新建一个Java工程,导入需要用的包。mybatis-3.2.8.jar+mysql-connector-java-5.1.22-bin.jar
3、新建一个Mybatis配置文件:
-
<?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>
-
<!-- 元素允许在主配置文件之外提供一个properties格式对应文件,从而使得主配置文件更加通用。这样对部署非常有用 -->
-
<!-- <properties resource="mysql.properties" /> -->
-
<!-- 设置别名,一定要放在properties下面 -->
-
<typeAliases>
-
<typeAlias alias="Employeer" type="com.mucfc.model.Employeer" />
-
</typeAliases>
-
<!-- 配置数据源相关的信息 -->
-
<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/test?characterEncoding=UTF-8"/>
-
<property name="username" value="root"/>
-
<property name="password" value="[email protected]"/>
-
<!--<property name="driver" value="${driver}" />
-
<property name="url" value="${url}" />
-
<property name="username" value="${username}" />
-
<property name="password" value="${password}" /> -->
-
</dataSource>
-
</environment>
-
</environments>
-
<!-- 列出映射文件 -->
-
<mappers>
-
<mapper resource="com/mucfc/model/Employeer.xml" />
-
</mappers>
-
</configuration>
数据源的配置方法也可以写成:
-
<?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>
-
<!-- 元素允许在主配置文件之外提供一个properties格式对应文件,从而使得主配置文件更加通用。这样对部署非常有用 -->
-
<properties resource="mysql.properties" />
-
<!-- 设置别名,一定要放在properties下面 -->
-
<typeAliases>
-
<typeAlias alias="Employeer" type="com.mucfc.model.Employeer" />
-
</typeAliases>
-
<!-- 配置数据源相关的信息 -->
-
<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/test?characterEncoding=UTF-8"/>
-
<property name="username" value="root"/>
-
<property name="password" value="[email protected]"/> -->
-
<property name="driver" value="${driver}" />
-
<property name="url" value="${url}" />
-
<property name="username" value="${username}" />
-
<property name="password" value="${password}" />
-
</dataSource>
-
</environment>
-
</environments>
-
<!-- 列出映射文件 -->
-
<mappers>
-
<mapper resource="com/mucfc/model/Employeer.xml" />
-
</mappers>
-
</configuration>
mysql.properties如下:
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/test?charset=utf8 username=root
上面两种方法都可以用,但每次只能用一个。
3、新建表对应的类:
-
package com.mucfc.model;
-
-
import java.io.Serializable;
-
-
/**
-
* 雇员信息类
-
*@author linbingwen
-
*@time 2015.5.11
-
*/
-
public class Employeer {
-
private Integer employeer_id;
-
private String employeer_name;
-
private Integer employeer_age ;
-
private String employeer_department;
-
private String employeer_worktype;
-
-
public Employeer() {
-
super();
-
}
-
public Integer getEmployeer_id() {
-
return employeer_id;
-
}
-
public void setEmployeer_id(Integer employeer_id) {
-
this.employeer_id = employeer_id;
-
}
-
public String getEmployeer_name() {
-
return employeer_name;
-
}
-
public void setEmployeer_name(String employeer_name) {
-
this.employeer_name = employeer_name;
-
}
-
public Integer getEmployeer_age() {
-
return employeer_age;
-
}
-
public void setEmployeer_age(Integer employeer_age) {
-
this.employeer_age = employeer_age;
-
}
-
public String getEmployeer_department() {
-
return employeer_department;
-
}
-
public void setEmployeer_department(String employeer_department) {
-
this.employeer_department = employeer_department;
-
}
-
public String getEmployeer_worktype() {
-
return employeer_worktype;
-
}
-
public void setEmployeer_worktype(String employeer_worktype) {
-
this.employeer_worktype = employeer_worktype;
-
}
-
@Override
-
public String toString() {
-
return "Employeer [employeer_id=" + employeer_id + ", employeer_name="
-
+ employeer_name + ", employeer_age=" + employeer_age
-
+ ", employeer_department=" + employeer_department
-
+ ", employeer_worktype=" + employeer_worktype + "]";
-
}
-
-
-
-
}
4、配置数据映射,这是本文的一个重点内容
-
<?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.mucfc.model.EmployeerMapper">
-
-
<!-- 查找 -->
-
<select id="findEmployeerByID" parameterType="int" resultType="Employeer">
-
select* from `t_employeer` where employeer_id =#{employeer_id}
-
</select>
-
-
<!-- 插入 -->
-
<!-- useGeneratedKeys设置为"true"表明要MyBatis获取由数据库自动生成的主键;keyProperty="id"指定把获取到的主键值注入到Employeer的id属性 -->
-
<insert id="addEmployeer" parameterType="Employeer"
-
useGeneratedKeys="true" keyProperty="employeer_id">
-
insert into `t_employeer`(employeer_name,employeer_age,employeer_department,employeer_worktype)
-
values(#{employeer_name},#{employeer_age},#{employeer_department},#{employeer_worktype})
-
</insert>
-
-
<!-- 删除 -->
-
<delete id="deleteEmployeer" parameterType="int">
-
delete from `t_employeer` where employeer_id = #{employeer_id}
-
</delete>
-
-
<!-- 修改 -->
-
<update id="updateEmployeer" parameterType="Employeer">
-
update t_employeer set employeer_name = #{employeer_name},employeer_age= #{employeer_age},employeer_department = #{employeer_department}
-
,employeer_worktype=#{employeer_worktype} where employeer_id = #{employeer_id}
-
</update>
-
-
</mapper>
5、测试类:
-
package com.mucfc.test;
-
-
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;
-
-
import com.mucfc.model.Employeer;
-
-
public class MybatisTest {
-
private static SqlSessionFactory sqlSessionFactory;
-
private static Reader reader;
-
static {
-
try {
-
reader = Resources.getResourceAsReader("mybatis-config.xml");
-
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
-
-
/**
-
* 查找
-
*/
-
public static void findEmployeerById(int id) {
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
Employeer employeer = (Employeer) session.selectOne(
-
"com.mucfc.model.EmployeerMapper.findEmployeerByID", 1);
-
if (employeer == null)
-
System.out.println("null");
-
else
-
System.out.println(employeer);
-
} finally {
-
session.close();
-
}
-
}
-
/**
-
* 增加
-
*/
-
public static void addEmployeer(Employeer employeer){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
//返回值是记录条数
-
int resultCount = session.insert("com.mucfc.model.EmployeerMapper.addEmployeer", employeer );
-
System.out.printf("当前插入的employeer_id :%d 当前插入数据库中条数:%d " , employeer.getEmployeer_id() ,resultCount); //获取插入对象的id
-
System.out.println("");
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
-
}
-
/**
-
* 删除
-
*
-
*/
-
public static void deleteEmployeer(int id){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
//返回值是记录条数
-
int resultCount=session.delete("com.mucfc.model.EmployeerMapper.deleteEmployeer",id);
-
System.out.println("当前删除数据库中条数: "+resultCount); //获取插入对象的id
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
}
-
/**
-
* 更改
-
*/
-
public static void updateEmployeer(Employeer employeer){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
session.update("com.mucfc.model.EmployeerMapper.updateEmployeer",employeer);
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
-
}
-
-
public static void main(String[] args) {
-
-
-
-
-
-
-
Employeer employeer1=new Employeer();
-
employeer1.setEmployeer_name("李四");
-
employeer1.setEmployeer_age(23);
-
employeer1.setEmployeer_department("产品一部");
-
employeer1.setEmployeer_worktype("开发工程师");
-
-
Employeer employeer2=new Employeer();
-
employeer2.setEmployeer_name("张三");
-
employeer2.setEmployeer_age(30);
-
employeer2.setEmployeer_department("产品二部");
-
employeer2.setEmployeer_worktype("测试工程师");
-
-
Employeer employeer3=new Employeer();
-
employeer3.setEmployeer_name("小王");
-
employeer3.setEmployeer_age(22);
-
employeer3.setEmployeer_department("产品三部");
-
employeer3.setEmployeer_worktype("数据分析师");
-
-
-
Employeer employeer4=new Employeer();
-
employeer4.setEmployeer_name("明明");
-
employeer4.setEmployeer_age(22);
-
employeer4.setEmployeer_department("财会部");
-
employeer4.setEmployeer_worktype("财务人员");
-
-
//插入
-
addEmployeer(employeer1);
-
addEmployeer(employeer2);
-
addEmployeer(employeer3);
-
addEmployeer(employeer4);
-
//查找
-
findEmployeerById(1);
-
//删除
-
deleteEmployeer(1);
-
//更改
-
employeer2.setEmployeer_id(2);
-
employeer2.setEmployeer_age(21);
-
employeer2.setEmployeer_department("产品三部");
-
updateEmployeer(employeer2);
-
-
}
-
-
}
下面一个一个来分析
(1)插入测试
函数 :
-
/**
-
* 增加
-
*/
-
public static void addEmployeer(Employeer employeer){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
//返回值是记录条数
-
int resultCount = session.insert("com.mucfc.model.EmployeerMapper.addEmployeer", employeer );
-
System.out.printf("当前插入的employeer_id :%d 当前插入数据库中条数:%d " , employeer.getEmployeer_id() ,resultCount); //获取插入对象的id
-
System.out.println("");
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
-
}
调用
-
//插入
-
addEmployeer(employeer1);
-
addEmployeer(employeer2);
-
addEmployeer(employeer3);
-
addEmployeer(employeer4);
数据库中结果:
(2)查找测试,接上面插入测试:
函数:
-
/**
-
* 查找
-
*/
-
public static void findEmployeerById(int id) {
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
Employeer employeer = (Employeer) session.selectOne(
-
"com.mucfc.model.EmployeerMapper.findEmployeerByID", 1);
-
if (employeer == null)
-
System.out.println("null");
-
else
-
System.out.println(employeer);
-
} finally {
-
session.close();
-
}
-
}
调用:
-
//查找
-
findEmployeerById(1);
结果(3)删除测试,接上面
其中函数:
-
/**
-
* 删除
-
*
-
*/
-
public static void deleteEmployeer(int id){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
//返回值是记录条数
-
int resultCount=session.delete("com.mucfc.model.EmployeerMapper.deleteEmployeer",id);
-
System.out.println("当前删除数据库中条数: "+resultCount); //获取插入对象的id
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
}
调用
deleteEmployeer(1);
结果
第1条记录被删除了
(4)修改数据
这是之前
函数:
-
/**
-
* 更改
-
*/
-
public static void updateEmployeer(Employeer employeer){
-
SqlSession session = null;
-
try {
-
session = sqlSessionFactory.openSession();
-
session.update("com.mucfc.model.EmployeerMapper.updateEmployeer",employeer);
-
session.commit() ;
-
} finally {
-
session.close();
-
}
-
-
}
调用:
-
//更改
-
employeer2.setEmployeer_id(2);
-
employeer2.setEmployeer_age(21);
-
employeer2.setEmployeer_department("产品三部");
-
updateEmployeer(employeer2);
这是之后
张三的信息成功被改