DAY21.1 Java核心基础
ORM
Object Relationship Mapping 对象关系映射
面向对象的程序到—关系型数据库的映射
比如java – MySQL的映射
ORM框架就是实现这个映射的框架
Hibernate、Mybatis、MybatisPlus、Spring Data JPA、Spring JDBC
Spring Data JPA的底层就是Hibernate
Mybatis和Hibernate
Mybatis是一个JDBC封装的工具,是帮助开发者实现数据持久化 工作的框架
Mybatis和Hibernate的区别?
Mybatis:半自动框架,Mybatis没有实现java对象到数据库表的映射,只实现了java程序和sql之间的映射
Hibernate:全自动框架,开发者只需要调用接口就可以完成相关的操作,整个框架已经封装好,不需要开发者关注
但是全自动框架不灵活,有些业务场景实现并不方便,半自动框架灵活,可以根据具体业务来写sql,更适合现代企业级项目的开发
Mybatis的优缺点
优点:
- 极大简化了JDBC的开发
- 更好上手,有更好的灵活性
- 通过定义sql在xml文件里面降低程序的耦合度
- 支持动态sql,可以根据业务灵活实现需求
缺点:
- 数据库迁移的时候需要更改大量的sql语句
- 相较于Hibernate,需要完成更多的工作,定义sql,设置sql与数据库表的关系
使用教程
使用原生接口:
创建maven工程,导入相关依赖
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.31</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
创建实体类User
@Data
public class User {
private Integer id;
private String name;
private String pwd;
private String email;
}
在resource创建一个config.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>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mytest1"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
两种使用方式:
-
使用原生接口
-
使用mapper代理
使用原生接口
创建mapper文件
namespace:通常设置为文件所在包名和文件
UserMapper.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.shuwu.mapper.UserMapper">
<select id="get" parameterType="int" resultType="com.shuwu.entity.User">
select * from user where id = #{id}
</select>
</mapper>
在配置文件添加注册mapper,让配置文件可以扫描到
<mappers>
<mapper resource="com/shuwu/mapper/UserMapper.xml"></mapper>
</mappers>
测试用例:
public class Test {
public static void main(String[] args) {
// 找到类加载器,通过配置文件的输入流然后创建一个SqlSession工厂
InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("com/mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
// 获取sqlsession
SqlSession sqlSession = build.openSession();
// 调用Mybatis原生接口执行sql
String statement = "com.shuwu.mapper.UserMapper.get";
User user = sqlSession.selectOne(statement, 1);
System.out.println(user);
}
}
测试结果:
要确保数据库里面有对应的表结构
1、通过配置文件创建 MyBatis 环境(数据源、Mapper)
2、构建环境需要使用 SqlSessionFactory
使用mapper代理实现自定义接口
自定义接口,开发者只需要定义,不需要实现
定义mapper接口
public interface UserMapper {
public User getUserById(Integer id);
public List<User> getAllUser();
}
mapper接口映射的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.shuwu.mapper.UserMapper">
<select id="getUserById" resultType="com.shuwu.entity.User">
select * from user where id = #{id}
</select>
<select id="getAllUser" resultType="com.shuwu.entity.User">
select * from user
</select>
</mapper>
要注意!!
- namespace需要指定到mapper接口的文件
- 方法名和xml里面的id必须一致
- 返回值的resultType的放回类型必须一致
- 方法传递参数名字必须对应,如果不一致可以用@Param来声明参数名字
比如:
public User getUserById(@Param("id") Integer id2);
增加、删除、修改用户
<?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.shuwu.mapper.UserMapper">
<insert id="addUser">
insert into user(name,pwd,email) values(#{name},#{pwd},#{email})
</insert>
<update id="updateUser" parameterType="com.shuwu.entity.User">
update user set name=#{name},pwd=#{pwd},email=#{email} where id = #{id}
</update>
<delete id="deleteUser" parameterType="integer">
delete from user where id = #{id}
</delete>
<select id="getUserById" resultType="com.shuwu.entity.User">
select * from user where id = #{id}
</select>
<select id="getAllUser" resultType="com.shuwu.entity.User">
select * from user
</select>
</mapper>
public interface UserMapper {
public User getUserById(@Param("id") Integer id2);
public List<User> getAllUser();
public int addUser(User user);
public int deleteUser(@Param("id") Integer id);
}
public static void main(String[] args) {
// 找到类加载器,然后创建一个工厂
InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("com/mybatis-config.xml");
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
// 获取sqlsession
SqlSession sqlSession = build.openSession();
// 获取接口的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 添加用户
mapper.addUser(new User(null,"shuwu","123","123@qq.com"));
// 根据id删除用户
mapper.deleteUser(4);
// 根据User的id修改用户信息
mapper.updateUser(new User(1,"shuwu","123","123@qq.com"));
// 提交事务
sqlSession.commit();
}
增删改 数据库的时候要注意需要提交事务,不然MySQL只会保存不会添加进数据库
sqlSession.commit();
Mapperxml
全局配置文件 mybatis-config.xml
Mapper 配置文件 UserMapper.xml
mybatis-config.xml:主要用来定义数据源信息和一些基本配置,事务管理、打印 SQL,开启二级缓存、设置延迟加载
UserMapper.xml:定义对应接口方法的 SQL 实现,需要在 mybatis-config.xml 中进行注册才可以使用
半自动化的 ORM 框架,SQL 需要开发者自定义,MyBatis 关注的是 Java 对象和 SQL 之间的关系,SQL 语句是在 Mapper.xml 中定义
parameterType
参数数据类型介绍
包装类型
Integer类型
public int deleteUser(@Param("id") Integer id);
<delete id="deleteUser" parameterType="integer">
delete from user where id = #{id}
</delete>
用户的SQL语句是where id = #{id},这里的id可能是int或Integer。如果调用这个方法时传入的是单个参数,比如Integer,MyBatis会自动识别参数类型,不需要显式指定parameterType。
String类型
public User getByUserName(@Param("name") String name);
<select id="getByUserName" resultType="com.shuwu.entity.User">
select * from user where name=#{name}
</select>
基本数据类型
int、flout、double…
public User getByAge(int age);
<select id="getByAge" parameterType="int" resultType="com.southwind.entity.User">
select * from user where age = #{age}
</select>
实体类
public List<User> getAllUser();
<select id="getAllUser" resultType="com.shuwu.entity.User">
select * from user
</select>
5、多个参数
public User getUsernameAndAge(String username,Integer age);
<select id="getUsernameAndAge" resultType="com.southwind.entity.User">
select * from user where username = #{param1} and age = #{param2}
</select>
resultType
返回类型
1、基本数据类型
public int getCount();
<select id="getCount" resultType="int">
select count(*) from user
</select>
2、包装类
public Integer getCount2();
<select id="getCount2" resultType="java.lang.Integer">
select count(*) from user
</select>
3、String
public String getUsernameById(Integer id);
<select id="getUsernameById" parameterType="java.lang.Integer" resultType="java.lang.String">
select username from user where id = #{id}
</select>
4、实体类
public User getById(Integer id);
<select id="getById" parameterType="java.lang.Integer" resultType="com.southwind.entity.User">
select * from user where id = #{id}
</select>
级联查询
实际开发中常见的是一对多和多对多关系
如果要查询学生信息和班级信息的关系呢?
SELECT student.id sid, student.`name` sname,class.id cid,class.`name` cname from student,class where student.cid = class.id
怎么在java程序中实现呢
先定义一个可以接收这个参数的student对象
@Data
public class Student {
private Integer id;
private String name;
private Class clazz;
}
@Data
public class Class {
private Integer id;
private String name;
}
但是有时候这个字段和数据库里面的字段不匹配怎么办呢?
这个clazz怎么和数据库对应呢?
这个时候就需要写一个字段映射了
mapper接口
public List<Student> getAllStudent();
xml映射
通过使用 resultMap="StudentMap"来设置一个返回值的字段映射
<resultMap id="StudentMap" type="com.shuwu.entity.Student">
<id property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="clazz" javaType="com.shuwu.entity.Class">
<id property="id" column="cid"/>
<result property="name" column="cname"/>
</association>
</resultMap>
<select id="getAllStudent" resultType="com.shuwu.entity.Student" resultMap="StudentMap">
SELECT student.id sid, student.`name` sname,class.id cid,class.`name` cname from student,class where student.cid = class.id
</select>
测试输入:
System.out.println(mapper.getAllStudent());