MyBatis简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录
MyBatis的框架核心
1,mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的信息。
2,mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
3,通过SqlSessionFactory,可以创建SqlSession会话。Mybatis是通过SqlSession来操作数据库的。
4,SQLSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Exexutor接口有两个实现类,一个是普通执行器,一个是缓存执行器。
5,Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型。
MyBatis入门
1,下载MyBatis:https://github.com/mybatis/mybatis-3/releases
2,创建项目导入包
3,创建全局配置文件SqlMapConfig.xml
4,创建映射文件User.xml
6,配置文件加载映射文件,在SqlMapConfig.xml中加入如下配置
7,编写测试程序,连接并操作数据库
a、读取配置文件
b、通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
c、通过SqlSessionFactory创建SqlSession
d、调用SqlSession的操作数据库方法
e、关闭SqlSession
public class Demo01 {
@Test
public void test1() throws IOException {
//a、读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//b、通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
//c、通过SqlSessionFactory创建SqlSession
SqlSession session = sessionFactory.openSession();
//d、调用SqlSession的操作数据库方法
User user = session.selectOne("findUserById", 10);
System.out.println(user);
//e、关闭SqlSession
session.commit();
}
}
输出结果:
操作数据库
<?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="user">
<!--根据id查询-->
<!--
[id]:statement的id,要求在命名空间内唯一
[paramenterType]:入参的java类型
[resultType]:查询出的单条结果集对应的java类型
[#{}]:表示一个占位符
[#{id}]:表示该占位符待接收参数的名称为id,注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义
-->
<select id="findUserById" parameterType="int" resultType="com.jsp.model.User">
SELECT * from user where id = #{id}
</select>
<!--
模糊查询
[${}]:表示拼接SQL字符串
[${value}]:表示要拼接的是简单类型参数
注意:
1,如果参数为简单类型时,${}里面的参数名称必须为value
2,${}会引起SQL注入,一般情况下不推荐使用。但是有些场景必须使用${},比如order by ${colname}
-->
<select id="findUserByName" parameterType="String" resultType="com.jsp.model.User">
SELECT * from user where username like '%${value}%'
</select>
<!--插入数据
这里的占位是写模型的属性
-->
<insert id="insertUser" parameterType="com.jsp.model.User">
insert into user (username,sex,birthday,address)
value (#{username},#{sex},#{birthday},#{address});
</insert>
<!--删除-->
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id};
</delete>
<!--更新-->
<update id="updateUser" parameterType="com.jsp.model.User">
update user set address = #{address},sex = #{sex}
where id = #{id};
</update>
<!--
插入时自动返回主键id
[selectKey标签]:通过select查询来生成主键
[keyProperty]:指定存放生成主键的属性
[resultType]:生成主键所对应的Java类型
[order]:指定该查询主键SQL语句的执行顺序,相对于insert语句
[last_insert_id]:MySQL的函数,要配合insert语句一起使用
-->
<insert id="insertUser2" parameterType="com.jsp.model.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select last_insert_id()
</selectKey>
insert into user (username,sex,birthday,address)
value (#{username},#{sex},#{birthday},#{address});
</insert>
</mapper>
代码:
package com.jsp.test;
import com.jsp.model.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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class Demo02 {
SqlSession session;
@Before
public void before() throws IOException {
System.out.println("before........... 获取Session");
//a、读取配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
//b、通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);
//c、通过SqlSessionFactory创建SqlSession
session = sessionFactory.openSession();
}
@After
public void after() {
System.out.println("after...............关闭Session");
//e、关闭SqlSession
session.close();
}
/**
* 查询一条记录和多条记录
* @throws IOException
*/
@Test
public void test1() throws IOException {
//d、调用SqlSession的操作数据库方法
User user = session.selectOne("findUserById", 10);
System.out.println(user);
//查询多条结果
List<Object> users = session.selectList("findUserByName", "张");
System.out.println(users);
}
@Test
public void test2() throws IOException{
User user = new User("Jsp02","2",new Date(),"安徽");
int affectRow = session.insert("insertUser", user);
session.commit();//事务
System.out.println("受影响的行数"+affectRow);
}
//删除用户
@Test
public void test3() throws IOException{
int affectRow = session.delete("deleteUser", 31);
session.commit();//事务
System.out.println("受影响的行数"+affectRow);
}
//更新用户
@Test
public void test4() throws IOException{
User user = new User();
user.setId(28);
user.setSex("男");
user.setAddress("黄山");
int affectRow = session.update("updateUser",user);
session.commit();//事务
System.out.println("受影响的行数"+affectRow);
}
/**
* 插入后,往模型里设置id
* @throws IOException
*/
@Test
public void test5() throws IOException{
User user = new User("Jsp","2",new Date(),"黄山");
int affectRow = session.insert("insertUser2",user);
session.commit();
System.out.println("受影响的行数"+affectRow);
System.out.println("用户的ID"+user.getId());
}
}
总结:
1、 parameterType和resultType
parameterType指定输入参数的Java类型,可以填写别名或Java类的全限定名。
resultType指定输出结果的Java类型,可以填写别名或Java类的全限定名。2、#{}和${}
#{}:相当于预处理中的占位符----?。
- #{}里面的参数表示接收Java输入参数的名称。
- #{}可以接受HashMap、POJO类型的参数。
- 当接受简单类型的参数时,#{}里面可以是value,也可以是其他。
- #{}可以防止SQl注入。
${}:相当于拼接SQL串,对传入的值不做任何解释的原样输出。
- ${}会引起SQL注入,所以要谨慎使用。
- ${}可以接受HashMap、POJO类型的参数。
- 当接受简单类型的参数时,${}里面只能是value。
3、selectOne和selectList
selectOne:只能查询0或1条记录,大于1条记录的话,会报错
selectList:可以查询0或N条记录。