我们在使用 Spring JDBC 之前,需要进行一些配置。这里我把配置信息放在了 application.xml 文件中,后面写测试代码时,让容器去加载这个配置。配置内容如下:
<context:property-placeholder location="jdbc.properties"/> <bean> <property value="${jdbc.driver}" /> <property value="${jdbc.url}" /> <property value="${jdbc.username}" /> <property value="${jdbc.password}" /> </bean> <bean> <property ref="dataSource" /> </bean>如上,JdbcTemplate封装了一些访问数据库的方法,下面我们会通过此对象访问数据库。演示代码如下:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application.xml") public class SpringJdbcTest { @Autowired private JdbcTemplate jdbcTemplate; @Test public void testSpringJdbc() { String author = "coolblog.xyz"; String date = "2018.06.10"; String sql = "SELECT id, title, author, content, create_time FROM article WHERE author = '" + author + "' AND create_time > '" + date + "'"; List<Article> articles = jdbcTemplate.query(sql, (rs, rowNum) -> { Article article = new Article(); article.setId(rs.getInt("id")); article.setTitle(rs.getString("title")); article.setAuthor(rs.getString("author")); article.setContent(rs.getString("content")); article.setCreateTime(rs.getDate("create_time")); return article; }); System.out.println("Query SQL ==> " + sql); System.out.println("Spring JDBC Query Result: "); articles.forEach(System.out::println); } }测试结果如下:
从上面的代码中可以看得出,Spring JDBC 还是比较容易使用的。不过它也是存在一定缺陷的,比如 SQL 仍是写在代码中。又比如,对于较为复杂的结果(数据库返回的记录包含多列数据),需要用户自行处理 ResultSet 等。不过与 JDBC 相比,使用 Spring JDBC 无需手动加载数据库驱动,获取数据库连接,以及创建 Statement 对象等操作。总的来说,易用性上得到了不少的提升。
这里就不对比 Spring JDBC 和 MyBatis 的优缺点了。Spring JDBC 仅对 JDBC 进行了一层比较薄的封装,相关对比可以参考上一节的部分分析,这里不再赘述。
3.4 使用 Hibernate 访问数据库本节会像之前的章节一样,我会先写代码进行演示,然后再对比 Hibernate 和 MyBatis 的区别。需要特别说明的是,我在工作中没有用过 Hibernate,对 Hibernate 也仅停留在了解的程度上。本节的测试代码都是现学现卖的,可能有些地方写的会有问题,或者不是最佳实践。所以关于测试代码,大家看看就好。若有不妥之处,也欢迎指出。
3.4.1 Hibernate 访问数据库的过程演示使用 Hibernate,需要先进行环境配置,主要是关于数据库方面的配置。这里为了演示,我们简单配置一下。如下:
<hibernate-configuration> <session-factory> <property>com.mysql.cj.jdbc.Driver</property> <property>jdbc:mysql://localhost:3306/myblog?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE</property> <property>root</property> <property>****</property> <property>org.hibernate.dialect.MySQL5Dialect</property> <property>true</property> <mapping resource="mapping/Article.hbm.xml" /> </session-factory> </hibernate-configuration>下面再配置一下实体类和表之间的映射关系,也就是上面配置中出现的Article.hbm.xml。不过这个配置不是必须的,可用注解进行替换。
<hibernate-mapping package="xyz.coolblog.model"> <class table="article"> <id column="id"> <generator /> </id> <property column="title" /> <property column="author" /> <property column="content" /> <property column="create_time" /> </class> </hibernate-mapping>测试代码如下:
public class HibernateTest { private SessionFactory buildSessionFactory; @Before public void init() { Configuration configuration = new Configuration(); configuration.configure("hibernate.cfg.xml"); buildSessionFactory = configuration.buildSessionFactory(); } @After public void destroy() { buildSessionFactory.close(); } @Test public void testORM() { System.out.println("-----------------------------✨ ORM Query ✨--------------------------"); Session session = null; try { session = buildSessionFactory.openSession(); int id = 6; Article article = session.get(Article.class, id); System.out.println("ORM Query Result: "); System.out.println(article); System.out.println(); } finally { if (Objects.nonNull(session)) { session.close(); } } } @Test public void testHQL() { System.out.println("-----------------------------✨ HQL Query ✨+--------------------------"); Session session = null; try { session = buildSessionFactory.openSession(); String hql = "from Article where author = :author and create_time > :createTime"; Query query = session.createQuery(hql); query.setParameter("author", "coolblog.xyz"); query.setParameter("createTime", "2018.06.10"); List<Article> articles = query.list(); System.out.println("HQL Query Result: "); articles.forEach(System.out::println); System.out.println(); } finally { if (Objects.nonNull(session)) { session.close(); } } } @Test public void testJpaCriteria() throws ParseException { System.out.println("---------------------------✨ JPA Criteria ✨------------------------"); Session session = null; try { session = buildSessionFactory.openSession(); CriteriaBuilder criteriaBuilder = session.getCriteriaBuilder(); CriteriaQuery<Article> criteriaQuery = criteriaBuilder.createQuery(Article.class); // 定义 FROM 子句 Root<Article> article = criteriaQuery.from(Article.class); // 构建查询条件 SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd"); Predicate greaterThan = criteriaBuilder.greaterThan(article.get("createTime"), sdf.parse("2018.06.10")); Predicate equal = criteriaBuilder.equal(article.get("author"), "coolblog.xyz"); // 通过具有语义化的方法构建 SQL,等价于 SELECT ... FROM article WHERE ... AND ... criteriaQuery.select(article).where(equal, greaterThan); Query<Article> query = session.createQuery(criteriaQuery); List<Article> articles = query.getResultList(); System.out.println("JPA Criteria Query Result: "); articles.forEach(System.out::println); } finally { if (Objects.nonNull(session)) { session.close(); } } } }