Mybatis(iBatis)简介:
(前身为iBatis)MyBatis是一个可以自定义SQL,存储过程和高级映射的持久层框架。MyBatis消除了几乎所以是JDBC代码和参数的手工设置以及结果集的检索。MyBatis可以使用简单的XML或注解用于配制和原始映射,将接口和JavaPOJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
作用:封装了JDBC操作,简化了数据库的访问
功能如下:——封装了获取连接,执行SQL,释放连接
——封装了SQL参数设置
——封装了记录映射成实体对象的过程,实体类的属性名与结果查询结果集ResultSet中列名保持一致
开发者:写SQL和实体类,然后使用SqlSession对象执行sql操作
MyBatis体系结构主要由以下几个关键部分
(1)加载配置
配置有两种形式,一种是XML配置文件,另一种是Java代码的注解。MyBatis将SQL的配置信息加载成为一个个MappdStatement对象(
包括了传入参数映射配置,执行的SQL语句,结果映射配置),并将其存储在内存中。
(2)SQL解析
当API接口层接收到调用请求时,会接收到传入SQL的ID和传入对象(可以是Map,JavaBean或者基本数据类型)MyBatis会根据SQL的ID找到对应的MappedStatement,然后根据传入参数对象对MappedStatement进行解析,解析后可以得到最终要执行的SQL语句和参数。
(3)SQL执行
将最终得到的SQL和参数拿到数据库进行执行,得到操作数据库的结果
(4)结果映射
将操作数据库的结果按照映射的配置进行转换,可以转换成HashMap,JavaBean或者数据类型,并将最终结果返回。
MyBatis配置文件
MyBatis框架的XML配置文件包含以下两种类型
(1)SqlMapConfig.xml(1个)
主配置文件,用于指定数据库连接参数和框架参数
(2)SqlMap.xml(n个)
映射定义文件,用于定义SQL语句和映射信息
MyBatis框架API
在使用MyBatis框架时,主要涉及以下几个API
(1)SqlSessionFactoryBuilder
该对象负责根据MyBatis配置文件SqlMapConfig.xml构建SqlSessionFactory实例
(2)SqlSessionFactory
每一个MyBatis的应用程序都以一个SqlSessionFactory对象为核心。该对象负责创建SqlSession对象实例
(3)SqlSession
该对象包含了所以执行SQL操作的方法,用于执行已映射的SQL语句
MyBatis主要流程结构:
1.在使用MyBatis之前,需要将MyBatis框架添加到工程中,主要步骤如下:
1)为工程添加MyBatis开发包和数据库驱动包
2)在src下添加MyBatis配置文件SqlMapConfig.xml
3)修改SqlMapConfig.xml,指定数据库连接参数
4)利用MyBatis API编程,获取SqlSession实例
2.当获取SqlSession对象后,就可以利用它对数据表执行增删改查操作了,使用步骤如下:
1)根据数据表编写实体类(Java POJO)
2)编写SqlMap.xml映射文件,定义SQL操作和映射信息
3)获取SqlSession对象,执行增删改查操作
4)提交事务(DML操作)
5)释放SqlSession对象资源
具体操作:
(1)SqlMapConfig.xml(指定数据库连接参数和SQL定义文件)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<!-- 配置连接参数 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql:///jsd1507db?useUnicode=true&characterEncoding=utf-8" />
<property name="username" value="system" />
<property name="password" value="wyt000000" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 声明所有的mapper.xml -->
<mapper resource="org/web/entity/EmpMapper.xml" />
</mappers>
</configuration>
(2)引入jar包(驱动包.mybatis包)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.web</groupId>
<artifactId>springMyBatis</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>springMyBatis Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!-- 添加jstl依赖 -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<!-- Spring依赖包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- mybatis依赖包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.8</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mysqly依赖包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 阿里巴巴数据源的jar包依赖 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.18</version>
</dependency>
</dependencies>
<build>
<finalName>springMyBatis</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat6-maven-plugin</artifactId>
<version>2.3-SNAPSHOT</version>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.3-SNAPSHOT</version>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
(3)编写实体类(要求属性名与数据表中字段名保持一致) 如:Emp
package org.web.entity;
import java.io.Serializable;
public class Emp implements Serializable{
//属性名与emp表字段一致
private Integer id;
private String name;
private Double salary;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
(4)编写SQL.xml(定义sql) 实现增删改查 如:EmpMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- resultType:查询结果的返回类型,映射对象类型 -->
<mapper namespace="empsql">
<select id="findAll" resultType="org.web.entity.Emp">
select * from emp
</select>
<!-- parameterType:传入参数的类型 例如name的类型为string -->
<select id="findLikeName" parameterType="string" resultType="org.web.entity.Emp">
select * from emp where name like #{name}
</select>
<select id="findById" parameterType="int" resultType="org.web.entity.Emp">
select * from emp where id=#{id}
</select>
<insert id="save" parameterType="org.web.entity.Emp">
insert into emp (name,salary,age) values (#{name},#{salary},#{sag})
</insert>
<!-- session.delete(id,16) -->
<delete id="delete" parameterType="int">
delete from emp where id=#{eid}
</delete>
<!-- session.update(id,emp) -->
<update id="updateSalary" parameterType="org.web.entity.Emp">
update emp set salary=#{salary} where id=#{id}
</update>
</mapper>
(5)获取SqlSession对象
package test;
import java.io.InputStream;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MyBatisUtil {
public static SqlSession getSqlSession(){
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//加载SqlMapConfig.xml
String conf="SqlMapConfig.xml";
//将文件变为流
InputStream confStream=MyBatisUtil.class.getClassLoader().getResourceAsStream(conf);
//获取SqlsessionFactory
SqlSessionFactory factory=builder.build(confStream);
//获取SqlSession
SqlSession session=factory.openSession();
return session;
}
}
(6)测试如下:
package test;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.util.List;
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 org.web.entity.Emp;
public class Testemp {
public static void main(String[] args) throws IOException {
SqlSession session=MyBatisUtil.getSqlSession();
//测试多行查询
//list集合的形式返回查询的数据
//List<Emp> list=session.selectList("findAll");
//自动封装为Emp类型
List<Emp> list=session.selectList("findLikeName","%张%");
for(Emp e:list){
System.out.println(e.getName());
}
//测试单行查询
Emp emp=session.selectOne("findById",18);
if(emp!=null){
System.out.println(emp.getName());
}else{
System.out.println("未查询到记录");
}
//测试添加,不会自动提交事务,需要commit一下
Emp emp1=new Emp();
emp1.setName("scott");
emp1.setSalary(5000.0);
emp1.setAge(20);
session.insert("save",emp1);
session.commit();//提交事务,增删改操作必须做事务提交
//测试更新工资、
Emp emp2=new Emp();
emp2.setId(20);
emp2.setSalary(8000.0);
session.update("updateSalary",emp2);
session.commit(); //提交事务,增删改操作必须做事务提交
session.close();
}
}
使用MyBatis返回的数据类型:
(1)实体对象:
实体类:
package org.web.entity;
import java.io.Serializable;
import java.util.Date;
public class Cost implements Serializable{
private int cost_id;
private String name;
private int base_duration;
private int base_cost;
private int unit_cost;
private String status;
private String descr;
private Date creatime;
private Date startime;
public int getCost_id() {
return cost_id;
}
public void setCost_id(int cost_id) {
this.cost_id = cost_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getBase_duration() {
return base_duration;
}
public void setBase_duration(int base_duration) {
this.base_duration = base_duration;
}
public int getBase_cost() {
return base_cost;
}
public void setBase_cost(int base_cost) {
this.base_cost = base_cost;
}
public int getUnit_cost() {
return unit_cost;
}
public void setUnit_cost(int unit_cost) {
this.unit_cost = unit_cost;
}
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public String getDescr() {
return descr;
}
public void setDescr(String descr) {
this.descr = descr;
}
public Date getCreatime() {
return creatime;
}
public void setCreatime(Date creatime) {
this.creatime = creatime;
}
public Date getStartime() {
return startime;
}
public void setStartime(Date startime) {
this.startime = startime;
}
public String getCost_type() {
return cost_type;
}
public void setCost_type(String cost_type) {
this.cost_type = cost_type;
}
private String cost_type;
}
1)当实体类属性名与字段名一致时,使用resultType
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- resultType:查询结果的返回类型,映射对象类型 -->
<mapper namespace="org.web.dao.CostDao">
<select id="findCost" resultType="org.web.entity.CostBean1">
select cost_id,name,status,creatime from cost
</select>
</mapper>
2)当属性名与字段名不一致时:给字段使用别名,使它与属性名一致,使用resultMap代替resultType定义如何装载数据
需要使用<resultMap>元素显示指定映射关系。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- resultType:查询结果的返回类型,映射对象类型 -->
<mapper namespace="org.web.dao.CostDao">
<!-- resultType:默认按照名称匹配装载数据 -->
<!-- resultMap属性(自定义):按照指定定义规则装载数据-->
<!-- 当属性名誉字段名不一致时,使用别名 -->
<select id="findCost" resultMap="costMap">
select cost_id,name,status,creatime from cost
</select>
<resultMap type="org.web.entity.CostBean1" id="costMap">
<!-- 主键字段定义 -->
<id property="id" column="cost_id"/>
<!-- 非主键字段定义 -->
<result property="name" column="name"/>
<result property="status" column="status"/>
<result property="createTime" column="createTime"/>
</resultMap>
</mapper>
(2)Map集合
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- resultType:查询结果的返回类型,映射对象类型 -->
<mapper namespace="org.web.dao.CostDao">
<!-- 查询字段较少时,最好选择map封装 -->
<select id="findMap" resultType="map">
select cost_id,name from cost
</select>
</mapper>
测试:
package test;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.web.dao.CostDao;
import org.web.entity.Cost;
import org.web.entity.CostBean1;
import org.web.util.MyBatisUtil;
public class TestCost {
public static void main(String[] args) {
SqlSession session=MyBatisUtil.getSession();
//测试返回Map结果
List<Map<String,Object>> list2=session.selectList("findMap");
for(Map<String,Object> data:list2){
System.out.println(data.get("cost_id")+" "+data.get("name"));
}
session.close();
}
}
(3)基本值
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<!-- resultType:查询结果的返回类型,映射对象类型 -->
<mapper namespace="org.web.dao.CostDao">
<select id="findRows" resultType="int">
select count(*) from cost
</select>
</mapper>
测试:
package test;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.web.dao.CostDao;
import org.web.entity.Cost;
import org.web.entity.CostBean1;
import org.web.util.MyBatisUtil;
public class TestCost {
public static void main(String[] args) {
SqlSession session=MyBatisUtil.getSession();
//测试返回单个值
int rows=session.selectOne("findRows");
System.out.println("记录数"+rows);
}
使用Mapper映射器
Mapper映射器是开发者创建绑定映射语句的借口,映射接口的实例可以从SqlSession中获得
SqlSession session=sqlSessionFactory.openSession();
try{
CostDao mapper=session.getMapper(CostDao.class)
}finally{
session.close();
}
CostMapper接口定义如下:
package org.web.dao;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.session.SqlSession;
import org.web.entity.Cost;
import org.web.util.MyBatisUtil;
//定义映射接口,不需要写实现类,会在内存中动态自动构建
public interface CostDao {
public List<Cost> findAll();
public List<Cost> findPage(int begin);
public List<Map<String,Object>> findMap();
public int findRows();
}
Mapper映射器接口规则
1)根据SQL定义的id属性当接口方法名
2)根据SQL定义的parameterType类型当方法参数
3)根据SQL定义的resultType类型当方法的返回类型:多行使用List<泛型>;单行使用 泛型;
4)将SQL定义文件<mapper>的namespace属性指定成"包名.接口名"
来源:https://www.cnblogs.com/peachwang/p/7363331.html