D20-JDBCTemplate&三层架构

一、JDBCTemplate(重点)

1.1 概述

使用JDBCTemplate可以将JDBC操作数据库的代码简化到2–3步,它是spring家族对JDBC的一套工具包。

API:

  1. 创建JDBCTemplate对象
    new JDBCTemplate(DtaSource 连接池);
  2. 编写sql(问号占位符)
  3. 执行所有sql
    public viod execute(…);
    3.1 执行dml
    public int update(…);
    3.2 执行dql
    public T queryXXX(…);

1.2 初体验

需求: 使用JDBCTemplate创建一张商品表
步骤分析:

  • 创建java工程
  • 导入jar包(MySQL驱动,druid连接池,JDBCTemplate工具包)
  • 定义druid配置文件
  • 编写代码
//创建一张商品表
@Test
public void test01() throws Exception {
    // 1.创建JDBCTemplate对象
    JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
    // 2.编写sql
    String sql = "create table product(" +
        "id int primary key auto_increment," +
        "name varchar(32)," +
        "price double" +
        ");";
    // 3.执行sql
    jdbcTemplate.execute(sql);
}

1.3 实现增删改

新增:

@Test
public void test01() throws Exception {
    // 1.创建JDBCTemplate对象
    JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
    // 2.编写sql
    String sql = "insert into product values(null,?,?);";
    // 3.执行sql
    int i = jdbcTemplate.update(sql, "小米8", 2699);
    System.out.println(i);
    jdbcTemplate.update(sql, "魅族16", 2698);
    jdbcTemplate.update(sql, "华为mate20", 3999);
    Object[] args = {"iphoneXSMax", 12999};
    jdbcTemplate.update(sql, args);
}

修改:

    //修改
    @Test
    public void test03() throws Exception{
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        String sql = "UPDATE product set price=? where id=? ";
        int i = jdbcTemplate.update(sql, 2499, 1);
        if (i>0){
            System.out.println("小米8降价!");
        }
    }
    ```
    **删除**
    ```java
    //删除
    @Test
    public void test02() throws Exception{
        //创建jdbcTemplate对象
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        //编写sql语句
        String sql = "delete from product where id=?";
        //执行sql语句
        int i = jdbcTemplate.update(sql, 4);
        if (i>0){
            System.out.println("苹果下架!");
        }
    }

1.4 实现查询

查询结果为单值(指定类型)

  • 例 :统计价格低于3000的商品
    格式:

public T queryForObject(String sql,Class 指定类型,Object… 参数列表);

代码:

 @Test
    public void test01() throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());

        String sql = "select count(*) from product where price < ?;";
        // int.class
        Integer integer = jdbcTemplate.queryForObject(sql, int.class, 3000);
        System.out.println(integer);
    }

查询结果为一条记录(map)

格式:

public Map<String ,Object> queryForMap(String sql,Object…参数列表);

代码:

 public void test02() throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        String sql = "select * from product where id=?";
        Map<String, Object> map = jdbcTemplate.queryForMap(sql, 1);
        System.out.println(map);

    }

查询结果为多条记录(list)

  • 例:查询价格低于3000的商品信息
    格式:

public List<Map<String,Object>> queryForList(String sql,Object …参数列表);

public void test03() throws Exception {
        JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());
        String sql = "select * from product where price<?";
        List<Map<String, Object>> lis = jdbcTemplate.queryForList(sql, 3000);
        System.out.println(lis);

    }

查询结果自动封装到对象(掌握!)

格式:

public List query(String sql,new BeanPropertyRowMapper(Class),Object…参数列表);

@Test
public void test05() throws Exception {
    // 2.例如:查询价格低于3000的商品信息
    String sql = "select * from product where price < ?;";

    // 3.执行sql 返回自动封装Product
    List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Product>(Product.class), 3000);

    // 4.输出结果
    for (Product product : list) {
        System.out.println(product);
    }
}
// 查询结果为一条记录直接封装到对象
@Test
public void test06() throws Exception {
    // 2.例如:查询小米8的商品信息
    String sql = "select * from product where id = ?;";

    // 3执行sql 如果使用list
    //List<Product> list = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Product>(Product.class), 1);
    //System.out.println(list.get(0));
    //
    Product product = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Product>(Product.class), 1);
    System.out.println(product);
}

二、 数据库元数据

2.1 概述

元数据:定义数据的数据, 数据库,表,列的定义信息。

2.2 ParameterMaterData

通过PrelparedStatement获取请求参数的元数据,为了拿到问号的个数和类型

// ParameterMateData
@Test
public void test01() throws Exception {
    // 1.获取连接
    Connection connection = DataSourceUtils.getConnection();
    // 2.编写sql
    String sql = "insert into product(name,price) values(?,?);";
    // 3.创建预编译语句执行者
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    // 4.获取请求参数的元数据
    ParameterMetaData metaData = preparedStatement.getParameterMetaData();
    // 5.获取问号的个数
    int count = metaData.getParameterCount();
    System.out.println("问号个数:" + count);
    // 6.问号的类型
    // 注意如果执行此方法 mysql会报错
    // Parameter metadata not available for the given statement
    // 解释下 mysql团队没有实现此功能 :preparedStatement.setObject(....);
    String className = metaData.getParameterClassName(1);
}

2.3 ResultSetMetaData

通过ResultSet获取查询结果的元数据,为了拿到列的信息(个数,名称,类型)

