背景介绍
mybatis原来是apache下面的一个开源项目,名为ibatis, 2010年开发团队转移到谷歌旗下,改名为mxbatis.
mxbatis介绍 mybatis是一个优秀的数据持久层(dao层 数据访问层 数据持久层) mybatis是对jdbc进行的封装,避免了idbc中手动设置参数,手动映射结果的操作.
mybatis将jdbc中的接口进行封装,提供了它自己的类和接口实现. mybatis可以使用xml配置和注解的方式,将数据库中记录自动映射到java对象中, 是一种ORM实现(对象关系映射)将可以自动将数据映射到对象中的这种框架,也称为orm框架
mybatis还提供动态sql和数据缓存
#{} 和${}的区别
#{}是占位符。是采用预编译方式向sql中传值,可以防止sql注入,如果我们往sql中传值,使用#{}
${}是将内容直接拼接到sql语句中,一般不用于向sql中传值,一般用于向sql动态传递列名
底层实现不同:
#{}采用预编译方式,防止sql注入更安全
${}采用字符串拼接,直接将值拼接到sql中
使用场景不同:
#{}一般用于向sql中的列传值
${}一般用于向sql动态传递列名
MyBatis 环境搭建
1.创建一张表和表对应的实体类
2.导入 MyBatis jar 包,mysql 数据库驱动包
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.2</version> </dependency>
3.创建 MyBatis 全局配置文件
<?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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="" /> <property name="url" value="" /> <property name="username" value="" /> <property name="password" value=""/> </dataSource> </environment> </environments> </configuration>
4.定义接口
在接口中定义方法
public interface AdminDao
{
Admin findAdminById(int id);
}
5.创建 sql 映射文件
<?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="接口的地址"> <select id="findAdminById" parameterType="int" resultType="com.ffyc.mybatis.model.Admin"> select * from admin where id = #{id} </select </mapper>
6.测试MyBatis
读取配置文件
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
创建 SqlSessionFactory
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
创建 SqlSession
SqlSession sqlSession = sessionFactory.openSession();
获得接口代理对象
sqlSession.getMapper(接口.class);
sqlSession .close();关闭
API 接口说明
SqlSessionFactory 接口
使用 SqlSessionFactory 来创建 SqlSession,一旦创建 SqlSessionFactory 就 会在整个应用过程中始终存在。由于创建开销较大,所以没有理由去销毁再创建 它,一个应用运行中也不建议多次创建 SqlSessionFactory。
SqlSession 接口 Sqlsession 意味着创建与数据库链接会话,该接口中封装了对数据库操作的方 法,与数据库会话完成后关闭会话。
Mybatis-Dao 层面向接口开发
面向接口开发方式只需要程序员编写接口,由 Mybatis 框架创建接口的动态代理 对象,使用 sqlsession.getMapper(接口.class);获得代理对象
面向接口开发需要遵循以下规范:
1.Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同.
2、 Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同.
3、 Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同.
4、 Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同.
Mybatis 日志
具体选择哪个日志实现由 MyBatis 的内置日志工厂确定。它会使用最先找到的。
Mybatis 内置的日志工厂提供日志功能,具体的日志实现有以下几种方式: SLF4J|LOG4J|JDK_LOGGINGCOMMONS_LOGGING|STDOUT_LOGGING
配置日志
<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
增删改查
<insert id="唯一标识" useGeneratedKeys="把新增加的主键赋值到自己定义的 keyProperty " keyProperty=“ 接收主键的属性 parameterType="参数类型">
insert into
admin(account,password)values(#{account},#{password})
</insert>
</mapper>
修改
<update id="唯一标识" parameterType=“参数类型">
update admin set account= #{account},password= #{password} where id= #{id}
</update>
删除
<delete id="唯一标识" parameterType="参数类型">
delete from admin where id= #{id}
</delete>
对象映射
如果表中的类名与类中的属性名完全相同,mybatis会自动将查询结果封装
到POJO对象中.
如果java中使用标准驼峰命名,数据库中使用下划线连接命名,可以开始全局 设置实现自动转换
<!--sql映射文件 主要写sql实现-->
<mapper namespace="com.ffyc.mybatispro.dao.AdminDao">
<!-- useGeneratedKeys="true" 返回自增主键
keyProperty="id" 定义接收属性
keyColumn="id" 定义主键列
-->
<insert id="insertAdmin" parameterType="Admin" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into admin(account,password,gender)values (#{account},#{password},#{gender})
</insert>
<!--
resultMap
type="admin 最终返回结果的类型
-->
<resultMap id="findMap" type="admin">
<id column="adminid" property="id"></id>
<result column="account" property="account"></result>
</resultMap>
<select id="findAdminId" resultMap="findMap">
select id,account,adminid from admin
</select>
<!-- 对关联查询到的学生信息进行自定义映射封装 -->
<resultMap id="studentMap" type="Student">
<id column="id" property="id"></id>
<result column="num" property="num"></result>
<result column="name" property="name"></result>
<result column="gender" property="gender"></result>
<!-- 映射关联数据 专业名称 首先会创建一个Major对象,然后将专业名称封装到Major对象,最后将Major对象封装到Student对象中 -->
<association property="major" javaType="Major">
<result column="mname" property="name"></result>
</association>
</resultMap>
在程序开发中,在哪儿需要使用哪个类的对象,就在哪儿创建这个类对象,去使用即可. 这种写法对于业务开发是没有问题的.
但是,在一些组件或者 框架中开发中,他们本身是不知道要处理哪些类, 例如jackson组件,我们给他什么类,他就要处理转换什么类
new ObjectMapper().writeValueAsString(user)
new ObjectMapper().writeValueAsString(admin)
new ObjectMapper().writeValueAsString(result)
在web.xml中配置了哪些servlet类,tomcat就要创建哪些类对象
<servlet-class>com.ffyc.dorm.web.LoginServlet</servlet-class>
<servlet-class>com.ffyc.dorm.web.TestServlet</servlet-class>
在mybatis中,给了什么类型,mybatis就可以将结果封装映射到给定的类的对象中
<select id="findAdminByld" parameterType="int" resultType="Admin">
<select id="teachers" resultType="com.ffyc.mybatispro.model.Teacher">
框架需要只写一套程序,就可以处理我们给他的任意类,
框架是如何做到写一套程序,就可以处理任意类了?
以前已知类名的使用方式,可以看做是正向使用类.
框架需要对任意类处理时,只是知道类的名字,通过类的名字动态才去获取类中的信息.
把这种对类的使用方式,称为反向使用.