Java 使用MySQL 總結

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 介紹

      • 兩個例子
        • Hibernate 沒有和 Spring整合的 例子
        • Hibernate 和 Spring整合的 例子
      • 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);
        }
        
          // 爲所有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>
        
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章