JDBC笔记(四):经典的ORM框架
Apache DBUtils和SpringJdbcTemplate简化了数据库的操作,但是提供的功能较少。在实际的开发过程中,用的大多都是ORM框架,较为流行的ORM持久层框架:Hibernate、Mybatis。
ORM ( Object Relational Mapping ),即对象关系映射,对象是程序里面的对象,关系是它与数据库里面的数据的关系。ORM框架帮助我们解决的问题是程序对象和关系型数据库的相互映射的问题。
1、Hibernate
Hibernate是全自动的ORM框架,只需简单的配置就可以实现数据库查询操作,无需编写SQL。
1、引入依赖
<!--添加mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- jpa依赖 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency>
SpringJpa是基于Hibernate实现了,maven中有对Hibernate依赖,为了后续演示demo方便,此处我们直接导入SpringJpa的依赖。
2、原生Hibernate配置文件的方式
1、配置文件
实体类的配置文件:为实体类创建hbm的xml映射文件User.hbm.xml。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC '-//Hibernate/Hibernate Mapping DTD 3.0//EN' 'http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd'> <hibernate-mapping> <class name="com.snails.jdbc.entity.User" table="user"> <id name="id" /> <property name="name" column="user_name"></property> <property name="createDate" column="create_date"></property> <property name="updateDate" column="update_date"></property> </class> </hibernate-mapping>
hibernate的配置文件hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 设置JDBC驱动 --> <property name="hibernate.connection.driver_class"> com.mysql.jdbc.Driver </property> <!-- 设置数据库连接及账目 --> <property name="hibernate.connection.url"> jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8 </property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 设置MySQL方言 --> <property name="hibernate.dialect"> org.hibernate.dialect.MySQLDialect </property> <!-- 是否显示SQL --> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 加载对象与数据库表映射关系文件 --> <mapping resource="/hibernate/User.hbm.xml"/> </session-factory> </hibernate-configuration>
2、测试
1 import com.snails.jdbc.entity.User; 2 import org.hibernate.Session; 3 import org.hibernate.SessionFactory; 4 import org.hibernate.Transaction; 5 import org.hibernate.cfg.Configuration; 6 import java.util.Date; 7 8 // hibernate配置文件测试 9 public class HibernateTest { 10 public static void main(String[] args) { 11 Configuration configuration = new Configuration(); 12 // 加载hibernate配置文件 13 configuration.configure("hibernate.cfg.xml"); 14 // 创建Session工厂 15 SessionFactory factory = configuration.buildSessionFactory(); 16 // 创建Session 17 Session session = factory.openSession(); 18 // 获取事务对象 19 Transaction transaction = session.getTransaction(); 20 // 开启事务 21 transaction.begin(); 22 // 把对象添加到数据库中 23 User user = new User(); 24 user.setId(666); 25 user.setName("hibernate"); 26 user.setCreateDate(new Date()); 27 user.setUpdateDate(new Date()); 28 // 数据添加到数据中 29 session.save(user); 30 // 提交事务 31 transaction.commit(); 32 // 关闭session 33 session.close(); 34 } 35 }
3、SpringJPA注解的方式
Spring提供的JPA对持久层框架做了统一的封装,而且本质上就是基于HibernateJPA来实现的,所以在使用的时候可以通过SpringDataJPA的API来操作。通过SpringJPA演示,映射文件的位置用注解代替使用。
1、实体类注解
1 import lombok.Data; 2 import javax.persistence.Column; 3 import javax.persistence.Entity; 4 import javax.persistence.Id; 5 import javax.persistence.Table; 6 import java.util.Date; 7 8 @Data 9 @Entity 10 @Table(name = "user") 11 public class User01 { 12 13 @Id 14 @Column(name = "id") 15 private Integer id; 16 17 @Column(name = "name") 18 private String name; 19 20 @Column(name = "create_date") 21 private Date createDate; 22 23 @Column(name = "update_date") 24 private Date updateDate; 25 }
2、Dao接口定义
1 import com.snails.jdbc.entity.User01; 2 import org.springframework.data.jpa.repository.JpaRepository; 3 4 public interface IUserDao extends JpaRepository<User01, Integer> { 5 }
3、Service定义
1 import com.snails.jdbc.entity.User01; 2 import java.util.List; 3 4 public interface IUserService { 5 6 /** 7 * 查询所有 8 * @return 9 */ 10 public List<User01> queryAll(); 11 }
1 import com.snails.jdbc.entity.User01; 2 import com.snails.jdbc.hibernate.IUserDao; 3 import com.snails.jdbc.hibernate.service.IUserService; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.stereotype.Service; 6 import java.util.List; 7 8 @Service 9 public class UserServiceImpl implements IUserService { 10 11 @Autowired 12 IUserDao userDao; 13 14 @Override 15 public List<User01> queryAll() { 16 return userDao.findAll(); 17 } 18 }
4、单元测试案例
1 import com.SnailsBaseApplication; 2 import com.snails.jdbc.entity.User01; 3 import com.snails.jdbc.hibernate.service.IUserService; 4 import org.junit.Test; 5 import org.junit.runner.RunWith; 6 import org.springframework.beans.factory.annotation.Autowired; 7 import org.springframework.boot.test.context.SpringBootTest; 8 import org.springframework.test.context.junit4.SpringRunner; 9 import java.util.List; 10 11 @RunWith(SpringRunner.class) 12 @SpringBootTest(classes = SnailsBaseApplication.class) 13 public class JDBCTest { 14 15 @Autowired 16 IUserService userService; 17 18 @Test 19 public void testSpringJpa() { 20 List<User01> userList = userService.queryAll(); 21 userList.forEach(user -> { 22 System.out.println(user); 23 }); 24 } 25 }
4、Hibernate总结
4.1、Hibernate优点
1、根据数据库方言自定生成SQL,移植性好;
2、自动管理连接资源;
3、实现了对象和关系型数据的完全映射,操作对象就像操作数据库记录一样;
4、提供了缓存机制。
4.2、Hibernate缺点
1. 无法指定部分字段做更新,操作记录不够灵活
2. 自定义生成SQL的方式,SQL优化较为困难
3. 不支持动态SQL
2、Mybatis
官网地址:https://mybatis.org/mybatis-3/。
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
MyBatis是"半自动"的ORM框架,封装程度没有Hibernate那么高,不会自动生成全部的SQL语句,主要解决的是SQL和对象的映射问题。
1、引入maven依赖
<!--添加mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!-- mybatis依赖 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency>
2、User实体类
1 import lombok.Data; 2 import lombok.ToString; 3 import java.util.Date; 4 5 @Data 6 @ToString 7 public class User { 8 9 private Integer id; 10 11 private String name; 12 13 private Date createDate; 14 15 private Date updateDate; 16 17 }
3、配置文件
3.1、全局配置文件
全局配置文件mybatis-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> <!--数据库属性--> <properties > <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8"/> <property name="username" value="root"/> <property name="password" value="root"/> </properties> <!--开启驼峰模式--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <!--数据库连接环境设置--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!--加载xml文件配置--> <mappers> <mapper resource="mybatis/mapper/UserMapper.xml"/> </mappers> </configuration>
3.2、实体Mapper配置文件
实体映射文件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.snails.jdbc.mybatis.UserMapper"> <select id="queryAll" resultType="com.snails.jdbc.entity.User"> select * from user </select> </mapper>
3.3、单元测试案例
1 import com.SnailsBaseApplication; 2 import com.snails.jdbc.entity.User; 3 4 5 import com.snails.jdbc.mybatis.UserMapper; 6 import org.apache.ibatis.io.Resources; 7 import org.apache.ibatis.session.SqlSession; 8 import org.apache.ibatis.session.SqlSessionFactory; 9 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 10 import org.junit.Test; 11 import org.junit.runner.RunWith; 12 import org.springframework.boot.test.context.SpringBootTest; 13 import org.springframework.test.context.junit4.SpringRunner; 14 import java.io.IOException; 15 import java.io.InputStream; 16 import java.util.List; 17 18 @RunWith(SpringRunner.class) 19 @SpringBootTest(classes = SnailsBaseApplication.class) 20 public class MybatisTest { 21 22 /** 23 * Mybatis编程式查询数据库 24 */ 25 @Test 26 public void testMybatisCode() throws IOException { 27 // 1.获取配置文件 28 InputStream in = Resources.getResourceAsStream("mybatis/mybatis-config.xml"); 29 // 2.加载解析配置文件并获取SqlSessionFactory对象 30 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); 31 // 3.根据SqlSessionFactory对象获取SqlSession对象 32 SqlSession sqlSession = factory.openSession(); 33 // 4.通过SqlSession中提供的 API方法来操作数据库 34 List<User> list = sqlSession.selectList("com.snails.jdbc.mybatis.UserMapper.queryAll"); 35 for (User user : list) { 36 System.out.println(user); 37 } 38 // 5.关闭会话 39 sqlSession.close(); 40 } 41 42 /** 43 * Mybatis代理方式查询数据库 44 */ 45 @Test 46 public void testMybatisProxy() throws IOException { 47 // 1.获取配置文件 48 InputStream in = Resources.getResourceAsStream("mybatis/mybatis-config.xml"); 49 // 2.加载解析配置文件并获取SqlSessionFactory对象 50 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); 51 // 3.根据SqlSessionFactory对象获取SqlSession对象 52 SqlSession sqlSession = factory.openSession(); 53 // 4.通过SqlSession获取UserMapper接口 54 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 55 List<User> list = mapper.queryAll(); 56 for (User user : list) { 57 System.out.println(user); 58 } 59 // 5.关闭会话 60 sqlSession.close(); 61 } 62 63 }