文章目录
一、定义
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
无论是Mybatis、Hibernate都是ORM的一种实现框架,都是对JDBC的一种封装!
二、mybatis使用步骤
1、导入mybatis依赖包
- cglib-2.2.2.jar : cgilb代理,用来自动创建类、对象
- commons-logging-1.1.1.jar:通用日志包,主要用于打印日志信息
- javassist-3.17.1-GA.jar:字节码包,主要是操作类、对象的属性、方法(反射)
- mybatis-3.2.7.jar: mybatis核心功能包
- mysql-connector-java-5.1.30.jar: 数据库连接包
2、编写mybatis的主配置文件。
- 主配置文件内容包括:
- 配置连接数据库的参数:驱动、url、账号、密码
- 配置mapper文件
- 主配置文件的作用:管理连接
主配置文件示例:
<?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>
<!-- 引入数据库配置文件 该文件内容为数据库url和账号密码的键值对 -->
<properties resource="db.properties"></properties>
<!-- 设置日志文件 -->
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
<!-- 全局设置 -->
<typeAliases>
<!-- 自动讲给指定包下的类取别名,别名即为类名 -->
<package name="com.woniu.pojo"/>
<!-- 给指定类取别名 -->
<!-- <typeAlias type="com.woniu.pojo.Person" alias="Person"/> -->
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 采用jdbc的原生事务管理器进行事务管理 -->
<transactionManager type="JDBC"/>
<!-- 采用连接池管理连接:POOLED 采用, UNPOOLED 不采用 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="com/woniu/mapper/personMapper.xml"/>
<!-- 接口映射 -->
<mapper class="com.woniu.mapper.TeacherMapper"/>
</mappers>
</configuration>
3、准备数据库和数据
4、编写POJO类
要求:类名最好与表名一致,属性名最好与字段名一致
如果属性名与表中的字段名不一致,会造成查出来的结果无法被封装成对应的类,这个时候可以通过在sql语句中,给查询的字段取别名解决该问题。别名与类中的属性名保持一致。
5、编写mapper文件
作用: 编写sql操作数据库
mapper文件的取名方式:POJO类名+Mapper.xml
示例:
5.1 xml文件
sql语句的属性说明:
- id:sql语句的唯一标识
- parameterType:参数类型
- resultType :将查询结果封装为哪个类型:写类型的全路径 。
- 注,下面没有写全路径是因为在主配置文件中设置了别名。
<?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">
<!-- 命名空间:区分不同的sql语句,类似package -->
<mapper namespace="abc">
<!-- id:sql语句的唯一标识, parameterType:参数类型,resultType :将查询结果封装为哪个类型:写类型的全路径
-->
<select id="selectAll" resultType="Person">
select * from person
</select>
<!-- 如果参数的类型是:基本数据类型,包装类,String类型,在获取参数时变量名可以随意取。
但是建议使用有特殊含义的名字
-->
<select id="selectById" parameterType="int" resultType="Person">
select * from person where id = #{id}
</select>
<select id="selectByName" parameterType="String" resultType="Person">
select * from person where name = #{name}
</select>
<select id="selectByIdAndName" parameterType="map" resultType="Person">
select * from person where id =#{aaa} and name=#{bbb}
</select>
<!-- 如果参数是pojo类的对象类型,那么在获取参数是必须使用属性名 -->
<select id="selectByIdAndName2" parameterType="Person" resultType="Person">
select * from person where id =#{id} and name=#{name}
</select>
<!-- 模糊查询 -->
<select id="selectLike" parameterType="String" resultType="Person">
select * from person where name like #{name}
</select>
<!-- 分页查询 -->
<select id="selectPage" parameterType="com.woniu.util.Page" resultType="Person">
select * from person limit #{index},#{count}
</select>
<!-- 插入数据 -->
<insert id="addPerson" parameterType="Person">
insert into person values(#{id},#{name},#{age})
</insert>
<!-- 根据id删除数据 -->
<delete id="deletePersonById" parameterType="int">
delete from person where id = #{id}
</delete>
<!-- 更新数据 -->
<update id="updateNameById" parameterType="Person">
update person set name=#{name} where id=#{id}
</update>
</mapper>
5.2测试函数
使用mybatis包含以下几步:
- 1.加载mybatis主配置文件:
- 2.创建SqlSession的工厂
- 3.利用工厂创建SqlSession对象
- 4.SqlSession对象调用对应方法操作数据库:session.方法(“namespace.id”,参数)
- mybatis只支持单参传递,如果有多个参数,可以使用自定义类,或者map形式传递
- 5.提交:session.commit()
- 6.关闭SqlSession对象:session.close()
/*
* mybatis 中的核心API类
* SqlSessionFactory:用于创建SqlSession对象
* SqlSession:用来操作数据库的对象
*
* mybatis 可以根据mapper文件中的配置将查询出来的数据自动映射
*
* $:用于获取静态资源
* #:用于sql语句中获取动态资源
*
*/
public class Test1 {
public static void main(String[] args) throws IOException {
//1、加载主配置文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//2、创建工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
//3、创建SqlSession
SqlSession session = factory.openSession();
//查询所有
List<Person> persons = session.selectList("abc.selectAll");
System.out.println(persons);
//以ID查询
Object obj = session.selectOne("abc.selectById", 1);
System.out.println(obj);
//以名字查询
obj = session.selectOne("abc.selectByName", "zhangsan");
System.out.println(obj);
//mybatis只支持单参传递,如果想要传递多个参数,那么需要想办法通过一个参数来传递多个数据
//常见方式有两种:map、pojo类
//通过map方式
Map<String,Object> map = new HashMap<>();
map.put("aaa", "1");
map.put("bbb","zhangsan");
obj = session.selectOne("abc.selectByIdAndName", map);
System.out.println(obj);
//通过pojo类方式
Person person = new Person();
person.setId(1);
person.setName("zhangsan");
obj = session.selectOne("abc.selectByIdAndName2", person);
System.out.println(obj);
//插入数据
person = new Person(6,"wangsiting",22);
int row = session.insert("abc.addPerson",person);
//mybatis默认将自动提交关闭了,在进行增删改时需要手动提交
session.commit();
System.out.println(row);
//删除数据
row = session.delete("abc.deletePersonById", 6);
session.commit();
System.out.println(row);//为什么删除一行数据时row为2,没有删除时,row为1?
//模糊查询
//like:模糊查询时通配符应该在Java程序中拼接好,传入sql语句中
persons = session.selectList("abc.selectLike","%a%");
System.out.println(persons);
//分页查询
Page<Person> page = new Page<>();
page.setIndex(0);
page.setCount(1);
page.setData(session.selectList("abc.selectPage", page));
System.out.println(page);
//5、关闭
session.close();
}
}
6、在主配置文件中加载mapper文件
- 作用:让mapper的配置生效
二、mybatis:自动映射的原理
1、执行sql语句查询除结果即以及字段的名字
2、根据resultType的类型调用对应POJO类的无参构造方法创建对象
2.1 获取对应的pojo类的字节码对象
- 2.2 根据字节码对象调用newInstance()->无参构造创建对象
3、根据结果集中字段的名字,获取到setter方法,然后利用setter方法给对应的属性赋值
- 例如如果结果集中字段名叫做uid,那么mybatis会根据这个名字自动拼接出setter方法的名字,然后根据方法名找到对应的方法,再通过setter方法进行赋值。
三、在mybatis中获取参数值方式
- 如果参数是基本类型、包装类、String类型,可以通过任意变量名获取
- 如果参数是map类型,应该使用key获取参数
- 如果参数是自定义类型,应该使用类的属性名获取参数
- 如果采用接口映射实现多参传递的话,在获取参数时应该采用{0,1,param1,param2}的方式获取参数