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);// 獲取sqlsessionSqlSession sqlSession = build.openSession();// 調用Mybatis原生接口執行sqlString 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);// 獲取sqlsessionSqlSession 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());