MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google
code,并且改名为MyBatis 。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL
Maps和Data Access Objects(DAOs)
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC
代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java
的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于
学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。
通过sql语句可以满足操作数据库的所有需求。
解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维
护,更易单元测试。sql和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.aaa</groupId>
<artifactId>mybatis-Test</artifactId>
<version>1.0-SNAPSHOT</version>
<!-- 写我们工程需要依赖的jar -->
<dependencies>
<!-- mybatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<!-- mysql 驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<!-- log4j 依赖 -->
<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>
</project>
3.com.aaa.dao.IStudentDao
package com.aaa.dao;
import com.aaa.entity.Student;
import com.aaa.entity.Student2;
import java.util.List;
/**
* ClassName:IStudentDao
* Package:com.aaa.dao
* Description:
*
* @date:2020/7/9 9:10
* @author:[email protected]
*/
public interface IStudentDao {
List<Student> findAllStudent();
Student findAllStduentById(int id);
int insertStudent(Student student);
int updateStudent(Student student);
int deleteStudent(Student student);
int insertStudentForKey(Student student);
List<Student> updateStunetLikeName(String name);
Student2 findAllStduentById2(int id);
}
4.com.aaa.entity.Student
com.aaa.entity.Student2
package com.aaa.entity;
import java.util.Date;
/**
* ClassName:Goods
* Package:com.aaa.entity
* Description:
*
* @date:2020/7/9 13:52
* @author:[email protected]
*/
public class Goods {
private int id;
private int img_id ;
private String name;
private String content;
private int status;
private int create_time ;
private int update_time ;
public Goods() {
}
public Goods(int id, int img_id, String name, String content, int status, int create_time, int update_time) {
this.id = id;
this.img_id = img_id;
this.name = name;
this.content = content;
this.status = status;
this.create_time = create_time;
this.update_time = update_time;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getImg_id() {
return img_id;
}
public void setImg_id(int img_id) {
this.img_id = img_id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public int getCreate_time() {
return create_time;
}
public void setCreate_time(int create_time) {
this.create_time = create_time;
}
public int getUpdate_time() {
return update_time;
}
public void setUpdate_time(int update_time) {
this.update_time = update_time;
}
@Override
public String toString() {
return "Goods{" +
"id=" + id +
", img_id=" + img_id +
", name='" + name + '\'' +
", content='" + content + '\'' +
", status=" + status +
", create_time=" + create_time +
", update_time=" + update_time +
'}';
}
}
package com.aaa.entity;
/**
* ClassName:Student2
* Package:com.aaa.entity
* Description:
*
* @date:2020/7/9 10:18
* @author:[email protected]
*/
public class Student2 {
private int id;
private int age;
private int height;
private String sex;
private String studentName;
private String name;
public Student2() {
}
@Override
public String toString() {
return "Student2{" +
"id=" + id +
", age=" + age +
", height=" + height +
", sex='" + sex + '\'' +
", studentName='" + studentName + '\'' +
", name='" + name + '\'' +
'}';
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Student2(int id, int age, int height, String sex, String studentName, String name) {
this.id = id;
this.age = age;
this.height = height;
this.sex = sex;
this.studentName = studentName;
this.name = name;
}
}
5.resources com/aaa/dao/GoodsDao.xml 必须与dao层的方法名相同
<?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 对应的是字符串一般是 对应dao层 接口全限定名 -->
<mapper namespace="com.aaa.dao.IStudentDao">
<!-- select 有 parameterType(参数类型) resultType(返回数据类型)
update insert delete 只有 resultType
id 对应 dao 方法名
resultType 设置返回值 类型 如果返回的是集合 那么写集合中元素类型
-->
<select id="findAllStudent" resultType="com.aaa.entity.Student">
select * from student
</select>
<!-- #{} 相当于 ? 占位符 -->
<select id="findAllStduentById" parameterType="int" resultType="com.aaa.entity.Student">
select * from student where id = #{id}
</select>
<insert id="insertStudent" parameterType="com.aaa.entity.Student">
insert into student (name,sex,age,height) values (#{name},#{sex},#{age},#{height})
</insert>
<update id="updateStudent" parameterType="com.aaa.entity.Student">
update student set name=#{name},sex=#{sex},age=#{age},height=#{height} where id=#{id}
</update>
<delete id="deleteStudent" parameterType="com.aaa.entity.Student">
delete from student where id=#{id}
</delete>
<!-- <selectKey keyProperty="id" keyColumn="id" resultType="java.lang.Integer" order="AFTER">
select last_insert_id()
</selectKey>-->
<insert id="insertStudentForKey" parameterType="com.aaa.entity.Student">
insert into student(name,sex,age,height) values (#{name},#{sex},#{age},#{height})
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
</insert>
<select id="updateStunetLikeName" parameterType="string" resultType="com.aaa.entity.Student">
select * from student where name like #{name}
</select>
<!-- 将sql语句查出来的列进行 一个映射,解决实体类属性 和 sql表中列名不匹配的问题
并且可以多次调用
-->
<!-- <resultMap id="student2map" type="student2">
<id property="id" column="id"></id>
<result property="studentName" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
</resultMap>-->
<!--给列起别名???-->
<!-- <select id="findAllStduentById2" parameterType="int" resultMap="student2map">
select id,name,age,sex,height from student where id = #{id}
</select>-->
<select id="findAllStduentById2" parameterType="int" resultType="student2">
select id,name as studentName,age,sex,height from student where id = #{id}
</select>
<!-- <select id="findAllStduentById2" parameterType="int" resultType="Student2">
select * from student where id = #{id}
</select>-->
</mapper>
6.log4j.properties 配置log4j 为了调用dubug模式
# 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
7.在resources下面新建mybatisconfig.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>
<!--开启驼峰命名法-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<!-- 别名 必须environments 之前 不区分大小写 -->
<!-- 用别名之后 不需要每次返回resultType 或者 parameter时 不用写全限定名了 -->
<!-- 两种方式,类似于mapper -->
<typeAliases>
<!--<typeAlias type="com.aaa.entity.Student" alias="student"></typeAlias>-->
<package name="com.aaa.entity"/>
</typeAliases>
<!-- 1.配置mybats 连接到sql -->
<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/student_db"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 扫描mappers下面所有的dao接口 并在mybatis中声明-->
<package name="com.aaa.dao"/>
</mappers>
</configuration>
8.Test com/aaa/dao/MyBatisTest.java
package com.aaa.dao;
import com.aaa.entity.Student;
import com.aaa.entity.Student2;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* ClassName:MyBatisTest
* Package:com.aaa.dao
* Description:
*
* @date:2020/7/9 9:28
* @author:[email protected]
*/
public class MyBatisTest {
public static void main(String[] args) {
//读取配mybatisconfig.xml置文件
try {
InputStream in = Resources.getResourceAsStream("mybatisconfig.xml");
//SqlSessionFactoryBuilder 建造者模式
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建 mybatis 连接mysql的工厂 相当于 创建jdbc中connect工厂
SqlSessionFactory sqlSessionFactory = builder.build(in);
//创建一个会话连接 自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取mapper dao的实体类
IStudentDao studentDao = sqlSession.getMapper(IStudentDao.class);
/*
*@Author lee
*@time:2020/7/9 9:34
*注释:查询
*/
/* List studentList = studentDao.findAllStudent();
for (Student student:studentList){
System.out.println("stduent:"+student);
}*/
/*
*@Author lee
*@time:2020/7/9 9:46
*注释:根据ID查询
*/
/*Student student = studentDao.findAllStduentById(1);
System.out.println(student);*/
/*
*@Author lee
*@time:2020/7/9 9:52
*注释:新增学生信息
*/
/*Student student = new Student();
student.setName("冰冰");
student.setAge(18);
student.setSex("女");
student.setHeight(180);
int num = studentDao.insertStudent(student);
if (num>0){
System.out.println(student);
}*/
/*
*@Author lee
*@time:2020/7/9 9:57
*注释:修改学生信息
*/
/* Student student = new Student();
student.setName("冰冰");
student.setAge(18);
student.setSex("女");
student.setHeight(180);
student.setId(1);
int num = studentDao.updateStudent(student);
if (num>0){
System.out.println(student);
}
*/
/*
*@Author lee
*@time:2020/7/9 10:00
*注释:删除学生信息
*/
/* Student student =new Student();
student.setId(8);
int i=studentDao.deleteStudent(student);
System.out.println(student);*/
/*
*@Author lee
*@time:2020/7/9 10:06
*注释:新增返回主键
*/
/* Student student = new Student();
student.setName("冰冰");
student.setAge(18);
student.setSex("女");
student.setHeight(180);
int num = studentDao.insertStudentForKey(student);
if (num>0) {
System.out.println("id:"+student.getId());
}*/
/*
*@Author lee
*@time:2020/7/9 10:11
*注释:模糊查询
*/
/*List studentList =studentDao.updateStunetLikeName("%三%");
for (Student student:studentList){
System.out.println(student);
}*/
/*
*@Author lee
*@time:2020/7/9 10:46
*注释:别名
*/
Student2 student2 = studentDao.findAllStduentById2(12);
System.out.println(student2);
} catch (IOException e) {
e.printStackTrace();
}
}
}
主要整理的知识操作有:
**a.全限定名设置别名
b.获取自增id两种方式
c.如何设置别名
d.驼峰写法的作用
e.配置文件的顺序
f.模糊插叙的两种方式
g.琐碎知识点回忆
**
重点笔记
a.全限定名设置别名 mybatisconfig.xml
<!-- 别名 必须environments 之前 不区分大小写 -->
<!-- 用别名之后 不需要每次返回resultType 或者 parameter时 不用写全限定名了 -->
<!-- 两种方式,类似于mapper -->
<typeAliases>
<!--<typeAlias type="com.aaa.entity.Student" alias="student"></typeAlias>-->
<package name="com.aaa.entity"/>
</typeAliases>
在这里插入代码片
b.获取自增id的两种方式 IStudentDao.xml
主键必须自增 (useGeneratedKeys=“true”)
${} 占位符 ?
<!-- <insert id="insertStudentForKey" parameterType="com.aaa.entity.Student" useGeneratedKeys="true"
keyColumn="id" keyProperty="id" >
insert into student (name,sex,age,height) values (#{name},#{sex},#{age},#{height})
</insert>-->
<insert id="insertStudentForKey" parameterType="com.aaa.entity.Student">
insert into student(name,sex,age,height) values (#{name},#{sex},#{age},#{height})
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
c.如何设置别名
分为三种方式
1.通过(IStudentDao.xml配置)resultMap
2.sql语句中起别名(IStudentDao.xml) select name as studentName from student where id = #{id}
3.驼峰命名法(mybatisconfig.xml):
<!--开启驼峰命名法-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
**
<!-- 将sql语句查出来的列进行 一个映射,解决实体类属性 和 sql表中列名不匹配的问题
并且可以多次调用
-->
<!-- <resultMap id="student2map" type="student2">
<id property="id" column="id"></id>
<result property="studentName" column="name"></result>
<result property="sex" column="sex"></result>
<result property="age" column="age"></result>
<result property="height" column="height"></result>
</resultMap>-->
<!--给列起别名???-->
<!-- <select id="findAllStduentById2" parameterType="int" resultMap="student2map">
select id,name,age,sex,height from student where id = #{id}
</select>-->
<select id="findAllStduentById2" parameterType="int" resultType="student2">
select id,name as studentName,age,sex,height from student where id = #{id}
</select>
d.驼峰命名法的作用
sql:属性列如果有 (下划线) 例如: student_Name,student_Age,student_height,student_sex
entity:实体类属性 如果定义的变量如果和sql中的属性列不相同,通过驼峰命名法就可以按相同属性列进行数据传递
例如:
private int stuentId;
private int stduentAge;
private int studentHeight;
private String studentSex;
private String studentName;
e.配置文件的顺序
配置文件的顺序已经按1-8步骤配置好了
f.模糊查询有两种方式
**模糊查询 第一种方式要求**
<select id="updateStunetLikeName" parameterType="string" resultType="com.aaa.entity.Student">
select * from student where name like #{name}
</select>
**模糊查询 第二种方式要求 主键自增(useGeneratedKeys="true")**
<!-- <insert id="insertStudentForId" parameterType="com.aaa.entity.Student" useGeneratedKeys="true"
keyColumn="id" keyProperty="id" >
insert into student (name,sex,age,height) values (#{name},#{sex},#{age},#{height})
</insert>-->
g.琐碎知识点
第一种模糊查询 | #{name} 占位符 select * from student where name like #{name} 例:("%小%") |
---|---|
第二种模糊查询 | ${} sql 语句的替换 v a l u e s e l e c t ∗ f r o m s t u d e n t w h e r e n a m e l i k e ′ {value} select * from student where name like '% valueselect∗fromstudentwherenamelike′{value}%’ 例: “小” |
分为自动提交和手动提交 | 创建一个会话 连接 SqlSession sqlSession = sqlSessionFactory.openSession(); |
– | – |
以自动提交方式获取 sql session | SqlSession sqlSession = sqlSessionFactory.openSession(true); |
jdbc 中的查询 | 查询如果没有参数,就没有参数类型,返回值类型看 具体所需 |
– | – |
新增,修改,删除 | 中Int i 定义的变量 i 返回的是影响条数 |
代理mapper的作用 | 1.过滤 |
2.通过接口反射生成实现类 | |
实体类与数据库的映射 | 命名一定要相同,如果不同会报错,如果定义的不同可以通过别名的三种方法改正 |
区分实体类的别名与全限定名的区别 | 实体类的别名有三种:1.驼峰,2.sql查询语句中起别名,3.resultMap进行映射 |
– | – |
全限定名:在mybatiscong.xml 中配置 如下代码: |
<!-- 别名 必须environments 之前 不区分大小写 -->
<!-- 用别名之后 不需要每次返回resultType 或者 parameter时 不用写全限定名了 -->
<!-- 两种方式,类似于mapper -->
<typeAliases>
<!--<typeAlias type="com.aaa.entity.Student" alias="student"></typeAlias>-->
<package name="com.aaa.entity"/>
</typeAliases>