配置数据源和JDBC使用

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_22314145/article/details/81562244

配置数据源和JDBC使用

一. 配置数据源

无论选择Spring的哪种数据访问方式,你都需要配置一个数据源的引用。Spring提供了在Spring上下文中配置数据源bean的多种方式,包括:

  1. 通过JDBC驱动程序定义的数据源
  2. 通过JNDI查找的数据源
  3. 连接池的数据源

1.1 使用JNDI数据源

使用Java配置的话,我们可以借助JndiObjectFactoryBean中查找DataSource:

@Bean
public DataSource productionDataSource(){
    //使用JNDI数据源
    JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
    jndiObjectFactoryBean.setJndiName("org.h2.Driver");
    jndiObjectFactoryBean.setResourceRef(true);
    jndiObjectFactoryBean.setProxyInterface(DataSource.class);
    return (DataSource) jndiObjectFactoryBean.getObject();
}

1.2 使用数据源连接池

使用Java配置,借助BasicDataSource类的bean声明如下:

@Bean
public DataSource quDataSource(){
    //数据源连接池
    BasicDataSource basicDataSource = new BasicDataSource();
    basicDataSource.setDriverClassName("org.h2.Driver");
    basicDataSource.setUrl("jdbc:h2:tcp://localhost/~/spitter");
    basicDataSource.setUsername("sa");
    basicDataSource.setPassword("");
    return basicDataSource;
}

1.3 基于JDBC驱动的数据源

在Spring中,通过JDBC驱动定义数据源是最简单的配置方式。Spring提供了三个这样的数据源类供选择:

  • DriverManagerDataSource:在每个连接请求时都会返回一个新建的连接。与JDBC的BasicDataSource不同,由DriverManagerDataSource提供的连接并没有进行池化管理。
  • SimpleDriverDataSource:与DriverManagerDataSource工作方式类似,但是它直接使用JDBC驱动,来解决在特定环境下的类加载问题,这样的环境包括OSGi容器。
  • SingleConnectionDataSource:在每个连接请求时都会返回同一个的连接。尽管SingleConnectionDataSource不是严格意义上的连接池数据源,但是可以将其视为只有一个连接的池。

注意:SingleConnectionDataSource有且只有一个数据库连接,不适于多线程,DriverManagerDataSource和SimpleDriverDataSource尽管支持多线程,但是在每次请求的时候都会创建新连接,这是以性能为代价的。

使用Java配置,借助DriverManagerDataSource类的bean声明:

//基于JDBC驱动的数据源
@Bean
public DataSource jdbcDataSource(){
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.h2.Driver");
    dataSource.setUrl("jdbc:h2:tcp://localhost/~/spitter");
    dataSource.setUsername("sa");
    dataSource.setPassword("");
    return dataSource;
}

1.4 使用嵌入式的数据源

使用Java配置,借助EmbeddedDatabaseBuilder类的bean声明:

@Bean
public DataSource developmentDataSource(){
    //嵌入式数据原:每次重启应用或运行测试的时候,都能够重新填充测试数据
    return new EmbeddedDatabaseBuilder()
        .setType(EmbeddedDatabaseType.H2)
        .addScript("classpath:schema.sql")
        .addScript("classpath:test-data.sql")
        .build();
}

1.5 小结

生产开发环境建议在数据源连接池和JNDI数据源中做选择,测试环境选择JDBC数据源或者嵌入式数据库。

二. 在Spring中使用JDBC

使用JDBC能够更好地对数据访问的性能进行调优。JDBC允许你使用数据库的所有特性,而这是其它框架不支持甚至禁止的。再者,相对于持久层框架,JDBC能够让我们在更低的层次上处理数据,我们可以完全控制应用程序如何读取和管理数据,包括访问和管理数据库中单独的列。这种细粒度的数据访问方式在很多应用程序中是很方便的。

直接使用JDBC代码示例:

@Component
public class TestDaoImpl implements TestDao {
    @Autowired
    private DataSource dataSource;

