1.dao层框架
2maven项目传统使用
2.1 pom文件加入坐标,Mybatis和数据库Mysql
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>
2.2加入插件,为了编译时候保存properties文件
<build>
<resources>
<resource>
<directory>src/main/java</directory> <!--所在的目录-->
<includes><!--包括目录下的.properties,.xml 文件都会扫描到-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
2.3编写实体类 例如Student,属性和数据库列名一样
2.4编写Dao接口 例如StudentDao
2.5接口同一文件下建立Dao接口的Mapper映射文件 例如 StudentDao.xml,一般一个表一个映射文件
- 在 dao 包中创建文件 StudentDao.xml
- 要 StudentDao.xml 文件名称和接口 StudentDao 一样,区分大小写的一样。
- 为反射做铺垫
映射文件例如
<?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 :必须有值,自定义的唯一字符串
推荐使用: dao 接口的全限定名称
-->
<mapper namespace="com.bjpowernode.dao.StudentDao">
<!--
<select>: 查询数据, 标签中必须是 select 语句
id: sql 语句的自定义名称,推荐使用 dao 接口中方法名称,
使用名称表示要执行的 sql 语句
resultType: 查询语句的返回结果数据类型,使用全限定类名
-->
<select id="selectStudents" resultType="com.bjpowernode.domain.Student">
<!-要执行的 sql 语句 -->
select id,name,email,age from student
</select>
</mapper>
2.6 Mybatis主配置文件 mybatis.xml ,一个项目一个
1.项目 src/main 下创建 resources 目录,设置 resources 目录为 resources root 创建主配置文件:名称为 mybatis.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>
<!-配置 mybatis环境 -->
<environments default="mysql">
<!--id: 数据源的名称 -->
<environment id="mysql">
<!-配置事务类型:使用 JDBC 事务(使用 Connection的提交和回滚) -->
<transactionManager type="JDBC"/>
<!-数据源 dataSource :创建数据库 Connection对象
type: POOLED 使用数据库的连接池
-->
<dataSource type="POOLED">
<!-连接数据库的四个要素 -->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-告诉 mybatis 要执行的 sql 语句的位置 -->
<mapper resource="com/bjpowernode/dao/StudentDao.xml"/>
</mappers>
</configuration>
2.7 通过Mybatis访问数据库
/*
* mybatis 入门
* */
* @Test
public void testStart() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象 , 目的是获取 Sql Session
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession,SqlSession 能执行 sql 语句
SqlSession session = factory.openSession();
//5. 执行 SqlSession 的 selectList()
List<Student> studentList=session.selectList("com.bjpowernode.dao.StudentDao.selectStudents");
//6. 循环输出查询结果
studentList.forEach( student -> System.out.println(student));
//7. 关闭 SqlSession ,释放资源
session.close();
}
2.8 配置日志功能
mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数
<settings>
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
2.9 增加功能整体流程 例如insert
2.9.1StudentDao 接口中增加方法
int insertStudent(Student student);
2.9.2StudentDao.xml 加入 sql 语句
<insert id="insertStudent">
insert into student(id,name,email,age)
values(#{id},#{name},#{email},#{age})
</insert>
2.9.3增加测试方法
@Test
public void testInsert() throws IOException {
//1.mybatis 主配置文件
String config = "mybatis.xml";
//2. 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
//3. 创建 SqlSessionFactory 对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//4. 获取 SqlSession
SqlSession session = factory.openSession();
//5. 创建保存数据的对象
Student student = new Student();
student.setId(1005);
student.setName("张丽");
student.setEmail("zhangli@163.com");
student.setAge(20);
//6. 执行插入 insert
int rows = session.insert( "com.bjpowernode.dao.StudentDao.insertStudent",student);
//7. 提交事务
session.commit();
System.out.println("增加记录的行数:"+rows);
//8. 关闭 SqlSession
session.close();
}
3.Mybatis对象
3.1Resources类
Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返 回不同类型的 IO 流对象。
3.2SqlSessionFactoryBuilder类
SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将 该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。
3.3SqlSessionFactory
SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用 只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。
➢ openSession(true):创建一个有自动提交功能的 SqlSession
➢ openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
➢ openSession():同 openSession(false)
3.4SqlSession接口
-
SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以 SqlSession对象的创建开始,以 SqlSession 对象的关闭结束。**
-
SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其
close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。
4.封装工具类快速获取SqlSession
4.1创建 MyBatisUtil 类
/**
* <p>Description: 实体类 </p>
* <p>Company: http://www.bjpowernode.com */
public class MyBatisUtil {
// 定义 SqlSessionFactory
private static SqlSessionFactory factory = null;
static {
// 使用 静态块 创建一次 SqlSessionFactory
try{
String config = "mybatis.xml";
// 读取配置文件
InputStream in = Resources.getResourceAsStream(config);
// 创建 SqlSessionFactory 对象
factory = new SqlSessionFactoryBuilder().build(in);
}catch (Exception e){
factory = null;
e.printStackTrace();
}
}
/* 获取 SqlSession 对象 */
public static SqlSession getSqlSession(){
SqlSession session = null;
if( factory != null){
session = factory.openSession();
}
return session;
}
}
4.2 使用 MyBatisUtil 类
@Test
public void testUtils() throws IOException {
SqlSession session = MyBatisUtil.getSqlSession();
List<Student> studentList = session.selectList("com.bjpowernode.dao.StudentDao.selectStudents");
studentList.forEach( student -> System.out.println(student));
session.close();
}
5 Dao代理模式
5.1去掉接口实现类,只保留接口
5.2使用SqlSession的getMapper代理接口
使用工具类:
StudentDao studentDao = MyBatisUtil.getSqlSession().getMapper(StudentDao.class);
5.3代理对象调用接口中的方法即可
例如
select 方法:
@Test
public void testSelect() throws IOException {
final List<Student> studentList = studentDao.selectStudents();
studentList.forEach( stu -> System.out.println(stu));
}
update 方法
@Test public void testUpdate() throws IOException {
Student student = new Student();
student.setId(1006);
student.setAge(28);
int nums = studentDao.updateStudent(student);
System.out.println("使用 Dao 修改数据:"+nums);
}
6.传参
6.1 一个简单参数
Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),占位符 #{ 任意字符 },和方法的参数名无关。
6.2 多个参数
当 Dao 接口方法多个参数,需要通过名称使用参数。 在方法形参前面加入@Param(“自定义参数名”), mapper 文件使用#{自定义参数名}。
例如定义
List<Student> selectStudent( @Param(“personName”) String name ) { … }
mapper 文件 select * from student where name = #{ personName}
6.3 多个参数使用对象
使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。
语法格式: #{ property,javaType=java 中数据类型名,jdbcType=数据类型名称 }
6.4 多个参数按照位置
参数位置从 0 开始, 引用参数语法 #{ arg 位置 } , 第一个参数是#{arg0}
, 第二个是#{arg1}
注意:mybatis-3.3 版本和之前的版本使用#{0},#{1}方式, 从 mybatis3.4 开始使用#{arg0}方式。
6.5 多个参数使用Map
Map集合可以存储多个值,使用Map向mapper文件一次传入多个参数。Map集合使用String的key, Object 类型的值存储参数。 mapper 文件使用 # { key }
引用参数值。
6.6补充#和$
6.6.1
#:占位符
,告诉 mybatis 使用实际的参数值代替。并使用 PrepareStatement 对象执行 sql 语句, #{…}代替 sql 语句的“?”。 这样做更安全,更迅速,通常也是首选做法,
6.6.2
$ 字符串替换
,告诉 mybatis 使用
包
含
的
“
字
符
串
”
替
换
所
在
位
置
。
使
用
S
t
a
t
e
m
e
n
t
把
s
q
l
语
句
和
包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和
包含的“字符串”替换所在位置。使用Statement把sql语句和{}的 内容连接起来。主要用在替换表名,列名,不同列排序等操作。
6.6.3 # 和 $区别
- #使用 ?在sql语句中做站位的, 使用PreparedStatement执行sql,效率高
- #能够避免sql注入,更安全。
- $不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低
- $有sql注入的风险,缺乏安全性。
- $:可以替换表名或者列名
7.Mapper文件中的resultType 和 resultMap
7.1resultType:
执行 sql 得到 ResultSet 转换的类型,使用类型的完全限定名或别名。 注意如果返回的是集 合,那应该设置为集合包含的类型,而不是集合本身。resultType 和 resultMap,不能同时使用。
7.2resultMap
可以自定义 sql 的结果和 java 对象属性的映射关系。更灵活的把列值赋值给指定属性。 常用在列名和 java 对象属性名不一样的情况。
8.动态Sql
◼ 动态 SQL-if ◼ 动态 SQL-where ◼ 动态 SQL-foreach ◼ 动态 SQL-片段
9.其他配置
9.1. 数据库的属性配置文件: 把数据库连接信息放到一个单独的文件中。 和mybatis主配置文件分开。
目的是便于修改,保存,处理多个数据库的信息。
1)在resources目录中定义一个属性配置文件, xxxx.properties ,例如 jdbc.properties
在属性配置文件中, 定义数据,格式是 key=value
key: 一般使用 . 做多级目录的。
例如 jdbc.mysql.driver , jdbc.driver, mydriver
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql//.....
jdbc.username=root
jdbc.password=123456
2)在mybatis的主配置文件,使用<property> 指定文件的位置
在需要使用值的地方, ${key}
9.2.mapper文件,使用package指定路径
<mappers>
<!--第二种方式: 使用包名
name: xml文件(mapper文件)所在的包名, 这个包中所有xml文件一次都能加载给mybatis
使用package的要求:
1. mapper文件名称需要和接口名称一样, 区分大小写的一样
2. mapper文件和dao接口需要在同一目录
-->
<package name="com.bjpowernode.dao"/>
</mappers>