使用JDBCTemplate可以将JDBC操作数据库的代码简化到2–3步,它是spring家族对JDBC的一套工具包。
API:
- 创建JDBCTemplate对象
new JDBCTemplate(DtaSource 连接池);- 编写sql(问号占位符)
- 执行所有sql
public viod execute(…);
3.1 执行dml
public int update(…);
3.2 执行dql
public T queryXXX(…);
需求: 使用JDBCTemplate创建一张商品表
步骤分析:
//创建一张商品表
@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);
}
新增:
@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("苹果下架!");
}
}
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);
}
格式:
public Map
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);
}
public List
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 list = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Product.class), 1);
//System.out.println(list.get(0));
//
Product product = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<Product>(Product.class), 1);
System.out.println(product);
}
元数据:定义数据的数据, 数据库,表,列的定义信息。
通过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);
}
通过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("-------------------------");
}
}
在java分层(方法)思想: 在软件领域中,我们一般按照不同的功能进行分层:表示层,业务层,数据访问层(持久层)
分层优点
包目录结构
com.itheima.dao---->数据访问层
com.itheima.serivce---->业务层
com.itheima.action---->表示层
com.itheima.domain---->java普通实体
com.itheima.utils---->工具类
需求: 模拟百度
需求分析:
步骤分析:
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;
}
}