Java 使用MySQL 总结

这篇博客总结了Java连接MySQL的各种方式,包括使用JDBC的基本步骤,Spring框架中的JdbcTemplate,全自动ORM Hibernate,以及半自动ORM MyBatis的集成和使用。同时,提到了JPA规范以及Spring Boot下与Hibernate和JPA的集成,讨论了不同ORM工具的适用场景和优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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>
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值