0%

spring整合orm之hibernate,jpa,mybatisplus

说明

  • 上篇文章主要介绍spring如何整合jdbc、mybatis,本文章继续整合orm中的常用框架

  • 环境:idea社区版本、jdk1.8,mysql8.0+,maven,win10

整合hibernate

  • 依赖文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.8</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>2.0.3</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<!-- 事务 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.0.7.Final</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.1</version>
</dependency>
</dependencies>
  • src-main-resources-db.properties
1
2
3
4
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/test?serverTimezone=Asia/Shanghai
user=root
password=123456
  • src-main-resources-applicationContext.xml 配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
">
<!-- 引入db.properties文件 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 创建druid 的数据源 -->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
<property name="url" value="${url}" />
<property name="driverClassName" value="${driver}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
</bean>
<!-- 配置Hibernate的SessionFactory对象 -->
<bean class="org.springframework.orm.hibernate5.LocalSessionFactoryBean" id="sessionFactory">
<!-- 关联数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 配置Hibernate的属性信息 -->
<property name="hibernateProperties">
<props>
<prop key="show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<!-- 扫描路径 -->
<property name="packagesToScan">
<list>
<value>xyz.shi.domain</value>
</list>
</property>
</bean>
<!-- 配置HibernateTemplate对象 -->
<bean class="org.springframework.orm.hibernate5.HibernateTemplate" id="hibernateTemplate">
<property name="sessionFactory" ref="sessionFactory"/>
</bean>
<!-- 配置事务管理-->
<bean class="org.springframework.orm.hibernate5.HibernateTransactionManager" id="transactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<!-- 配置开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 配置扫描路径 -->
<context:component-scan base-package="xyz.shi" />
</beans>
  • userdao
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.shi.dao;

import xyz.shi.domain.QueryResult;
import xyz.shi.domain.User;

public interface UserDao {
void save(User user);
void update(User user);
User findById(int id);
QueryResult findAll(int firstResult, int maxResults);
void delete(User user);
}

  • 实现userdao
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package xyz.shi.dao.Impl;

import org.hibernate.SessionFactory;
import xyz.shi.dao.UserDao;
import xyz.shi.domain.QueryResult;
import xyz.shi.domain.User;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private SessionFactory sessionFactory;
// private HibernateTemplate template;
@Override
public void save(User user) {
Session session = sessionFactory.getCurrentSession();
session.save(user);

}

@Override
public void update(User user) {
Session session = sessionFactory.getCurrentSession();
session.update(user);

}

@Override
public User findById(int id) {
Session session = sessionFactory.getCurrentSession();
User user = session.get(User.class, id);
return user;
}


/**
* 分页的查询数据列表
* @param firstResult 从结果列表中的哪个索引开始取数据
* @param maxResults 最多取多少条数据
* @return 一页的数据列表
*/
@Override
public QueryResult findAll(int firstResult, int maxResults) {
Session session = sessionFactory.getCurrentSession();

List<User> list = session.createQuery(
"FROM User")
.setFirstResult(firstResult)
.setMaxResults(maxResults)
.list();
Long count = (Long)session.createQuery(
"SELECT COUNT(*) FROM User")
.uniqueResult();
return new QueryResult(count.intValue(), list);
}

@Override
public void delete(User user) {
Session session = sessionFactory.getCurrentSession();
session.delete(user);

}
}

  • 分页实体类
1
2
3
4
5
public class QueryResult {

private int count; // 总记录数
private List list; // 一页的数据
...
  • user实体类 省略

  • 开始测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.transaction.annotation.Transactional;
import xyz.shi.dao.UserDao;
import xyz.shi.domain.QueryResult;
import xyz.shi.domain.User;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserTest {
@Autowired
private UserDao dao;

@Test
@Transactional
@Rollback(false) // 不需要回滚
public void save() {
User user = new User();
user.setUserName("test789");
user.setPassword("777777");
dao.save(user);
}
@Test
@Transactional
// 如果不加这个,以上就是回滚,这样的好处就是在单元测试中能测试通过,但是最终不修改数据库的值
@Rollback(false)
public void update() {
User user = new User();
user.setUserId(52);
user.setUserName("test8888");
user.setPassword("888888");
dao.update(user);
}
@Test
@Transactional
public void findId() {
User user = dao.findById(52);
System.out.println(user.getUserName());
}
@Test
@Transactional
public void findAll() {
QueryResult result = dao.findAll(0, 5);
System.out.println(result.getCount());
for (Object o : result.getList()) {
User user = (User)o;
System.out.println(user.getUserName());
}
}
@Test
@Transactional
public void delete() {
User user = new User();
user.setUserId(53);
dao.delete(user);
}
}

注意这里的标识

Transactional 开启事务

Rollback(false) 这样的好处就是在单元测试中能测试通过,但是最终不修改数据库的值,在发布到生产环境需要检查,切记需要去掉此标识,不然造成修改数据全部都回滚了,造成数据修改不成功

jpa

  • jpa是基于hibernate来实现的

  • 依赖文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
    <dependencies>
<!-- Spring框架核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.4</version>
</dependency>
<!-- Spring JPA依赖 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.5.4</version>
</dependency>
<!-- Hibernate JPA实现依赖 -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.27.Final</version>
</dependency>

<!-- MySQL连接驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
  • 实体类,映射数据库中表的关系
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
package xyz.shi.domain;

import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name="users")
public class User implements Serializable {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Integer userId;
@Column(name="name")
private String userName;
@Column(name="password")
private String password;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}

}
  • src-main-java-resources-applicationContext.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

