typora-copy-images-to: 图片
Mybatis框架
1.框架
1.1 什么是框架?
框架软件的半成品,我们在框架基础上快速开发我们公司定制化的软件应用
好处:
1.开发速度块
2.降低难度 框架提供了很多现成的模块和功能 拿来就用
3.提供软件同一的规范 很多公司都在用
4.提高软件质量 框架解决高并发高性能的问题,可以让初学者都能开出高性能的应用
1.2 ORM框架
ORM框架,即对象映射框架
读取:将数据库表中的每一行数据 映射为java对象
写入: 将java对象映射为数据库 每一行数据
mybatis 就是一个orm框架,要取代最基本的jdbc queryRuner
2.mybatis框架
2.1概述
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
2.2特点
- 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
- 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
- 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql。
2.3中文官网
http://www.mybatis.cn/
3.mybatis快速入门
3.1创建maven-java工程,并引入依赖
第一步
第二步
第三步
在pom.xml文件中引入依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
3.2引入实体类
package com.yth.entity;
import java.util.Date;
public class Student{
private int id;
private String name;
private String sex;
private int age;
private double height;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getHeight() {
return height;
}
public void setHeight(double height) {
this.height = height;
}
@Override
public String toString() {
return "Student{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
", height=" + height +
'}';
}
public Student(String name, String sex, int age, double height) {
this.name = name;
this.sex = sex;
this.age = age;
this.height = height;
}
public Student(int id, String name, String sex, int age, double height) {
this.id = id;
this.name = name;
this.sex = sex;
this.age = age;
this.height = height;
}
public Student() {
}
}
3.3编写持久层IStudentdao层接口
import com.yth.entity.Student;
/**
* student dao接口
*
* 需要 mybatis 创建一个 实现类
* 在IStudentDao.xml 告诉mybatis 如何创建一个实现类
*/
public interface IStudentDao {
/**
* 查询所有学生
*/
List<Student> getAllStudent();
}
3.4编写持久层配置文件IStudentDao.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.yth.dao.IStudentDao">
<!--配置查询所有学生的 方法
id:为对应的方法方法名
resultType:返回数据类型的全限定名
-->
<select id="getAllStudent" resultType="com.yth.entity.Student">
select * from student
</select>
</mapper>
3.5编写sqlMapConfig.xml文件
注意:
- 1.此文件必须放在resources目录下
- 2.数据库链接信息采用配置文件的方式,可以方便之后的修改
- 3.数据库链接信息文件和sqlMapConfig.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">
<!--
mybatis主配置
-->
<configuration >
<properties resource="jdbc.properties"/>
<!--配置mybatis环境-->
<typeAliases>
<package name="com.yth.entity"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源-->
<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/yth/dao/IStudentDao.xml"></mapper>
</mappers>
</configuration>
3.6创建测试类
public class TestMybatis {
public static void main(String[] args) {
try {
// 1.读取配置文件
InputStream in = Resources.getResourceAsStream("
");
// 2.创建session工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(in);
// 3.获取session
SqlSession sqlSession = sqlSessionFactory.openSession();
// 4.使用sqlSession 创建代理对象
// 方式一 通过代理:
// IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class);
// List<Student> studentList = studentDao.getAllStudent();
// 方式二:方式二直接指明方法名
List<Student> studentList = sqlSession.selectList("com.yth.dao.IStudentDao.getAllStudent");
for (Student student:studentList){
System.out.println(student);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
3.7配置mybatis的日志,在resources目录下创建log4j.properties
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=mybatis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
4.mybatis实现增删改查
4.1IStudentDao
/**
* 查询所有学生
*/
List<Student> getAllStudent();
/**
* 根据id查询学生
*/
Student getStudentById(int id);
/**
* 添加学生
*/
int addStudent(Student student);
/**
* 修改学生
*/
int updateStudent(Student student);
/**
* 删除学生
*/
int deleteStudentByName(String name);
4.2IStudentDao.xml
<select id="getStudentById" resultType="com.yth.entity.Student" parameterType="java.lang.Integer">
select * from student where id = #{id}
</select>
<insert id="addStudent" parameterType="com.yth.entity.Student" useGeneratedKeys="true" keyProperty="id" keyColumn="id" >
insert into student (name,sex,age,height) values (#{name},#{sex},#{age},#{height})
</insert>
<update id="updateStudent" parameterType="com.yth.entity.Student">
update student set name=#{name},age=#{age},height=#{height},sex=#{sex} where id=#{id}
</update>
<delete id="deleteStudentByName" >
delete from student where name = #{name}
</delete>
4.3测试
/* // 添加学生
Student student = new Student();
student.setName("吕臣2");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
int num = iStudentDao.addStudent(student);
System.out.println("num:"+num);*/
// 更新学生
/* Student student = new Student();
student.setId(101);
student.setName("吕臣3");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
iStudentDao.updateStudent(student);
*/
// 删除
iStudentDao.deleteStudentByName("吕臣3");
// 提交事务
sqlSession.commit();
注意:
- resultType 标签只存在与select查询中,增删改不需要 映射javabean
- 在sqlSessionFactory创建的时候会在事务中关闭自动提交,因此我们需要手动提交,即sqlSession.commit()。当然sqlSession也提供rollback(),close()方法,之后的文章会有关于事务,SqlSessionFactoryBuilder,SqlSessionFactory,SqlSession的生命周期等问题,以及SqlSession工具类的创建和动态代理生成代理对象实例
5.获取自增id
5.1IStudentDao.xml
<!-- 第一种插入学生 获取id
<selectKey 获取自增id
resultType="int" 自增id 类型
keyColumn="id" 对应数据库表中自增主键列名
keyProperty="id" 传入的实体类中 主键的属性
order="AFTER" 插入完成之后执行 select last_insert_id()
-->
<insert id="addStudentGetId" parameterType="com.yth.entity.Student">
insert into student_tb (name,age,sex,height) values (#{name},#{age},#{sex},#{height})
<selectKey resultType="int" keyColumn="id" keyProperty="id" order="AFTER">
select last_insert_id()
</selectKey>
</insert>
<!--第二种获取自增id
useGeneratedKeys="true" 获取自增id
将数据库表自增id keyColumn="id" 设置到 student对象的属性id keyProperty="id"
-->
<insert id="addStudentGetId" parameterType="com.yth.entity.Student" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into student_tb (name,age,sex,height) values (#{name},#{age},#{sex},#{height})
</insert>
5.2IStudentDao
/**
* 添加学生后 获取自增id
*
* 返回值是 修改数据库的影响行数
* @param student
* @return
*/
int addStudentGetId(Student student);
5.3测试
// 通过sqlSession 获取IStudentDao 的实现类
IStudentDao iStudentDao = sqlSession.getMapper(IStudentDao.class);
// 添加学生
Student student = new Student();
student.setName("大拿");
student.setSex("M");
student.setAge(19);
student.setHeight(170);
// 影响的行数
int num = iStudentDao.addStudentGetId(student);
System.out.println("num:"+num);
// 提交事务
sqlSession.commit();
// 获取自增id
System.out.println("获取自增id:"+student.getId());
6.模糊查询
- 方式一
6.1IStudentDao
/**
* 根据名称模糊查询
* @param likeName
* @return
*/
List<Student> findStudentListByName(String likeName);
6.2在IStudentDao.xml
<select id="findStudentListByName" parameterType="string" resultType="com.yth.entity.Student">
select * from student where name like #{likeName}
</select>
6.3测试
List<Student> studentList = studentDao.findStudentListByName("%an%");
for (Student student:studentList){
System.out.println(student);
}
- 方式2
修改IStudentDao.xml
<select id="findStudentListByName" parameterType="string" resultType="com.yth.entity.Student">
select * from student where name like '%${value}%'
</select>
v a l u e 为 s q l 语 句 的 拼 接 , 以 {value} 为sql语句的拼接,以 value为sql语句的拼接,以{value} 的形式获取likeName的值,并拼接,注意${value}必须是value字段
测试
private static void findStudentByName(IStudentDao studentDao) {
List<Student> studentList = studentDao.findStudentListByName("an");
for (Student student:studentList){
System.out.println(student);
}
}
注意: #{}vs${}区别?
#{}是获取参数中的属性值,并讲java中的类型转化为数据库中的类型
为 s q l 语 句 拼 接 , 以 {} 为sql语句拼接,以 为sql语句拼接,以{value} 获取参数中的值
7.别名的配置
在mybatis中使用parameterType或者resultType 是必须写全限定名,其实在mybatis已经为我们配置好了一些类型别名,我们也可以自定配置别名
系统别名
在mybatis中TypeAliasRegistry已经为我们配置的默认别名
registerAlias("string", String.class);
registerAlias("byte", Byte.class);
registerAlias("long", Long.class);
registerAlias("short", Short.class);
registerAlias("int", Integer.class);
registerAlias("integer", Integer.class);
registerAlias("double", Double.class);
registerAlias("float", Float.class);
registerAlias("boolean", Boolean.class);
registerAlias("byte[]", Byte[].class);
registerAlias("long[]", Long[].class);
registerAlias("short[]", Short[].class);
registerAlias("int[]", Integer[].class);
registerAlias("integer[]", Integer[].class);
registerAlias("double[]", Double[].class);
registerAlias("float[]", Float[].class);
registerAlias("boolean[]", Boolean[].class);
registerAlias("_byte", byte.class);
registerAlias("_long", long.class);
registerAlias("_short", short.class);
registerAlias("_int", int.class);
registerAlias("_integer", int.class);
registerAlias("_double", double.class);
registerAlias("_float", float.class);
registerAlias("_boolean", boolean.class);
registerAlias("_byte[]", byte[].class);
registerAlias("_long[]", long[].class);
registerAlias("_short[]", short[].class);
registerAlias("_int[]", int[].class);
registerAlias("_integer[]", int[].class);
registerAlias("_double[]", double[].class);
registerAlias("_float[]", float[].class);
registerAlias("_boolean[]", boolean[].class);
registerAlias("date", Date.class);
registerAlias("decimal", BigDecimal.class);
registerAlias("bigdecimal", BigDecimal.class);
registerAlias("biginteger", BigInteger.class);
registerAlias("object", Object.class);
registerAlias("date[]", Date[].class);
registerAlias("decimal[]", BigDecimal[].class);
registerAlias("bigdecimal[]", BigDecimal[].class);
registerAlias("biginteger[]", BigInteger[].class);
registerAlias("object[]", Object[].class);
registerAlias("map", Map.class);
registerAlias("hashmap", HashMap.class);
registerAlias("list", List.class);
registerAlias("arraylist", ArrayList.class);
registerAlias("collection", Collection.class);
registerAlias("iterator", Iterator.class);
registerAlias("ResultSet", ResultSet.class);
自定义别名
在mybatis配置文件sqlMapConfig.xml配置,注意typeAliases要写在environments标签之前
<typeAliases>
<!--声明单个别名 使用时忽略大小写-->
<!-- <typeAlias type="com.yth.entity.Student" alias="Student"></typeAlias>-->
<!--扫描包声明别名-->
<package name="com.yth.entity"/>
</typeAliases>
使用
<select id="findStudentListByName" parameterType="string" resultType="Student">
select * from student where name like '%${value}%'
</select>
- 当sql 语句需要参数 时,就要指定对应 参数类型 parameter(基本类型可以不指定),
当sql语句是查询时 需要指定resultType 增删改返回的的时影响到的行数 不需要指定