    private static final String SQL_INSERT_TEST = "insert into test (user_name) values (?)";
    private static final String SQL_UPDATE_TEST = "update test set user_name = ? where id = ?";
    private static final String SQL_CHECK_TEST = "select id,user_name from test where id = ?";

    @Override
    public void addTest(Test test) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(SQL_INSERT_TEST);
            stmt.setString(1, test.getUserNme());
            stmt.execute();
        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            try{
                if(stmt != null){
                    stmt.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void updateTest(Test test) {
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(SQL_UPDATE_TEST);
            stmt.setString(1, test.getUserNme());
            stmt.setInt(2, test.getId());
            stmt.execute();
        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            try{
                if(stmt != null){
                    stmt.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public Test checkTest(int id) {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try{
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement(SQL_CHECK_TEST);
            stmt.setInt(1, id);

            rs = stmt.executeQuery();
            Test test = null;
            if(rs.next()){
                test = new Test();
                test.setId(rs.getInt("id"));
                test.setUserNme(rs.getString("user_name"));
            }
            return test;
        }catch(SQLException e){
            e.printStackTrace();
        }finally {
            try{
                if(stmt != null){
                    stmt.close();
                }
                if(conn != null){
                    conn.close();
                }
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        return null;
    }
}

使用JdbcTemplate来读取数据:

@Component
public class DbUserDaoImpl implements DbUserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    private static final String SQL_INSERT_DBUSER = "insert into user_list (username, mobile, cardnumber) values (?, ?, ?)";
    private static final String SQL_CHECK_DBUSER = "select id,username,mobile,cardnumber from user_list";
    private static final String SQL_FINDBYID_DBUSER = "select id,username,mobile,cardnumber from user_list where id = ?";
    private static final String SQL_UPDATE_DBUSER = "update user_list set username = ?,mobile = ?,cardnumber = ? where id = ?";

    @Override
    public void addDbUser(DbUser dbUser) {
        jdbcTemplate.update(SQL_INSERT_DBUSER, dbUser.getUsername(), dbUser.getMobile(), dbUser.getCardnumber());
    }

    @Override
    public List<DbUser> findAll() {
        return jdbcTemplate.query(SQL_CHECK_DBUSER, new DbUserRowMapper());
    }

    @Override
    public DbUser findById(int id) {
        return jdbcTemplate.queryForObject(SQL_FINDBYID_DBUSER, new DbUserRowMapper(), id);
    }

    public static final class DbUserRowMapper implements RowMapper<DbUser>{
        public DbUser mapRow(ResultSet rs, int rowNum) throws SQLException {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            String mobile = rs.getString("mobile");
            String cardnumber = rs.getString("cardnumber");

            DbUser dbUser = new DbUser();
            dbUser.setId(id);
            dbUser.setUsername(username);
            dbUser.setMobile(mobile);
            dbUser.setCardnumber(cardnumber);

            return dbUser;
        }
    }

    public DbUser save(DbUser dbUser){
        if(dbUser.getId() == null){
            int id = insertDbUserAndReturnId(dbUser);
            return jdbcTemplate.queryForObject(SQL_FINDBYID_DBUSER, new DbUserRowMapper(), id);
        }

        jdbcTemplate.update(SQL_UPDATE_DBUSER, dbUser.getUsername(), dbUser.getMobile(), dbUser.getCardnumber(), dbUser.getId());

        return dbUser;
    }

    public int insertDbUserAndReturnId(DbUser dbUser){
        SimpleJdbcInsert jdbcInsert = new SimpleJdbcInsert(jdbcTemplate).withTableName("user_list");
        jdbcInsert.setGeneratedKeyName("id");
        Map<String, Object> map = new HashMap<>();
        map.put("username", dbUser.getUsername());
        map.put("mobile", dbUser.getMobile());
        map.put("cardnumber", dbUser.getCardnumber());
        int id = jdbcInsert.executeAndReturnKey(map).intValue();
        return id;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_22314145/article/details/81562244