1.概述
我们可以通过多种方式从Java连接到MySQL数据库,在本文中,我们将探索几种方法来实现这一目标。
首先,我们将探讨使用JDBC和Hibernate的最受欢迎的选项。
然后,我还将研究一些外部库,包括MyBatis,Apache Cayenne和Spring Data。在此过程中,我将提供许多实际示例。
2.前提条件
假设我们已经安装了一个MySQL服务器并在localhost(默认端口3306)上运行,并且我们已经有了一个包含以下人员表的测试架构:
CREATE TABLE person
(
ID INT,
FIRST_NAME VARCHAR(100),
LAST_NAME VARCHAR(100)
);
我们还将需要mysql-connector-java构件,该构件可以从Maven Central中获得:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
3. 使用JDBC连接
JDBC(Java数据库连接性)是用于连接和执行数据库查询的API。
3.1 共同属性
在本文的过程中,我们通常将使用几个常见的JDBC属性:
-
连接URL – JDBC驱动程序用于连接数据库的字符串。它可以包含诸如在哪里搜索数据库,要连接到的数据库的名称以及其他配置属性之类的信息:
jdbc:mysql:// [主机] [,failoverhost ...]
[:端口] / [数据库]
[?propertyName1] [= propertyValue1]
[&propertyName2] [= propertyValue2] ... -
我们将这样设置该属性:jdbc:mysql:// localhost:3306 / test?serverTimezone = UTC
-
驱动程序类– 要使用的驱动程序的全限定类名。在本文中,我们将使用MySQL驱动程序:com.mysql.cj.jdbc.Driver
-
用户名和密码– MySQL帐户的凭据
3.2 JDBC连接示例
让我们看看如何连接到数据库并通过try-with-multiple-resources执行简单的全选:
String sqlSelectAllPersons = "SELECT * FROM person";
String connectionUrl ="jdbc:[mysql://localhost:3306/test?serverTimezone=UTC](mysql://localhost:3306/test?serverTimezone=UTC)";
try (Connection conn = DriverManager.getConnection(connectionUrl, "username", "password");
PreparedStatement ps = conn.prepareStatement(sqlSelectAllPersons);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
long id = rs.getLong("ID");
String name = rs.getString("FIRST_NAME");
String lastName = rs.getString("LAST_NAME");
// do something with the extracted data...
}
} catch (SQLException e) {
// handle the exception
}
如我们所见,在try主体内部,我们遍历结果集并从人员表中提取值。
4.使用ORM连接
更典型地,我们将使用对象关系映射(ORM)框架连接到我们的MySQL数据库。因此,让我们来看一些使用这些框架中比较流行的连接示例。
4.1 本机Hibernate AP
在本文中,我们将看到如何使用Hibernate来管理与数据库的JDBC连接。
首先,我们需要添加休眠核心Maven依赖项:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.4.10.Final</version>
</dependency>
Hibernate要求必须为每个表创建一个实体类。让我们继续来定义Person类:
@Entity
@Table(name = "Person")
public class Person {
@Id
Long id;
@Column(name = "FIRST_NAME")
String firstName;
@Column(name = "LAST_NAME")
String lastName;
// getters & setters
}
另一个重要方面是创建通常名为*hibernate.cfg.xml的Hibernate资源文件,我们将在其中定义配置信息:
<?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](http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd)">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
<property name="connection.url">jdbc:[mysql://localhost:3306/test?serverTimezone=UTC](mysql://localhost:3306/test?serverTimezone=UTC)</property>
<property name="connection.username">username</property>
<property name="connection.password">password</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- Validate the database schema on startup -->
<property name="hbm2ddl.auto">validate</property>
<!-- Names the annotated entity class -->
<mapping class="Person"/>
</session-factory>
</hibernate-configuration>
Hibernate具有许多配置属性,除了标准的连接属性外,值得一提的是方言属性,该属性使我们可以为数据库指定SQL方言的名称。
框架使用此属性将(HQL)语句正确转换为适合给定数据库的SQL;Hibernate附带了40多种(SQL方言)在本文重点介绍MySQL时,我们将坚持使用MySQL5Dialect方言。
最后,Hibernate还需要通过映射标签知道实体类的全名。一旦完成配置,我们将使用SessionFactory类,该类负责创建和池化JDBC连接。
通常,只需为应用程序设置一次即可:
SessionFactory sessionFactory;
// configures settings from hibernate.cfg.xml
StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();
try {
sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
} catch (Exception e) {
// handle the exception
}
现在我们已经建立了连接,我们可以运行查询以从人员表中选择所有人员:
Session session = sessionFactory.openSession();
session.beginTransaction();
List<Person> result = session.createQuery("from Person", Person.class).list();
result.forEach(person -> {
//do something with Person instance...
});
session.getTransaction().commit();
session.close();
4.2 MyBatis
MyBatis于2010年推出,是一个以简单性为优势的SQL映射器框架。在这里,我们将重点介绍如何直接配置MyBatis。
要使用它,我们需要添加mybatis依赖项:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency>
假设我们在没有注释的情况下重用了上面的Person类,我们可以继续创建PersonMapper接口:
public interface PersonMapper {
String selectAll = "SELECT * FROM Person";
@Select(selectAll)
@Results(value = {
@Result(property = "id", column = "ID"),
@Result(property = "firstName", column = "FIRST_NAME"),
@Result(property = "lastName", column = "LAST_NAME")
})
List<Person> selectAll();
}
下一步就是MyBatis配置:
Configuration initMybatis() throws SQLException {
DataSource dataSource = getDataSource();
TransactionFactory trxFactory = new JdbcTransactionFactory();
Environment env = new Environment("dev", trxFactory, dataSource);
Configuration config = new Configuration(env);
TypeAliasRegistry aliases = config.getTypeAliasRegistry();
aliases.registerAlias("person", Person.class);
config.addMapper(PersonMapper.class);
return config;
}
DataSource getDataSource() throws SQLException {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setDatabaseName("test");
dataSource.setServerName("localhost");
dataSource.setPort(3306);
dataSource.setUser("username");
dataSource.setPassword("password");
dataSource.setServerTimezone("UTC");
return dataSource;
}
该配置包括创建一个Configuration对象,该对象是诸如Environment之类的设置的容器。它还包含数据源设置。
然后,我们可以使用Configuration对象,该对象通常为应用程序创建一次SqlSessionFactory设置一次:
Configuration configuration = initMybatis();
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
try (SqlSession session = sqlSessionFactory.openSession()) {
PersonMapper mapper = session.getMapper(PersonMapper.class);
List<Person> persons = mapper.selectAll();
// do something with persons list ...
}
4.3 阿帕奇卡宴
Apache Cayenne是一个持久性框架,其第一版可追溯到2002年。要了解有关它的更多信息,建议阅读Apache Cayenne的介绍。
和往常一样,让我们添加cayenne-server Maven依赖项:
我们将特别关注MySQL连接设置。在这种情况下,我们将配置cayenne-project.xml:
<?xml version="1.0" encoding="utf-8"?>
<domain project-version="9">
<map name="datamap"/>
<node name="datanode"
factory="org.apache.cayenne.configuration.server.XMLPoolingDataSourceFactory"
schema-update-strategy="org.apache.cayenne.access.dbsync.CreateIfNoSchemaStrategy">
<map-ref name="datamap"/>
<data-source>
<driver value="com.mysql.cj.jdbc.Driver"/>
<url value="jdbc:[mysql://localhost:3306/test?serverTimezone=UTC](mysql://localhost:3306/test?serverTimezone=UTC/">
<connectionPool min="1" max="1"/>
<login userName="username" password="password"/>
</data-source>
</node>
</domain>
在以cayenneDataObject的形式自动生成datamap.map.xml和Person类*之后,我们可以执行一些查询。
例如,我们将像以前一样继续全选:
ServerRuntime cayenneRuntime = ServerRuntime.builder()
.addConfig("cayenne-project.xml")
.build();
ObjectContext context = cayenneRuntime.newContext();
List<Person> persons = ObjectSelect.query(Person.class).select(context);
// do something with persons list...
5. 使用Spring数据进行连接
Spring Data是用于数据访问的基于Spring的编程模型。从技术上讲,Spring Data是一个伞形项目,其中包含许多特定于给定数据库的子项目。
让我们看看如何使用其中两个项目连接到MySQL数据库。
5.1 春季数据/ JPA
Spring Data JPA是一个强大的框架,可帮助减少样板代码,并提供了一种通过多个预定义存储库接口之一来实现基本CRUD操作的机制。除此之外,它还有许多其他有用的功能。
请务必查看我们对Spring Data JPA的介绍以了解更多信息。
该弹簧数据的JPA神器上可以找到Maven的中央:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
我们将继续使用Person类。下一步是使用注释配置JPA:
@Configuration
@EnableJpaRepositories("packages.to.scan")
public class JpaConfiguration {
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:[mysql://localhost:3306/test?serverTimezone=UTC](mysql://localhost:3306/test?serverTimezone=UTC)");
dataSource.setUsername( "username" );
dataSource.setPassword( "password" );
return dataSource;
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
return new JpaTransactionManager(emf);
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
jpaVendorAdapter.setDatabase(Database.MYSQL);
jpaVendorAdapter.setGenerateDdl(true);
return jpaVendorAdapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lemfb = new LocalContainerEntityManagerFactoryBean();
lemfb.setDataSource(dataSource());
lemfb.setJpaVendorAdapter(jpaVendorAdapter());
lemfb.setPackagesToScan("packages.containing.entity.classes");
return lemfb;
}
}
为了允许Spring Data实现CRUD操作,我们必须创建一个扩展CrudRepository接口的接口:
@Repository
public interface PersonRepository extends CrudRepository<Person, Long> {
}
最后,让我们来看一个使用Spring Data的全选示例:
personRepository.findAll().forEach(person -> {
// do something with the extracted person
});
5.2 Spring数据/ JDBC
Spring Data JDBC是Spring Data系列的有限实现,其主要目标是允许简单地访问关系数据库。
因此,它不提供诸如缓存,脏跟踪,延迟加载和许多其他JPA功能的功能。
这次我们需要的Maven依赖是spring-data-jdbc:
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jdbc</artifactId>
<version>1.1.4.RELEASE</version>
</dependency>
与上一节中用于Spring Data JPA的配置相比,该配置更轻便:
@Configuration
@EnableJdbcRepositories("packages.to.scan")
public class JdbcConfiguration extends AbstractJdbcConfiguration {
// NamedParameterJdbcOperations is used internally to submit SQL statements to the database
@Bean
NamedParameterJdbcOperations operations() {
return new NamedParameterJdbcTemplate(dataSource());
}
@Bean
PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:[mysql://localhost:3306/test?serverTimezone=UTC](mysql://localhost:3306/test?serverTimezone=UTC)");
dataSource.setUsername("username");
dataSource.setPassword("password");
return dataSource;
}
}
对于Spring Data JDBC,我们必须定义一个新的Person类或修改现有的Person类以添加一些特定于Spring的注释。
这是因为Spring Data JDBC将直接处理实体映射而不是Hibernate:
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Column;
import org.springframework.data.relational.core.mapping.Table;
@Table(value = "Person")
public class Person {
@Id
Long id;
@Column(value = "FIRST_NAME")
String firstName;
@Column(value = "LAST_NAME")
String lastName;
// getters and setters
}
使用Spring Data JDBC,我们还可以使用CrudRepository接口。因此,该声明将与我们在Spring Data JPA示例中上面编写的声明相同。同样,全选示例也是如此。
六.结论
在本文中,我们已经看到了几种从Java连接到MySQL数据库的不同方法。我们从基本的JDBC连接开始。然后,我们研究了常用的ORM,例如Hibernate,Mybatis和Apache Cayenne。最后,我们看了一下Spring Data JPA和Spring Data JDBC。
使用JDBC或Hibernate API意味着更多的样板代码,使用样板框架,例如Spring Data或Mybatis,需要更多的配置,但是却具有明显的优势,因为它们提供了默认的实现和功能,例如缓存和延迟加载。
七.最后
欢迎大家讨论交流,如果喜欢可以关注转发,感谢支持,以后会有更多优质干货内容,敬请期待!
网友评论