// ResultSetMetaData
@Test
public void test02() throws Exception {
    // 1.获取连接
    DataSource dataSource = DataSourceUtils.getDataSource();
    Connection connection = dataSource.getConnection();
    // 2.编写sql
    String sql = "select * from product where id = ?;";
    // 3.创建预编译语句执行者
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    // 4.设置实际参数
    preparedStatement.setObject(1, 1);
    // 5.执行sql并返回结果 ResultSet
    ResultSet resultSet = preparedStatement.executeQuery();
    // 6.获取查询结果的元数据
    ResultSetMetaData metaData = resultSet.getMetaData();
    // 7.获取列的信息
    // 7.1 列个数
    int count = metaData.getColumnCount();
    System.out.println("列个数为:" + count);
    for (int i = 0; i < count; i++) {
        // 获取列名
        // 注意:索引是从0开始,列是从1开始
        System.out.println(metaData.getColumnName(i + 1));
        // 列类型 数据库类型  varchar
        System.out.println(metaData.getColumnTypeName(i + 1));
        // 列类型  java类型 string
        System.out.println(metaData.getColumnClassName(i + 1));
        // resultSet.next();
        // System.out.println(resultSet.getObject(metaData.getColumnName(i + 1)));

        System.out.println("-------------------------");

    }
}

三、三层架构(1)

3.1 概述

在java分层(方法)思想: 在软件领域中,我们一般按照不同的功能进行分层:表示层,业务层,数据访问层(持久层)

分层优点

  1. 解耦,降低层与层之间的耦合性
  2. 提高软件的维护性,对原有的功能修改和更新时不会影响到现有的功能
  3. 提高软件的拓展性,添加新功能的时候不会影响到原有的功能
  4. 提高软件的复用性,不同层之间进行功能调用,相同的功能可以重复使用

包目录结构
com.itheima.dao---->数据访问层
com.itheima.serivce---->业务层
com.itheima.action---->表示层
com.itheima.domain---->java普通实体
com.itheima.utils---->工具类

3.2 案例:用户注册

需求: 模拟百度
需求分析:

  1. 判断用户是否存在
  2. 保存用户信息到数据库

步骤分析:

  1. 创建java工程
  2. 导入jar包(MySQL驱动、druid连接池、JDBCTemplate工具包)
  3. 定义druid配置文件
  4. 搭建包目录结构

com.itheima.dao(持久层代码)

UserDao

com.itheima.service(业务层代码)

UserSerivce

com.itheima.action(表现层代码)

UserAction

com.itheima.domain(java实体)

User

com.itheima.utils(工具类)

DataSourceUtils

com.itheima.test(测试的代码)

UserHtml

代码:
模拟用户注册页面–UserHtml

package com.itheima.test;

import com.itheima.action.UserAction;

import java.util.Scanner;

public class UserHtml {

    // 模拟用户注册页面
    public static void main(String[] args) {
        System.out.println("百度注册页面");
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名");
        String username = scanner.nextLine();
        // 1.判断用户名是否存在 UserAction
        UserAction userAction = new UserAction();
        boolean flag = userAction.findUser(username);
        if (flag) {
            // 输出红色字体 error
            System.err.println("此用户太受欢迎,请更换一个");
            return;
        }
        System.out.println("请输入密码");
        String password = scanner.nextLine();
        // 2.保存用户信息到数据库
        boolean result = userAction.saveUser(username, password);

        if (result) {
            System.out.println("恭喜您注册成功,您有5分钟试看时间");
        } else {
            System.out.println("注册失败,请稍后重试");
        }

    }
}

表现层:

package com.itheima.action;

import com.itheima.domain.User;
import com.itheima.service.UserSerivce;

public class UserAction {
    // 获取userservice对象
    UserSerivce userSerivce = new UserSerivce();

    //1.1接收用户名
    public boolean findUser(String username) {
        //1.4 返回判断结果
        return userSerivce.findUser(username);
    }

    //2.1接收用户名和密码+手机号和验证码
    public boolean saveUser(String username, String password) {
        // 封装参数
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);
        // 2.4 返回注册结果
        return userSerivce.saveUser(user);
    }
}

业务层

package com.itheima.service;

import com.itheima.dao.UserDao;
import com.itheima.domain.User;

public class UserSerivce {

    // 获取userdao对象
    UserDao userDao = new UserDao();

    //1.2判断用户是否存在
    public boolean findUser(String username) {
        // 查询数据库
        User user = userDao.findUser(username);
        // 进行判断
        return user != null ? true : false;
    }

    //2.2检查用户名是否合法
    public boolean saveUser(User user) {
        // 保存到数据库并返回结果
        int i = userDao.saveUser(user);

        // 返回注册结果
        return i > 0 ? true : false;

    }
}

持久层

package com.itheima.dao;

import com.itheima.domain.User;
import com.itheima.utils.DataSourceUtils;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

public class UserDao {
    // 1. 创建JDBCTemplate对象
    JdbcTemplate jdbcTemplate = new JdbcTemplate(DataSourceUtils.getDataSource());

    //1.3根据用户名查询数据库
    public User findUser(String username) {
        User result = null;
        // 2.编写sql
        String sql = "select * from user where username = ?;";
        try {
            // 3.执行sql 返回User对象
            // 注意:此方法执行时如果没有数据那么会抛异常
            result = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<User>(User.class), username);
        } catch (DataAccessException e) {
            // e.printStackTrace();
        }
        return result;
    }

    //2.3添加到数据库 insert
    public int saveUser(User user) {
        int result = 0;
        // 2.编写sql
        String sql = "insert into user values(null,?,?);";
        try {
            // 3.执行sql  返回结果 影响行数
            result = jdbcTemplate.update(sql, user.getUsername(),user.getPassword());
        } catch (DataAccessException e) {
            e.printStackTrace();
        }
        return result;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值