概述
ORMapping: Object Relationship Mapping 对象关系映射
对象指⾯面向对象
关系指关系型数据库
Java 到 MySQL 的映射,开发者可以以⾯面向对象的思想来管理理数据库。
如何使用
1 新建Maven工程,pom.xml
pom.xml
<?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.southwind</groupId>
<artifactId>aimybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<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>8.0.11</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.6</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!--使java文件里面的xml文件可读-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
2 新建数据表
use mybatis;
create table t_account(
id int primary key auto_increment,
username varchar(11),
password varchar(11),
age int
)
3 新建数据表对应的实体类Account
Account.java
package com.southwind.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
private long id;
private String username;
private String password;
private int age;
}
4 创建MyBatis的配置文件 config.xml 文件名可自定义
放在resources目录下
<?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="development">
<environment id="development">
<!-- 配置JDBC事务管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- POOLED配置JDBC数据源连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</dataSource>
</environment>
</environments>
</configuration>
5 MyBatis开发方式一 使用原生接口
1、MyBatis 框架需要开发者⾃定义 SQL 语句,写在 Mapper.xml ⽂件中,实际开发中,会为每个实体类创建对应的 Mapper.xml ,定义管理该对象数据的 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="com.southwind.mapper.AccoutMapper">
<insert id="save" parameterType="com.southwind.entity.Account">
insert into t_account(username,password,age) values (#{username},#{password},#{age})
</insert>
</mapper>
namespace 通常设置为⽂件所在包+⽂件名的形式。
insert 标签表示执行添加操作。
- select 标签表示执行查询操作。
- update 标签表示执行更新操作。
delete 标签表示执⾏删除操作。
id 是实际调⽤ MyBatis ⽅法时需要⽤到的参数。
- parameterType 是调用对应⽅法时参数的数据类型。
2、在全局配置文件 config.xml 中注册 AccountMapper.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="development">
<environment id="development">
<!-- 配置JDBC事务管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- POOLED配置JDBC数据源连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</dataSource>
</environment>
</environments>
<!-- 注册AccountMapper.xml -->
<mappers>
<mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
</mappers>
</configuration>
3、调用MyBatis的原生接口执行添加操作
测试类
package com.southwind.test;
import com.southwind.entity.Account;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
public class Test {
public static void main(String[] args) {
//加载MyBatis的配置文件
InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
String statement = "com.southwind.mapper.AccoutMapper.save"; //namespace.id
Account account = new Account(1L,"张三","123123",22);
sqlSession.insert(statement, account);
sqlSession.commit();
}
}
5 MyBatis开发方式二 通过Mapper代理实现自定义接口
- 自定义接口,定义相关业务方法
- 编写与方法相对应的Mapper.xml
Tips:咱们只需要定义接口和Mapper.xml,实现类和对象都是Mapper自动生成的
1、自定义接口
package com.southwind.repository;
import com.southwind.entity.Account;
import java.util.List;
public interface AccountRepository {
public int save(Account account);
public int update(Account account);
public int deleteById(Long id);
public List<Account> findAll();
public Account findById(Long id);
}
2、创建接⼝对应的 Mapper.xml,定义接口⽅方法对应的 SQL 语句。
statement 标签可根据 SQL 执行的业务选择 insert、delete、update、select。
MyBatis 框架会根据规则⾃动创建接⼝实现类的代理对象。
规则:
Mapper.xml 中 namespace 为接⼝的全类名。
Mapper.xml 中 statement 的 id 为接⼝中对应的方法名。
Mapper.xml 中 statement 的 parameterType 和接⼝中对应方法的参数类型一致。
Mapper.xml 中 statement 的 resultType 和接⼝中对应方法的返回值类型⼀致。
<?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.southwind.repository.AccountRepository">
<insert id="save" parameterType="com.southwind.entity.Account">
insert into t_account(username,password,age) values(#{username},#{password},#{age})
</insert>
<update id="update" parameterType="com.southwind.entity.Account">
update t_account set username = #{username},password = #{password},age= #{age} where id = #{id}
</update>
<delete id="deleteById" parameterType="long">
delete from t_account where id = #{id}
</delete>
<select id="findAll" resultType="com.southwind.entity.Account"><!--不要写集合,应该写集合里的范型的类型-->
select * from t_account
</select>
<select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
select * from t_account where id = #{id}
</select>
</mapper>
3、在 config.xml 中注册 AccountRepository.xml
追加即可
<!-- 注册AccountMapper.xml -->
<mappers>
<mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
<mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
</mappers>
4、调⽤用接⼝的代理对象完成相关的业务操作
测试类Test2.java
package com.southwind.test;
import com.southwind.entity.Account;
import com.southwind.repository.AccountRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.List;
public class Test2 {
public static void main(String[] args) {
//加载配置文件
InputStream inputStream = Test2.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取实现接口的代理对象
AccountRepository accountRepository = sqlSession.getMapper(AccountRepository.class);
//添加对象
// Account account = new Account(2L,"cheung","12345",20);
// int save = accountRepository.save(account);
// sqlSession.commit();
// System.out.println("影响了" + save + "行");
//查询对象
// List<Account> list = accountRepository.findAll();
// for(Account account:list){
// System.out.println(account);
// }
//通过id查询对象
// Account account = accountRepository.findById(3L);
// System.out.println(account);
//update修改对象
// Account account = accountRepository.findById(3L);
// account.setUsername("⼩小明");
// account.setPassword("000");
// account.setAge(18);
// int result = accountRepository.update(account);
// sqlSession.commit();
// System.out.println("影响了" + result + "行");
//通过id删除对象
// int result = accountRepository.deleteById(3L);
// sqlSession.commit();
// System.out.println(result);
sqlSession.close();
}
}
Mapper.xml
Tips:environment是告诉mybatis怎么连接数据库,mapper是说,我怎么跟数据库里的表映射的。
statement标签:select、update、dalete、insert分别对应查询、修改、删除、添加操作。
parameterType:参数数据类型
1、基本数据类型,通过id查询Account
<select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
select * from t_account where id = #{id}
</select>
2、String类型,通过name查询Account
<select id="findByName" parameterType="java.lang.String" resultType="com.southwind.entity.Account">
select * from t_account where username = #{username}
</select>
3、包装类,通过id查询Account
Tips:为什么要用包装类 因为基本数据类型不能接受null值
<select id="findById2" parameterType="java.lang.Long" resultType="com.southwind.entity.Account">
select * from t_account where id = #{id}
</select>
4、多个参数,通过name和age查询Account
那parameterType
写谁呢?我直接不写
Mapping.xml
<select id="findByNameAndAge" resultType="com.southwind.entity.Account">
select * from t_account where username = #{arg0} and age = #{arg1}
</select>
Tips:读参通过下标来取
arg从0开始 param从1开始
5、Java Bean
常用的修改 就是传bean进去
<update id="update" parameterType="com.southwind.entity.Account">
update t_account set username = #{username},password = #{password},age =#{age} where id = #{id}
</update>
resultType:结果类型
1、基本数据类型,统计Account总数
<select id="count" resultType="int">
select count(id) from t_account
</select>
2、包装类,统计Account总数
<select id="count2" resultType="java.lang.Integer">
select count(id) from t_account
</select>
3、String类型,通过id查询Account的name
<select id="findNameById" resultType="java.lang.String">
select username from t_account where id = #{id}
</select>
4、Java Bean
<select id="findById" parameterType="long" resultType="com.southwind.entity.Account">
select * from t_account where id = #{id}
</select>
及联查询
一对多(学生查班级)
1 建对应实体类
Student.java
package com.southwind.entity;
import lombok.Data;
@Data
public class Student {
private long id;
private String name;
private Classes classes;
}
Classes.java
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Classes {
private long id;
private String name;
private List<Student> students;
}
大概要怎么查询呢?
2 写接口
package com.southwind.repository;
import com.southwind.entity.Student;
public interface StudentRepository {
public Student findById(long id);
}
3 写mapping.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.southwind.repository.StudentRepository">
<resultMap id="studentMap" type="com.southwind.entity.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<association property="classes" javaType="com.southwind.entity.Classes">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</association>
</resultMap>
<select id="findById" parameterType="long" resultMap="studentMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where s.id = #{id} and s.cid = c.id;
</select>
</mapper>
主键用
column对应了结果集的字段
property对应了实体类的属性
4 在config.xml里面注册mapper
<!-- 注册AccountMapper.xml -->
<mappers>
<mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
<mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
<mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
</mappers>
5 测试
一对多(班级查学生)
接口
package com.southwind.repository;
import com.southwind.entity.Classes;
public interface ClassesRepository {
public Classes findById(long id);
}
Mapping.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.southwind.repository.ClassesRepository">
<resultMap id="classesMap" type="com.southwind.entity.Classes">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
<collection property="students" ofType="com.southwind.entity.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
</collection>
</resultMap>
<select id="findById" parameterType="long" resultMap="classesMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,classes c where c.id = #{id} and s.cid = c.id;
</select>
</mapper>
在config里注册mapper
<!-- 注册AccountMapper.xml -->
<mappers>
<mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
<mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
<mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
<mapper resource="com/southwind/repository/ClassesRepository.xml"></mapper>
</mappers>
测试
多对多(查顾客购买的商品)
数据库表
JavaBean
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Customer {
private long id;
private String name;
private List<Goods> goods;
}
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Goods {
private long id;
private String name;
private List<Customer> customers;
}
接口
package com.southwind.repository;
import com.southwind.entity.Customer;
public interface CustomerRepository {
public Customer findById(long id);
}
mapping.xml并在config中注册
<?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.southwind.repository.CustomerRepository">
<resultMap id="customerMap" type="com.southwind.entity.Customer">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
<collection property="goods" ofType="com.southwind.entity.Goods">
<id column="gid" property="id"></id>
<result column="gname" property="name"></result>
</collection>
</resultMap>
<select id="findById" parameterType="long" resultMap="customerMap">
select c.id cid,c.name cname,g.id gid,g.name gname from customer c,goods g,customer_goods cg where c.id = #{id} and cg.cid = c.id and cg.gid = g.id;
</select>
</mapper>
<!-- 注册AccountMapper.xml -->
<mappers>
<mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
<mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
<mapper resource="com/southwind/repository/StudentRepository.xml"></mapper>
<mapper resource="com/southwind/repository/ClassesRepository.xml"></mapper>
<mapper resource="com/southwind/repository/CustomerRepository.xml"></mapper>
</mappers>