<context:annotation-config />

<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="packagesToScan">
<list>
<value>xyz.shi.domain</value> <!-- 替换成你的实体类所在包名 -->
</list>
</property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />
</property>
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL8Dialect</prop> <!-- 替换成你所使用的MySQL版本对应的方言类 -->
<prop key="hibernate.hbm2ddl.auto">update</prop> <!-- 自动更新表结构 -->
</props>
</property>
</bean>

<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /> <!-- 替换成你所使用的MySQL版本对应的驱动类 -->
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai" /> <!-- 替换成你的数据库连接信息 -->
<property name="username" value="root" /> <!-- 替换成你的数据库用户名 -->
<property name="password" value="123456" /> <!-- 替换成你的数据库密码 -->
</bean>

<bean id="transactionManager"
class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
</bean>

<jpa:repositories base-package="xyz.shi.dao" /> <!-- 替换成你的Repository接口所在包名 -->

</beans>

  • dao层,几乎不用写任何逻辑,当然页支持自定义
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package xyz.shi.dao;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import xyz.shi.domain.User;



public interface UserDao extends JpaRepository<User, Integer>, JpaSpecificationExecutor<User> {
// 普通的查询方法
// 示例 getByName(String name):getBy固定用法
//1. Name是User成员变量的首字母大写
//2. name与User的成员变量name相同
// public User getByUserName(String name);
// @Query("SELECT u FROM User u WHERE u.name LIKE %:name%")
// List<User> findByNameContaining(@Param("name") String name);
}

  • 测试src-test-java-UserTest1.class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import xyz.shi.dao.UserDao;
import xyz.shi.domain.User;

import javax.annotation.Resource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")

public class UserTest1 {
@Resource
UserDao userDao;
@Test
public void testFindPage() {

PageRequest page = PageRequest.of(0, 5, Sort.by(Sort.Order.desc("userId")));
Page<User> all = userDao.findAll(page);
System.out.println("分页 + 根据id逆序 查询结果: " + all.getContent());
}
@Test
public void testFindBy() {
User user2 = userDao.findById(50).get();
System.out.println(user2.getUserName());
}
@Test
public void save() {
User user = new User();
user.setUserName("tttt");
user.setPassword("pppp");
User user11 = userDao.save(user);
System.out.println(user11.getUserId());
}
@Test
public void update() {
User user = new User();
user.setUserName("tttt60");
user.setPassword("pppp60");
user.setUserId(60);
userDao.save(user);
}
@Test
public void delete() {
User user = new User();
user.setUserId(59);
userDao.delete(user);
}
}

mybatisplus

  • 这篇文章练习了spring集成mybatis,本次用mybatisplus

  • java8,mysql8,idea社区版,win10

  • 依赖文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.4</version>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>3.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.16.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.13</version>
</dependency>
</dependencies>
  • 实体类,User
1
2
3
4
5
6
7
8
9
10
11
12
13
package xyz.shi.entity;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("users")

public class User {
@TableId
private int id;
private String name;
private String password;
}
  • UserMapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package xyz.shi.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import xyz.shi.entity.User;

@Mapper
// BaseMapper中包含了常用的增删改查的方法,也可以自定义方法
public interface UserMapper extends BaseMapper<User> {
// @Select("SELECT * FROM users WHERE id = #{id}")
// User getUserById(int id);
//
// @Insert("INSERT INTO users(name,) VALUES(#{name}})")
// int insertUser(User user);
//
//// @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}")
// @Update("UPDATE user SET name = #{name} WHERE id = #{id}")
// int updateUser(User user);
//
// @Select("SELECT * FROM users WHERE name = #{name}")
// List<User> getUsersByName(String name);
}
  • src-main-resources-appcationContext.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 加载数据库配置文件 -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf8&amp;serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="autoCommit" value="true"/>
<property name="connectionTimeout" value="5000" />
<property name="idleTimeout" value="60" />
</bean>
<!--jdbc的xml配置-->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource">
<constructor-arg name="configuration" ref="hikariConfig"/>
</bean>
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
<!-- 配置MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="xyz.shi.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
  • src-main-resources-mybatis-config.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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>
<!--settings:控制mybatis全局行为-->
<settings>
<!--设置mybatis输出日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<!--设置别名-->
<typeAliases>
<!--
package:把包下面的所有类名作为别名
name:实体类所在的包名-->
<package name="xyz.shi.entity"/>
</typeAliases>
</configuration>
  • 单元测试,src-test-java-UserMapper
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import xyz.shi.entity.User;
import xyz.shi.mapper.UserMapper;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {
@Autowired
UserMapper userDao;
@Test
public void selectById() {
User user = userDao.selectById(50);
System.out.println(user.getName());
}
@Test
public void findPage() {
Page<User> page = new Page<>(1, 10);
List<User> userList = userDao.selectPage(page, null).getRecords();
for(User user1: userList) {
System.out.println(user1.getName());
}
}
@Test
public void save() {
User user = new User();
user.setName("mybatisplus");
user.setPassword("11111");
userDao.insert(user);
}
@Test
public void update() {
User user = new User();
user.setId(61);
user.setName("tst60");
user.setPassword("2222");
userDao.updateById(user);
}
@Test
public void delete() {
userDao.deleteById(61);
}
}

  • 注意本次没有用mapper.xml文件,完全抛弃了
  • 源代码