mybatis从零到一学习实战
mybatis介绍
mybatis是一个简化java操作数据的操作的,简化开发,增加小路的框架(JDBC的封装)
依赖的引入
主要是mybatis的依赖和mysql数据的依赖,本次测试是使用的mysql数据库
<!-- mybatis的依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- mysql驱动的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- 单元测试可以不加入 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
配置数据库连接
在resouces目录里面创建mybatis-config.xml文件,里面用来配置数据库的链接数据文件内容如下:里面的具体配置需要自己进行修改,主要是driver url username password对应的value。
<?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>
<!-- 给类起别名 -->
<typeAliases>
<typeAlias type="cn.pengpeng.domain.Order" alias="_Order"/>
</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/mybatis?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!-- map映射文件 -->
<mappers>
<mapper resource="UserMapper.xml" />
<mapper resource="OrderMapper.xml" />
</mappers>
</configuration>
配置完后可以测试下,使用一下代码用来测试mybatis链接数据库
public class App {
public static void main(String[] args) {
try {
//指定配置文件的路径(类路径)
String resource = "mybatis-config.xml";
//加载文件
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//创建会话工厂Builder,相当于连接池
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
//通过sf开启会话,相当于打开连接。
SqlSession s = sf.openSession();
//输出测试是否有异常
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
单表的增删改查
创建数据库
mysql>create database mybatis ;
mysql>use mybatis ;
mysql>create table users(id int primary key auto_increment , name varchar(20) ,age int) ;
创建users表对应的javabean
package cn.pengpeng.domain;
import java.util.List;
/**
* Created by root on 2018/12/25.
*/
public class User {
private int id;
private String name;
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
创建Users.java跟数据库映射文件
创建UserMapper.xml,存放在resources/目录下
<?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="users">
<!-- 定义insert语句 -->
<insert id="insert">
insert into users(name,age) values(#{name},#{age})
</insert>
</mapper>
测试是否可用
package cn.pengpeng;
import cn.pengpeng.domain.User;
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 java.io.IOException;
import java.io.InputStream;
/**
* 测试javabean跟数据库的联通性,
* 具体的sql是UserMapper.xml里面的写的
*/
public class App {
public static void main(String[] args) {
try {
//指定配置文件的路径(类路径)
String resource = "mybatis-config.xml";
//加载文件
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//创建会话工厂Builder,相当于连接池
SqlSessionFactory sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
//通过sf开启会话,相当于打开连接。
SqlSession s = sf.openSession();
User u = new User();
u.setName("明明");
u.setAge(3);
// users 是UserMapper.xml里面的 namespace="users" insert 是<insert id="insert" >
s.insert("users.insert",u);
s.commit();
s.close();
System.out.println(s);
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行后可以去数据库里面查看下,是否有数据插入,插入数据说明是可行的。
多表关联数据测试
创建表
创建三张表,items,orders,users表,并且给三张表进行插入数据。
表关系为:一个users会有多个orders,一个orders又会有多个items
use mybatis ;
-- 删除表
drop table if exists items ;
drop table if exists orders ;
drop table if exists users ;
-- 创建表
create table users(id int primary key auto_increment , name varchar(20) , age int);
create table orders(id int primary key auto_increment , orderno varchar(20) , uid int);
create table items(id int primary key auto_increment , itemname varchar(20) , oid int);
-- 插入用户
insert into users(name,age) values('tom',12);
insert into users(name,age) values('tomas',13);
-- 插入订单
insert into orders(orderno,uid) values('No001',1);
insert into orders(orderno,uid) values('No002',1);
insert into orders(orderno,uid) values('No003',2);
insert into orders(orderno,uid) values('No004',2);
-- 插入订单项
insert into items(itemname,oid) values('item001',1);
insert into items(itemname,oid) values('item002',1);
insert into items(itemname,oid) values('item003',2);
insert into items(itemname,oid) values('item004',2);
insert into items(itemname,oid) values('item005',3);
insert into items(itemname,oid) values('item006',3);
insert into items(itemname,oid) values('item007',4);
insert into items(itemname,oid) values('item008',5);
select * from users ;
select * from orders ;
select * from items ;
创建数据库对应的javabean
users表对应的javabean
package cn.pengpeng.domain;
import java.util.List;
/**
* 这里面需要注意的是 一个user对应多个order,所以这里面使用list来存放,
* 需要注意UserMapper.xml里面的sql语法
*/
public class User {
private int id;
private String name;
private int age;
private List<Order> orders;
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", orders=" + orders +
'}';
}
}
表orders对应的javabean
package cn.pengpeng.domain;
/**
* 这一需要注意的是数据库里面存储的是userid,这里面直接转换成user对象的,
* 需要注意OrderMapper.xml里面的写法
*/
public class Order {
private int id;
private String orderNo;
private User user;
@Override
public String toString() {
return "Order{" +
"id=" + id +
", orderNo='" + orderNo + '\'' +
", user=" + user +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
this.orderNo = orderNo;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
建立数据库跟javabean的映射关系
UserMapper.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">
<mapper namespace="users">
<!-- 插入数据 -->
<insert id="insert" >
insert into users(name,age) values(#{name},#{age})
</insert>
<!-- 更新操作 -->
<update id="update" >
update users set name = #{name} ,age = #{age} where id = #{id}
</update>
<!-- 根据id查询数据 这个没有使用关联查询,不能查出来表之外的数据-->
<select id="selectOne" parameterType="int" resultType="cn.pengpeng.domain.User">
select * from users where id = #{id}
</select>
<!-- 查询出来说有的数据 -->
<select id="selectAll" resultType="cn.pengpeng.domain.User">
select * from users
</select>
<!-- 多表关联的时候 一对多的时候进行配置 这个是多表关联的重点 -->
<select id="findById" parameterType="int" resultMap="RM_user">
select
u.id uid,
u.name uname,
u.age uage,
o.id oid,
o.orderno oorderno
from users u
left outer join orders o on u.id = o.uid
where u.id = #{id}
</select>
<!-- 结果是比较复杂的,需要自己去定义映射关系 -->
<resultMap id="RM_user" type="cn.pengpeng.domain.User">
<id property="id" column="uid"/>
<result property="name" column="uname"/>
<result property="age" column="uage"/>
<!-- 映射一对多关联关系 -->
<collection property="orders" ofType="cn.pengpeng.domain.Order">
<id property="id" column="oid" />
<result property="orderNo" column="oorderno"/>
</collection>
</resultMap>
<!-- 查询所有的selectAll -->
<select id="findAll" resultMap="RM_user">
SELECT
u.id uid,
u.name uname,
u.age uage,
o.id oid,
o.orderno oorderno
FROM users u
left outer JOIN orders o on u.id = o.uid
</select>
</mapper>
Orders表跟Order java类进行映射文件 OrderMapper.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">
<mapper namespace="orders">
<insert id="insert" >
insert into orders(orderno,uid) values(#{orderNo},#{user.id})
</insert>
<!-- 返回中是属于类嵌套类的形式 -->
<select id="selectOne" parameterType="int" resultMap="RM_order">
select
o.id oid,
o.orderno oorderno,
o.uid uid,
u.name uname,
u.age uage
from orders o
left outer join users u on o.id = u.id where o.id = #{id}
</select>
<!-- 自定义结果对象 -->
<resultMap id="RM_order" type="cn.pengpeng.domain.Order">
<id property="id" column="oid"/>
<result property="orderNo" column="ooderno"/>
<association property="user" javaType="cn.pengpeng.domain.User">
<id property="id" column="uid"/>
<result property="name" column="uname"/>
<result property="age" column="uage"/>
</association>
</resultMap>
<!-- 多个查询 -->
<select id="selectAll" parameterType="int" resultMap="RM_order">
select
o.id oid,
o.orderno oorderno,
o.uid uid,
u.name uname,
u.age uage
from orders o
left outer join users u on o.id = u.id
</select>
</mapper>
工具类
主要是对session进行的简单的封装
package cn.pengpeng.util;
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 java.io.InputStream;
/**
* 工具类
*/
public class Util {
static SqlSessionFactory sf = null;
static {
try{
//指定配置文件的路径(类路径)
String resource = "mybatis-config.xml";
//加载文件
InputStream resourceAsStream = Resources.getResourceAsStream(resource);
//创建会话工厂Builder,相当于连接池
sf = new SqlSessionFactoryBuilder().build(resourceAsStream);
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 开启session
* @return
*/
public static SqlSession getSession(){
return sf.openSession();
}
/**
* 关闭session
*/
public static void closeSeesion(SqlSession s){
if(s !=null){
s.close();
}
}
/**
* 事物回滚
*/
public static void rollBackTx(SqlSession s){
if(s!=null){
s.rollback();
}
}
}
编写相对应的dao层
例如user的dao
package cn.pengpeng.dao;
import cn.pengpeng.domain.User;
import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;
/**
* UserDao
*/
public class UserDao {
/**
* 插入操作
*/
public void insert(User user){
SqlSession s = null;
try{
s = Util.getSession();
s.insert("user.insert",user);
s.commit();
}catch (Exception e){
e.printStackTrace();
if(s !=null){
s.rollback();
}
}finally {
if(s !=null){
s.close();
}
}
}
public void updata(User user){
SqlSession s = null;
try{
s = Util.getSession();
s.update("users.update",user);
s.commit();
}catch (Exception e){
e.printStackTrace();
if(s !=null){
s.rollback();
}
}finally {
if(s !=null){
s.close();
}
}
}
}
这样写好dao层就可以对外提供使用了,但是会发现这里面有很多代码是冗余的,所以把相同的代码进行封装(使用接口的形式)。
接口设计(抽取公共代码)
主要是把重复使用的代码进行封装,减少重复的代码
下面是把重复性的代码写上,不同的代码使用接口给丢出去,不用的实现可以实现不同的接口
package cn.pengpeng.dao;
import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;
/**
* 模板类
*/
public class DaoTemplate {
/**
* 执行,公共代码
*/
public static Object execute(MybatisCallback cb){
SqlSession s = null;
try{
s = Util.getSession();
//中间的不同点 使用接口来实现
Object ret = cb.doInMyBatis(s);
//结束,给外面流接口
s.commit();
return ret;
}catch(Exception e){
Util.rollBackTx(s);
}finally {
Util.closeSeesion(s);
}
return null;
}
}
定义接口,不用的操作只需要不用的实现
package cn.pengpeng.dao;
import org.apache.ibatis.session.SqlSession;
/**
* 回调接口,不同的操作,实现只需要不同的实现就可以了
*/
public interface MybatisCallback {
Object doInMyBatis(SqlSession s);
}
使用接口设计后的dao实现
使用接口设计后代码简洁了很多
package cn.pengpeng.dao;
import cn.pengpeng.domain.User;
import cn.pengpeng.util.Util;
import org.apache.ibatis.session.SqlSession;
/**
* UserDao
*/
public class UserDao {
/**
* 插入操作
*/
public void insert(User user){
DaoTemplate.execute(new MybatisCallback() {
@Override
public Object doInMyBatis(SqlSession s) {
s.insert("users.insert",user);
return null;
}
});
}
/**
* 更新操作
*/
public void updata(User user){
DaoTemplate.execute(new MybatisCallback() {
@Override
public Object doInMyBatis(SqlSession s) {
s.update("users.update",user);
return null;
}
});
}
}
mybatis就介绍完了,后面还有spring,和springMVC,以及他们之间的整合。
mybatis的代码已经同步到git上
点击下载代码
看文档不给力?还有视频来讲解,提交信息,小姐姐会主动联系你为你奉上视频解答哦。
点我填写资料领取视频