什么是框架?
它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题。
使用框架的好处:
框架封装了很多的细节,使开发者可以使用极简的方式实现功能。大大提高开发效率。
三层架构
表现层:
是用于展示数据的
业务层:
是处理业务需求
持久层:
是和数据库交互的
持久层技术解决方案
JDBC技术:
Connection
PreparedStatement
ResultSet
Spring的JdbcTemplate:
Spring中对jdbc的简单封装
Apache的DBUtils:
它和Spring的JdbcTemplate很像,也是对Jdbc的简单封装
以上这些都不是框架
JDBC是规范
Spring的JdbcTemplate和Apache的DBUtils都只是工具类
mybatis的概述
mybatis是一个持久层框架,用java编写的。
它封装了jdbc操作的很多细节,使开发者只需要关注sql语句本身,而无需关注注册驱动,创建连接等繁杂过程
它使用了ORM思想实现了结果集的封装。
ORM:
Object Relational Mappging 对象关系映射
简单的说:
就是把数据库表和实体类及实体类的属性对应起来
让我们可以操作实体类就实现操作数据库表。
user User
id userId
user_name userName
我们需要做到
实体类中的属性和数据库表的字段名称保持一致。
user User
id id
user_name user_name
mybatis的入门
mybatis的环境搭建
第一步:创建maven工程并导入坐标
< dependencies>
< dependency>
< groupId> org.mybatis</ groupId>
< artifactId> mybatis</ artifactId>
< version> 3.4.5</ version>
</ dependency>
< dependency>
< groupId> junit</ groupId>
< artifactId> junit</ artifactId>
< version> 4.10</ version>
< scope> test</ scope>
</ dependency>
< dependency>
< groupId> mysql</ groupId>
< artifactId> mysql-connector-java</ artifactId>
< version> 5.1.6</ version>
< scope> runtime</ scope>
</ dependency>
< dependency>
< groupId> log4j</ groupId>
< artifactId> log4j</ artifactId>
< version> 1.2.12</ version>
</ dependency>
</ dependencies>
第二步:创建实体类和dao的接口
public class User implements Serializable {
}
public interface IUserDao {
/**
* 查询所有用户
* @return
*/
List< User> findAll();
}
第三步:创建Mybatis的主配置文件:SqlMapConifg.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>
< environments default = " mysql" >
< environment id = " mysql" >
< transactionManager type = " JDBC" > </ transactionManager>
< dataSource type = " POOLED" >
< property name = " driver" value = " com.mysql.jdbc.Driver" />
< property name = " url" value = " jdbc:mysql://localhost:3306/ee50" />
< property name = " username" value = " root" />
< property name = " password" value = " 1234" />
</ dataSource>
</ environment>
</ environments>
< mappers>
< mapper resource = " com/demo/dao/IUserDao.xml" />
</ mappers>
</ configuration>
第四步:创建映射配置文件:IUserDao.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 = " com.demo.dao.IUserDao" >
< select id = " findAll" resultType = " com.demo.domain.User" >
select * from user
</ select>
环境搭建的注意事项:
第一个:创建IUserDao.xml 和 IUserDao.java时名称是为了和我们之前的知识保持一致。
在Mybatis中它把持久层的操作接口名称和映射文件也叫做:Mapper
所以:IUserDao 和 IUserMapper是一样的
第二个:在idea中创建目录的时候,它和包是不一样的
包在创建时:com.demo.dao它是三级结构
目录在创建时:com.demo.dao是一级目录
第三个:mybatis的映射配置文件位置必须和dao接口的包结构相同
第四个:映射配置文件的mapper标签namespace属性的取值必须是dao接口的全限定类名
第五个:映射配置文件的操作配置(select),id属性的取值必须是dao接口的方法名
当我们遵从了第三,四,五点之后,我们在开发中就无须再写dao的实现类。
mybatis的入门案例
//1.读取配置文件
InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建 SqlSessionFactory 的构建者对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.使用构建者创建工厂对象 SqlSessionFactory
SqlSessionFactory factory = builder.build(in);
//4.使用 SqlSessionFactory 生产 SqlSession 对象
SqlSession session = factory.openSession();
//5.使用 SqlSession 创建 dao 接口的代理对象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使用代理对象执行查询所有方法
List< User> users = userDao.findAll();
for(User user : users) {
System.out.println(user);
}
//7.释放资源
session.close();
in.close();
注意事项: 不要忘记在映射配置中告知mybatis要封装到哪个实体类中 配置的方式:指定实体类的全限定类名
mybatis基于注解的入门案例:
1.把IUserDao.xml移除,在dao接口的方法上使用@Select注解,并且指定SQL语句
public class User implements Serializable {
}
@Select("select * from user")
public interface IUserDao {
/**
* 查询所有用户
* @return
*/
List< User> findAll();
}
2.同时需要在SqlMapConfig.xml中的mapper配置时,使用class属性指定dao接口的全限定类名。
<?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 = " mysql" >
< environment id = " mysql" >
< transactionManager type = " JDBC" > </ transactionManager>
< dataSource type = " POOLED" >
< property name = " driver" value = " com.mysql.jdbc.Driver" />
< property name = " url" value = " jdbc:mysql://localhost:3306/ee50" />
< property name = " username" value = " root" />
< property name = " password" value = " 1234" />
</ dataSource>
</ environment>
</ environments>
< mappers>
< mapper class = " com.demo.dao.IUserDao" />
</ mappers>
</ configuration>
* 明确:
1、我们在实际开发中,都是越简便越好,所以都是采用不写dao实现类的方式。
2、不管使用XML还是注解配置。
3、但是Mybatis它是支持写dao实现类的。
* 使用要求:
1、持久层接口和持久层接口的映射配置必须在相同的包下
2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是
持久层接口的全限定类名
3、SQL 语句的配置标签<select>,<insert>,<delete>,<update>的 id
属性必须和持久层接口的方法名相同。
* 细节:
1.和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的
提交,session.commit();
2.新增用户 id 的返回值:新增用户后,同时还要返回当前新增
用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就
相当于我们要在新增后将自动增长 auto_increment 的值返回
<insert id="saveUser" parameterType="USER">
<!-- 配置保存时获取插入的 id -->
<selectKey keyColumn="id" keyProperty="id" resultType="int">
select last_insert_id();
</selectKey>
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
3.模糊查询:*#{}与${}的区别
* #{}表示一个占位符号
通过#{}可以实现 preparedStatement 向占位符中设置值,自动
进行 java 类型和jdbc 类型转换,#{}可以有效防止 sql 注入。
#{}可以接收简单类型值或 pojo 属性值。 如果 parameterType
传输单个简单类型值,#{}括号中可以是 value 或其它名称。
* ${}表示拼接 sql 串
通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行
jdbc 类型转换, ${}可以接收简单类型值或 pojo 属性值,如果
parameterType 传输单个简单类型值,${}括号中只能是 value。
<!-- 根据名称模糊查询 方式一-->
<select id="findByName" resultType="com.demo.domain.User" parameterType="String">
select * from user where username like #{username}
-->userDao.findByName("%王%");
-->select * from user where username like ?
-->parameters:%王%(String)
</select>
<!-- 根据名称模糊查询 方式二-->
<select id="findByName" resultType="com.demo.domain.User" parameterType="String">
select * from user where username like '%${value}%'
-->userDao.findByName("王");
-->select * from user where username like %王%
</select>
自定义Mybatis的分析:
1.mybatis在使用代理dao的方式实现增删改查时做什么事呢?
只有两件事:
第一:创建代理对象
第二:在代理对象中调用selectList
自定义mybatis能通过入门案例看到类
class Resources
class SqlSessionFactoryBuilder
interface SqlSessionFactory
interface SqlSession
mybatis参数的传递以及返回值的封装
1.parameterType:用于指定传入参数的类型
* sql 语句中使用#{}字符,它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据,具体的数据是由#{}里面的内容决定的
* #{}中内容的写法:
* 基本类型:处可以随意写
* 对象类型:用的是 ognl 表达式
* ognl 表达式:
1.它是 apache 提供的一种表达式语言
2.Object Graphic Navigation Language 对象图导航语言
3.语法格式就是使用 #{对象.对象}的方式,类似databinding用法
* 例如:QueryVo对象中有一个User对象和一个String类型的company
使用:#{user.username} #{company}
* 注意:如果我们在 parameterType 属性上指定了实体类名称,就可以省略第一个对象名
2.resultType:用于指定结果集的类型,它支持基本类型和实体类类型
* 注意:实体类中的属性名称必须和查询语句中的列名保持一致,
否则无法实现封装
* 解决方法:
1.用别名:
<!-- 配置查询所有操作 -->
<select id="findAll" resultType="com.demo.domain.User">
select id as userId,username as userName,birthday as userBirthday,
sex as userSex,address as userAddress from user
</select>
2.resultMap 结果类型:
<resultMap type="com.demo.domain.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
id 标签:用于指定主键字段
result 标签:用于指定非主键字段
column 属性:用于指定数据库列名
property 属性:用于指定实体类属性名称
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
select * from user
</select>
SqlMapConfig.xml配置文件
properties(属性):
* 第一种写法:
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/eesy"/>
<property name="jdbc.username" value="root"/>
<property name="jdbc.password" value="1234"/>
</properties>
* 第二种写法:resource 属性:用于指定 properties 配置文件的位置,要求配置文件必须在类路径下
1.在 classpath 下定义 jdbcConfig.properties 文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/eesy
jdbc.username=root
jdbc.password=1234
2.
<properties resource="jdbcConfig.properties">
</properties>
* 第三种写法:url 属性:
URL: Uniform Resource Locator 统一资源定位符
http://localhost:8080/mystroe/CategoryServlet URL
协议 主机 端口 URI
URI:Uniform Resource Identifier 统一资源标识符
/mystroe/CategoryServlet
它是可以在 web 应用中唯一定位一个资源的路径
<properties url=
file:///D:/IdeaProjects/day02_eesy_01mybatisCRUD/src/main/resources/jdbcConfig.prop
erties">
</properties>
* 扩展 :
mappers/mapper标签下也有resource和url属性,但是url属性比较难写,所以一般不考虑
*** 此时我们的 dataSource 标签就变成了引用上面的配置
<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>
typeAliases(类型别名)
* 自定义别名:在 SqlMapConfig.xml 中配置:
使用typeAliases配置别名,它只能配置domain中类的别名
<typeAliases>
<!-- 单个别名定义 -->
<typeAlias alias="user" type="com.demo.domain.User"/>
<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
<package name="com.demo.domain"/>
<package name="其它包"/>
</typeAliases>
* 扩展:
mappers标签下要写一堆的mapper标签,比较麻烦,所以可以直接指定package属性
注册指定包下的所有 mapper 接口
<mappers>
<package name="cn.demo.mybatis.mapper"/>
</mappers>
注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。