Java 使用MySQL 總結
-
一、JDBC 連接 MySQL ,JDBC 是一種用於執行SQL語句的Java API,可以爲多種關係數據庫提供統一訪問
-
下載 jar 包: JDBC driver for MySQL in MySQL Connectors
-
加載JDBC驅動程序
// 在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機) // 成功加載後,會將Driver類的實例註冊到DriverManager類中。 try { Class.forName("com.mysql.jdbc.Driver") ; }catch(ClassNotFoundException e){ System.out.println("找不到驅動程序類 ,加載驅動失敗!"); e.printStackTrace() ; }
-
提供JDBC連接的URL , 創建數據庫的連接
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf-8"; String username = "root" ; String password = "root" ; try{ Connection con = DriverManager.getConnection(url , username , password ) ; }catch(SQLException se){ System.out.println("數據庫連接失敗!"); se.printStackTrace() ; }
-
創建一個Statement , 執行SQL語句
// 執行靜態SQL語句 Statement statement = con.createStatement(); // 執行動態SQL語句 PreparedStatement preparedStatement = con.prepareStatement(sql); // 執行數據庫存儲過程 CallableStatement callableStatement = con.prepareCall("{CALL demoSp(? , ?)}"); // 執行查詢數據庫的SQL語句 ResultSet resultSet = statement.executeQuery("SELECT * FROM ...") ; // 用於執行INSERT、UPDATE或 DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等 int rows = statement.executeUpdate("INSERT INTO ...") ; // 用於執行返回多個結果集、多個更新計數或二者組合的語句 boolean flag = statement.execute(String sql) ;
-
處理結果,關閉連接
int columnCount = resultSet.getMetaData().getColumnCount(); while(resultSet.next()){ String name = resultSet.getString("name") ; String pass = resultSet.getString(1) ; // 此方法比較高效 } try{ conn.close() ; }catch(SQLException e){ e.printStackTrace() ; }
-
-
二、 JdbcTemplate : 是Spring框架支持的ORM
-
JdbcTemplate 介紹
- Spring 對數據庫的操作在jdbc上面做了深層次的封裝,使用spring的注入功能,可以把DataSource註冊到 JdbcTemplate 之中
- 需要引用jar 包 : spring-jdbc 和 spring-tx
-
SpringBoot 與 JdbcTemplates 集成 , Spring 中使用 JdbcTemplates
-
在pom文件引入spring-boot-starter-jdbc的依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>1.0.29</version> </dependency>
-
在application.properties文件配置mysql的驅動類,數據庫地址,數據庫賬號、密碼信息
spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=123456
-
Entity 類
public class Account { private int id ; private String name ; private double money; // ....省略了getter. setter }
-
Dao 層
public interface IAccountDAO { int add(Account account); int update(Account account); int delete(int id); Account findAccountById(int id); List<Account> findAccountList(); } @Repository public class AccountDaoImpl implements IAccountDAO { @Autowired private JdbcTemplate jdbcTemplate; @Override public int add(Account account) { return jdbcTemplate.update("insert into account(name, money) values(?, ?)", account.getName(),account.getMoney()); } @Override public int update(Account account) { return jdbcTemplate.update("UPDATE account SET NAME=?, money=? WHERE id=?", account.getName(),account.getMoney(),account.getId()); } @Override public int delete(int id) { return jdbcTemplate.update("DELETE from TABLE account where id=?",id); } @Override public Account findAccountById(int id) { List<Account> list = jdbcTemplate.query("select * from account where id = ?", new Object[]{id}, new BeanPropertyRowMapper(Account.class)); if(list!=null && list.size()>0){ Account account = list.get(0); return account; }else{ return null; } } @Override public List<Account> findAccountList() { List<Account> list = jdbcTemplate.query("select * from account", new Object[]{}, new BeanPropertyRowMapper(Account.class)); if(list!=null && list.size()>0){ return list; }else{ return null; } } }
-
-
-
三 、 Hiberante : 全自動的ORM,請使用 JPA
-
Hiberante 介紹
- 兩個例子
- Spring 提供對 DAO 的支持 , DAO模式
- 所有的數據訪問都通過DAO組件完成,DAO組件封裝了數據庫的增、刪、改、查等原子操作。
- 業務邏輯組件依賴於DAO組件提供的數據庫原子操作,完成業務邏輯的實現
- Spring 爲實現DAO組件提供了許多工具類(就Hibernate而言,Spring提供了:HibernateTemplate , HibernateCallback 和 HibernateDaoSupport 3個類)
- 不適合Hiberante的場景
- 安全性要求,不讓開發人員看到表結構
- 開發規範要求,必須以存儲過程實現
- 性能要求,SQL語句需要經過高度優化
-
以聲明的方式管理SessionFactory 實例,直接在配置文件中配置
- 一旦配置了SessionFactory Bean,它會隨着應用的啓動而加載,並可以充分利用容器的功能,將sessionFactory 注入到DAO組件中,一旦DAO獲得了sessionFactory,就可以完成實際數據庫操作
<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:hibernate.cfg.xml" /> <!-- 加載實體類的映射文件位置及名稱 --> <property name="mappingLocations" value="classpath:mapping/*.hbm.xml" /> </bean>
<!-- Hibernate的配置文件:hibernate.cfg.xml --> <hibernate-configuration> <session-factory> <!-- 配置Hibernate的基本屬性 --> <!-- 1.數據源配置到IOC容器中 --> <!-- 2.關聯的.hbm.xml也在IOC容器配置SessionFactory實例 --> <!-- 3.配置Hibernate的基本屬性:方言,SQL顯示及格式化,生成數據表的策略以及二級緩存 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</property> <property name="hibernate.show_sql">true</property> <property name="hbm2ddl.auto">update</property> </session-factory> </hibernate-configuration>
-
使用 HibernateTemplate (模板)
- HibernateTemplate 將持久層訪問模板化,它只需要引用SessionFactory,就可以執行持久化操作
public class PersonDaoImp implements PersonDao { // HibernateTemplate 提供很多方法來完成基本的操作,如:增刪改查,分頁等 // HibernateTemplate 維護Hibernate相關的Session對象 private HibernateTemplate ht = null; private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory){ this.sessionFactory = sessionFactory; } public HibernateTemplate getHibernateTemplate() { if (ht == null){ ht = new HibernateTemplate(this.sessionFactory); } return ht; } public Person get(Integer id) { return getHibernateTemplate().get(Person.class, id); } }
-
使用 HibernateCallback
- 爲了解決 HibernateTemplate 靈活性不足的問題,HibernateTemplate 提供了一種更加靈活的方式來操作數據庫,可以直接使用 Hibernate 的Session直接進行操作
public List findByPage(String hql, int offset, int pageSize){ // 這個 execute 方法需要一個 HibernateCallback 實例,通過這個callback實例可以完全使用Hibernate的操作方式 List list = getHibernateTemplate().execute(new HibernateCallback<List>() { @Override public List doInHibernate(Session session) throws HibernateException { List result = session.createQuery(hql).setFirstResult(offset).setMaxResults(pageSize).list(); return result; } }); return list; }
-
使用 HibernateDaoSupport
-
Spring 提供了大量的 xxxDaoSupport 類, 這些DAO支持類對於實現DAO組件大有幫助,因爲它已經完成了大量的基礎性工作
-
Spring爲 Hibernate 提供了HibernateDaoSupport 支持類, 可以更方便的實現DAO組件
// HibernateDaoSupport類已經將 HibernateTemplate和 SessionFactory處理好了,子類可以直接使用 public class UserDaoImp extends HibernateDaoSupport implements UserDao { @Override public User get(Integer id) { return getHibernateTemplate().get(User.class, id); } }
-
-
-
四、JPA (Java Persistence API)
-
介紹 , 教程
- JPA 是一個ORM 規範,它本身不執行任何操作, 它需要一個實現。 像Hibernate,TopLink和iBatis這樣的ORM工具實現了JPA 規範,可以從中任選一個
- Spring Data JPA 是Spring Data的子模塊。使用Spring Data,使得基於“repositories”概念的JPA實現更簡單和容易
- 如果應用程序面向 JPA編程,那麼ORM框架就可以隨意切換,因此具有更好的擴展性
- JPA @Id 和 @GeneratedValue 註解詳解
- JPA與Hibernate的關係 , JPA 和 Mybatis 對比
-
Spring Boot 與 JPA 集成
-
添加依賴
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>
-
配置數據源和JPA
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC spring.datasource.username = root spring.datasource.password = root spring.datasource.tomcat.max-active=20 #連接哪種數據庫 spring.jpa.database=mysql #查詢過程中日誌裏是否顯示查詢語句 spring.jpa.show-sql=true #自動根據實體創建表 spring.jpa.hibernate.ddl-auto=update spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.jpa.hibernate.naming.physical-strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
-
創建實體類
@Entity @Table(name="person") @GenericGenerator(name="jpa-uuid",strategy="uuid") public class Person { @Id //@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(generator="jpa-uuid") @Column(length=32) private String id; @Column(name="name",nullable=true,length=20) private String name; @Column(name="age",nullable=true,length=4) private int age; // 省略 getter setter }
-
Dao 層
- 方法一:繼承 JpaRepository , 可以極大的減少了JPA作爲數據訪問方案的代碼量
public interface PersonRepository extends JpaRepository<Person, String>{ // JpaRepository 已經默認實現了一些基本的方法,如:findAll, findOne, save,delete 等 // 自定義 SQL 語句 @Query(value = "SELECT * FROM person WHERE name = ?1", nativeQuery = true) List<Person> findByPersonName(String person_name); }
- 方法二:使用JPA的EntityManager實現DAO
// 爲所有DAO實現的基礎層, 一個使用泛型的抽象類 public class BaseDao<T extends Serializable> { // 實體Class在子類的構造函數中賦值 private Class<T> clazz; // 使用 @PersistenceContext註解,可以獲得 EntityManager實例,由PersistenceAnnotationBeanPostProcessor後處理器處理,從包中檢索JPA實體管理器並注入它 @PersistenceContext EntityManager entityManager; public final void setClazz( Class< T > clazzToSet ){ this.clazz = clazzToSet; } public T findOne( long id ){ return entityManager.find( clazz, id ); } }
// 繼承自 BaseDao,BaseDao爲子類實現了大部分功能 @Repository public class FooDao extends BaseDao<Foo> implements IFooDao{ // 實體Class在構造函數中傳遞 public FooDao(){ setClazz(Foo.class ); } }
- 注意: 在 Spring 4.x 以前,可以使用 JpaTemplate ,這與Hibernate非常相似
-
Service 層,調用 Dao
@RestController @RequestMapping("/person") public class JPAController { @Autowired PersonRepository personRepository; @RequestMapping("/add") public String addPerson(Person person) { personRepository.save(person); return "success"; } @RequestMapping("/update") public String updatePerson(Person person) { personRepository.save(person); return "success"; } @RequestMapping("/del") public String delPerson(String id) { personRepository.deleteById(id); return "success"; } @RequestMapping("/findAll") public List<Person> findPerson() { return personRepository.findAll(); } }
-
-
-
五、MyBatis : 半自動的ORM,能夠手寫SQL,更加靈活
-
Spring Boot 集成 MyBatis(註解方式)
-
添加pom依賴
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency>
-
添加配置
spring.datasource.url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8 spring.datasource.username: root spring.datasource.password: 123456 spring.datasource.driver-class-name: com.mysql.jdbc.Driver
-
創建實體類
public class Person { private Integer id; private String name; private Integer age; // 忽略 getter setter }
-
創建 mapper
@Repository public interface UserMapper { @Select("SELECT * FROM Person WHERE id = #{id}") Person selectUser(int id); }
-
配置Mapper掃描,在啓動類中添加MapperScan("")
@MapperScan("com.example.springmybatisdemo.mapper") //掃描的mapper @SpringBootApplication public class SpringmybatisdemoApplication { public static void main(String[] args) { SpringApplication.run(SpringmybatisdemoApplication.class, args); } }
-
創建服務
@Service public class UserService { @Autowired UserMapper userMapper; public Person selectUser(int id) { return userMapper.selectUser(id); } }
-
-
Spring Boot 與 mybatis 整合 非註解方式,用 mybatis-generator-gui 工具自動生成代碼, github
-
除了mapper 不一樣外,其他都一樣
public interface UserMapper { void insertUser(User user); List<User> getUsers(); }
<!-- Mapper 配置文件, 可以使用 mybatis-generator-gui 自動生成--> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.sanfeng.springbootmybatisjpa.mapper.UserMapper"> <insert id="insertUser" parameterType="com.sanfeng.springbootmybatisjpa.beans.User"> insert into user values(#{id}, #{name}, #{score}) </insert> <select id="getUsers" resultType="com.sanfeng.springbootmybatisjpa.beans.User"> select * from user </select> </mapper>
-
-