MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。是一个ORM的数据库持久化框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。(很官方)
简单点:
ORM:对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。
数据库持久化:把内存中数据保存到数据库中。
常见的ORM持久化框架:
Hibernate是一个完整的ORM框架,常规CRUD我们不需要写一句SQL;
jpa:完整orm映射规范
hibernate:是整orm映射规范的一种实现.
DataJpa:对jpa的操作进行封装,让我们使用更加简单.
MyBatis 并不是一个完整的ORM框架,因为我们还需要自己去写全部SQL。
MyBatis-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>
<!--引入jdbc.propeties文件-->
<properties resource="jdbc.properties" />
<typeAliases>
<package name="cn.potato.domain"></package>
<package name="cn.potato.query"></package>
<package name="cn.potato.update"></package>
</typeAliases>
<!-- 环境们 (很多环境的意思)
default:默认使用哪一个环境(必需对应一个环境的id)
-->
<environments default="development">
<!--
一个环境 id:为这个环境取唯一一个id名称
-->
<environment id="development">
<!--
事务管理 type:JDBC(支持事务)/MANAGED(什么都不做)
-->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数 -->
<property name="driver" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/potato/domain/UserMapper.xml" />
</mappers>
</configuration>
jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///mybatis
jdbc.username=root
jdbc.password=123456
日志文件配置
log4j.properties
log4j.rootLogger=ERROR, stdout
#log4j.rootLogger=NONE
log4j.logger.cn.potato=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
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">
<!--
namespace的值,规则的:映射文件XxxMapper.xml所在的包+domain类名+Mapper
-->
<mapper namespace="cn.potato.domain.User">
<!--
select : 这里面写查询语句
id:用来确定这条sql语句的唯一
以后我们确定唯一,也就是找sql语句 : namespace +.+ id
例: cn.itsource.mybatis.day1._1_hello.ProductMapper.get
parameterType : 传入的参数类型 long:大Long _long:小long (具体的对应请参见文档)
resultType : 返回值类型
-->
<select id="queryAll" resultType="user">
select * from t_user
</select>
<select id="queryOne" resultType="user">
select * from t_user where id=#{
id}
</select>
<!--useGeneratedKeys="true" keyProperty="id" keyColumn="id" 配置之后就可以拿到主键-->
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into t_user(name) values(#{
name})
</insert>
<update id="update" parameterType="user" >
update t_user set name=#{
name} where id=#{
id}
</update>
<delete id="delete" parameterType="long">
delete from t_user where id=#{
id}
/*删除指定id的数据*/
</delete>
<delete id="deleteMore" parameterType="list">
delete from t_user where id in
<foreach collection="list" item="id" open="(" separator="," close=")">
#{
id}
</foreach>
</delete>
<insert id="saveMore" parameterType="list" >
insert into t_user(name) values
<foreach collection="list" item="user" separator=",">
/*Parameters: 汉堡(String), 鸡腿(String) 要加括号 不然添加的数据不对*/
(#{
user.name})
</foreach>
</insert>
<!--写需要追加到sql语句中的条件,需要判断 这个where可以在<sql></sql> 里面写 也可以在<select></select>里面写-->
<sql id="queryBy">
<where>
<if test="name!=null">
and name like #{
name}
</if>
<if test="age!=null">
and age like #{
age}
</if>
</where>
</sql>
<!--parameterType传入值类型 resultType返回值类型 -->
<select id="queryBy" parameterType="queryBy" resultType="user">
select * from t_user
<include refid="queryBy"></include>
</select>
<!--parameterType="up" 传入值的类型-->
<update id="updateMore" parameterType="up" >
update t_user set name=#{
name} where id in
/*collection="ids" 要遍历的字段 id 就是id !-_- */
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{
id}
</foreach>
</update>
</mapper>
domain
package cn.potato.domain;
public class User {
private Long id;
private String name;
public User(String name) {
this.name = name;
}
public User() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
dao
package cn.potato.dao;
import cn.potato.domain.User;
import cn.potato.query.QueryBy;
import cn.potato.update.Up;
import java.util.List;
public interface IUserDao {
/*查询所有数据*/
List<User> queryAll() throws Exception;
/*根据id查询*/
User queryOne(Long id) throws Exception;
/*添加数据*/
void save(User user) throws Exception;
/*修改数据*/
User update(User user) throws Exception;
/*删除数据*/
void delete(Long id) throws Exception;
/*批量删除*/
void deleteMore(List ids) throws Exception;
/*批量添加数据*/
void saveMore(List users) throws Exception;
/*高级查询*/
List<User> queryBy(QueryBy queryBy);
/*批量修改数据*/
void updateMore(Up up) throws Exception;
}
daoImpl
package cn.potato.dao.impl;
import cn.potato.dao.IUserDao;
import cn.potato.domain.User;
import cn.potato.query.QueryBy;
import cn.potato.update.Up;
import cn.potato.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
public class UserDaoImpl implements IUserDao {
@Override
public List<User> queryAll() throws Exception{
SqlSession sqlSession = MyBatisUtils.INSTANCES.getSqlSession();
List<User> users = sqlSession.selectList("cn.potato.domain.User.queryAll");
return users;
}
@Override
public User queryOne(Long id) throws Exception{
SqlSession sqlSession = MyBatisUtils.getSqlSession();
User user = sqlSession.selectOne("cn.potato.domain.User.queryOne", id);
return user;
}
@Override
public void save(User user) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.insert("cn.potato.domain.User.save",user);
sqlSession.commit();
}
@Override
public User update(User user) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.update("cn.potato.domain.User.update",user);
sqlSession.commit();
return user;
}
@Override
public void delete(Long id) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.delete("cn.potato.domain.User.delete",id);
sqlSession.commit();
}
@Override
public void deleteMore(List ids) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.delete("cn.potato.domain.User.deleteMore",ids);
sqlSession.commit();
}
@Override
public void saveMore(List users) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.insert("cn.potato.domain.User.saveMore",users);
sqlSession.commit();
}
@Override
public List<User> queryBy(QueryBy queryBy) {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
List<User> users = sqlSession.selectList("cn.potato.domain.User.queryBy", queryBy);
return users;
}
@Override
public void updateMore(Up up) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.update("cn.potato.domain.User.updateMore",up);
sqlSession.commit();
}
}
QueryBy(高级查询的类)
package cn.potato.query;
public class QueryBy {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Up(批量修改的类)
package cn.potato.update;
import java.util.ArrayList;
import java.util.List;
public class Up {
private String name;
private List<Long> ids = new ArrayList();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getIds() {
return ids;
}
public void setIds(List ids) {
this.ids = ids;
}
}
MyBatisUtils(抽取的一个工具类 用来拿到sqlSession)
package cn.potato.utils;
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.Reader;
public enum MyBatisUtils {
INSTANCES;
public static SqlSessionFactory getSqlSession;
private static SqlSessionFactory sqlSessionFactory =null;
static {
Reader reader = null;
try {
//拿到对应的映射文件
reader = Resources.getResourceAsReader("MyBatis-Config.xml");
//拿到sqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
//拿到sqlSession
public static SqlSession getSqlSession(){
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
测试代码
package cn.potato.test;
import cn.potato.dao.impl.UserDaoImpl;
import cn.potato.domain.User;
import cn.potato.query.QueryBy;
import cn.potato.update.Up;
import org.junit.Test;
import java.util.Arrays;
import java.util.List;
public class MyBatisTest {
@Test
public void queryAll() throws Exception {
List<User> users = new UserDaoImpl().queryAll();
users.forEach(e->{
System.out.println(e);
});
}
@Test
public void queryOne() throws Exception {
User user = new UserDaoImpl().queryOne(3L);
System.out.println(user);
}
@Test
public void save() throws Exception {
User user = new User();
user.setName("果汁");
new UserDaoImpl().save(user);
System.out.println(user);
}
@Test
public void update() throws Exception {
User user = new User();
user.setId(9L);
user.setName("烧烤");
new UserDaoImpl().update(user);
}
@Test
public void deleteMore() throws Exception {
List<Long> ids = Arrays.asList(9L, 11L);
new UserDaoImpl().deleteMore(ids);
}
@Test
public void saveMore() throws Exception{
List<User> users = Arrays.asList(new User("汉堡"), new User("鸡腿"));
new UserDaoImpl().saveMore(users);
}
@Test
public void queryBy() throws Exception {
QueryBy queryBy = new QueryBy();
queryBy.setName("%菜%");
queryBy.setAge(21);
List<User> users = new UserDaoImpl().queryBy(queryBy);
users.forEach(e->{
System.out.println(e);
});
}
@Test
public void updateMore() throws Exception {
Up up =new Up();
up.setName("冒菜");
up.setIds(Arrays.asList(3L,4L));
new UserDaoImpl().updateMore(up);
}
}
这个修改弄了一会,容易出错
<update id="updateMore" parameterType="up" >
update t_user set name=#{
name} where id in
/*collection="ids" 要遍历的字段 id 就是id !-_- */
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{
id}
</foreach>
</update>
private List<Long> ids = new ArrayList();
/*批量修改数据*/
void updateMore(Up up) throws Exception;
@Override
public void updateMore(Up up) throws Exception {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
sqlSession.update("cn.potato.domain.User.updateMore",up);
sqlSession.commit();
}
@Test
public void updateMore() throws Exception {
Up up =new Up();
up.setName("冒菜");
up.setIds(Arrays.asList(3L,4L));
new UserDaoImpl().updateMore(up);
}