mybatis
一、简介
1.名称由来
Mybatis原名叫ibatis.Mybatis一开始属于Apache,2010年从Apache转移到了GoogleCode这个组织中.
2.Mybatis概念
Mybatis是一种基于ORM模式的,作用于Dao层的轻量级框架.和Hibernate类似,也支持各种SQL语句,也支持存储过程和高级映射等操作.
3.Mybatis优点
Mybatis比Hibernate更为轻量级;
Mybatis几乎消除了所有的JDBC代码和参数的手工设置.
4.Mybatis特点
Mybatis具有比较强大的动态语句功能.而且Mybatis在JavaBean和表之间的映射关系建立方面,也更加的便捷灵活.
5.Mybatis的核心API
①.SqlSessionFactoryBuilder:
SqlSessionFactoryBuilder是整个Mybatis框架的入口,提供了一个build()方法,用来创建SqlSessionFactory对象. SqlSessionFactoryBuilder对象一般是在xml文件中通过configuration节点来进行配置.
②.SqlSessionFactory:
用来创建SqlSession.注意:该对象一般只用创建一个对象就可以,也就是不要重复创建该对象!
③.SqlSession:
SqlSession用来实现数据库的各种增删改查操作.
注意:
因为SqlSession对象不是线程安全的,所以在使用该对象的时候,要确保该对象不能被多个方法所共享,当用完该对象之后,就要把该对象close()掉.
6.Mybatis和Hibernate对比
Hibernate相对来说较重,使用和配置起来较麻烦,内存占用和资源消耗较多;Hibernate的查询效率并不突出;Hibernate的入门门槛较高.Hibernate里面的API方法及功能较多.
Mybatis相对来说较轻,.......;Mybatis学习成本较低.
Mybatis相对于Hibernate来说API较少,比较单薄.
二、配置与使用
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis让程序将主要精力放在sql上,通过MyBatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
MyBatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)
1.利用maven工厂导入所需要的jar包
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.0.7</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.7</version>
</dependency>
2:创建db.properties.xml文件
该文件用来简化数据库的连接配置,以后数据库有更改,直接在这个文件里面修改即可,可以添加多种不同的数据库。我的如下
mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/sql05 mysql.username=root mysql.password=123 orcl.driver=oracle.jdbc.driver.OracleDriver orcl.url=jdbc:oracle:thin:@localhost:1521:orcl orcl.username=scott orcl.password=123
3.创建mybatis.xml配置文件
首先引用db.properties.xml文件,
就可以引用db.properties的配置文件了。
如果是mysql的数据库的话,就加载mysql_conn
管理数据源的时候
<property name="driver" value="${mysql.driver}" />
<property name="url" value="${mysql.url}" />
<property name="username" value="${mysql.username}" />
<property name="password" value="${mysql.password}" />
mysql.driver一些分别对应着之前写db.properties配置文件。
接着加载映射文件,加载的映射文件用于配置数据库链接的一些操作
<!-- 加载映射文件 -->
<mappers>
<mapper resource="PersonMapper.xml"/>
</mappers>
4.创建PersonMapper.xml映射文件
<?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">
<!-- namespace:这里的值,可以随便写!但是要保证它的值唯一.一般开发过程中,都是JavaBean的全路径. -->
<mapper namespace="com.syc.dao.domain.Person">
<!-- type:要操作的JavaBean的全路径 -->
<!-- resultMap:建立起JavaBean和表的映射关系 -->
<!-- 直接引用别名 -->
<resultMap type="person" id="personMap">
<!-- id:表示主键 -->
<id column="pid" property="pid" />
<!-- result:普通列 -->
<result column="name" property="name" />
<result column="nickname" property="nickname" />
</resultMap>
<!-- insert:添加操作的标签,id:用来引用该标签 -->
<insert id="insertPerson">
insert into person (name,nickname)
values('王小二','店小二')
</insert>
<!-- 带参数的标签 -->
<insert id="insertPersonWithParams" parameterType="person">
insert into
person (name,nickname)
values(#{name},#{nickname})
</insert>
<!-- 查询标签 -->
<!-- resultMap:集合的泛型类 -->
<select id="findAll" resultMap="personMap">
select * from person
</select>
<select id="findById" resultType="person" parameterType="int">
select *
from person
where pid=#{pid}
</select>
<!-- 修改 -->
<update id="updateById" parameterType="person">
update person set
name=#{name},nickname=#{nickname}
where pid=#{pid}
</update>
<!-- 删除 -->
<delete id="deleteById" parameterType="person">
delete from person
where pid=#{pid}
</delete>
<!-- 注意:除了查询之外,其他的操作,增删改操作的,起始和标签名称没有关系! -->
<delete id="insertWithDeleteTag" parameterType="person">
insert into
person (name,nickname)
values(#{name},#{nickname})
</delete>
</mapper>
5.创建MybatisUtil工具类,加载配置文件
package com.syc.dao.utils;
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 SqlSessionFactory factory;
// 解决资源争抢问题.
private static ThreadLocal<SqlSession> localSessions = new ThreadLocal<SqlSession>();
static {
Reader reader = null;
try {
// 加载Mybatis的配置文件
reader = Resources.getResourceAsReader("mybatis.xml");
// 创建SqlSessionFactory对象.
factory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
// 获取Session对象
public static SqlSession getSession() {
SqlSession session = localSessions.get();
if (session == null) {
session = factory.openSession();
localSessions.set(session);
}
return session;
}
// 关闭session的方法
public static void closeSession() {
SqlSession session = localSessions.get();
if (session != null) {
session.close();
localSessions.remove();
}
}
}
创建session对象:
6.创建Person类。
private Integer pid; //id
private String name; //姓名
private String nickname; //称呼
7.创建PersonDao类,执行具体的CRUD操作
三、常见用法
MyBatis框架执行过程:
1、配置MyBatis的配置文件,SqlMapConfig.xml(名称不固定)
2、通过配置文件,加载MyBatis运行环境,创建SqlSessionFactory会话工厂
SqlSessionFactory 在实际使用时按单例方式。
3、通过SqlSessionFactory创建SqlSession
SqlSession 是一个面向用户接口(提供操作数据库方法),实现对象是线程不安全的,建议sqlSession应用场合在方法体内。
4、调用 sqlSession 的方法去操作数据。
如果需要提交事务,需要执行 SqlSession 的 commit() 方法。
5、释放资源,关闭SqlSession
新建一个工程用于描述这些用法。
编写User.java类
package cn.itcast.mybatis.po;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
public class User implements Serializable {
//属性名和数据库表的字段对应
private int id;
private String username;// 用户姓名
private String sex;// 性别
private Date birthday;// 生日
private String address;// 地址
//用户创建的订单列表
private List<Orders> ordersList;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
public List<Orders> getOrdersList() {
return ordersList;
}
public void setOrdersList(List<Orders> ordersList) {
this.ordersList = ordersList;
}
}
编写User.xml映射文件
<?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">
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
<mapper namespace="test">
<!-- 在 映射文件中配置很多sql语句 -->
<!-- 需求:通过id查询用户表的记录 -->
<!-- 通过 select执行数据库查询
id:标识 映射文件中的 sql
将sql语句封装到mappedStatement对象中,所以将id称为statement的id
parameterType:指定输入 参数的类型,这里指定int型
#{}表示一个占位符号
#{id}:其中的id表示接收输入 的参数,参数名称就是id,如果输入 参数是简单类型,#{}中的参数名可以任意,可以value或其它名称
resultType:指定sql输出结果 的所映射的java对象类型,select指定resultType表示将单条记录映射成的java对象。
-->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>
<!-- 根据用户名称模糊查询用户信息,可能返回多条
resultType:指定就是单条记录所映射的java对象 类型
${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
使用${}拼接sql,引起 sql注入
${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!-- 添加用户
parameterType:指定输入 参数类型是pojo(包括 用户信息)
#{}中指定pojo的属性名,接收到pojo对象的属性值,MyBatis通过OGNL获取对象的属性值
-->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<!--
将插入数据的主键返回,返回到user对象中
SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
<!--
使用MySQL的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
-->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) -->
</insert>
<!-- 删除 用户
根据id删除用户,需要输入 id值
-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<!-- 根据id更新用户
分析:
需要传入用户的id
需要传入用户的更新信息
parameterType指定user对象,包括 id和更新信息,注意:id必须存在
#{id}:从输入 user对象中获取id属性值
-->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper>
配置SqlMapConfig.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>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由MyBatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由MyBatis管理-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<!--通过resource方法一次加载一个映射文件 -->
<!-- <mapper resource="mapper/UserMapper.xml"/> -->
<!-- 通过mapper接口加载单个 映射文件
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
<!-- 批量加载mapper
指定mapper接口的包名,MyBatis自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录 中
上边规范的前提是:使用的是mapper代理方法
-->
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
</configuration>
查找
对应的User.xml中的statement
模糊查找
对应的User.xml中的statement
插入
对应的User.xml中的statement
删除
对应的User.xml中的statement
修改
对应的User.xml中的statement
parameterType
在映射文件中通过parameterType指定输入 参数的类型。
对于综合查询,建议parameterType使用包装的pojo,(将各种pojo包装在一个单独的类)有利于系统 扩展。
resultType
在映射文件中通过resultType指定输出结果的类型。查询到的列名和resultType指定的pojo的属性名一致,才能映射成功。
reusltMap
可以通过resultMap 完成一些高级映射。
如果查询到的列名和映射的pojo的属性名不一致时,通过resultMap设置列名和属性名之间的对应关系(映射关系)。可以完成映射。
高级映射:
将关联查询的列映射到一个pojo属性中。(一对一)
将关联查询的列映射到一个List<pojo>中。(一对多)

浙公网安备 33010602011771号