1.jdbc
1)概念:
JDBC:Java连接数据库 ,使用Java语言规范 操作数据库.
2)jdbc的入门七大步骤_设计的API解释说明:
1)导入数据库包 mysql-connector-java-8.0.23.jar mysql8的jar包
有了包了,里面的核心类就加载进来了
2)注册驱动
本身注册驱动:DriverManger里面
public static void registerDriver(Driver driver) 注册驱动的方法
推荐:
加载类--->执行原码的静态代码块注册驱动
Class.forName("com.mysql.cj.jdbc.Driver") ;---->获取com.mysql.cj.jdbc.Driver的类字节码文件对象
向下兼容性
原码的内容
class com.mysql.cj.jdbc.Driver implements java.sql.Drvier{
//静态代码块---本身就使用了DriverManger里面的注册驱动方法
static {
try {
java.sql.DriverManager.registerDriver(new Driver()); //本身就在注册驱动,不需要在单独写了
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
}
3)获取连接对象
驱动管理程序的类DriverManager:
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/javaee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", /
//当前支持的字符集格式 服务器时区 开启公钥
"root",
"123456");)
java.sql.DriverManager:用于管理一组JDBC驱动程序的基本服务
获取数据库的连接对象
public static Connection getConnection(String url, String user, String password)
参数1:统一资源定位符号
url组成
协议 :jdbc的协议 格式 ---> jdbc: (java连接数据库)
数据库: mysql /oracle /指定的数据库 (安装特定数据库的服务器软件)
域名:端口号
本地 localhost:本机/或者直接写127.0.0.1:本地回环地址
远程连接
远程服务器的ip地址或者域名
mysql端口号:3306
资源地址(数据库地址): 数据库名称
参数2:本地mysql的用户名 root
参数3:用户密码
返回值类型:java.sql.Connection接口:与特定数据库的连接会话
4)准备sql
String sql = "insert into student values(9,'德邦',18,'男','艾欧尼亚',60,70)"; 静态sql (硬编码)
5)通过连接对象创建执行对象
java.sql.Connection:与特定数据库的连接会话
Statement createStatement():创建执行对象,它可以将静态sql语句发送到数据库中
6)执行sql语句
java.sql.Statement接口
通用的方法
int executeUpdate(String sql):将sql语句发送的数据库中执行 (更新操作)
针对DDL:表的修改、创建、删除、查询。。。
针对DML语句:insert into,update ,delete,
ResultSet executeQuery(String sql):将select语句发送到到数据中进行执行(通用查询操作)
java.sql.ResultSet接口:
数据库结果集的数据表,通常通过执行查询数据库的语句生成。
3)案例:
实现步骤
* 1)导包--->jar包 mysql驱动jar包
* 2)注册驱动
* 3)获取数据库的连接对象
* 4)准备好sql语句
* 5)通过连接对象创建执行对象Statement createStatement不安全
prepareStatement 安全推荐使用
* 6)执行sql语句
* 7)释放资源
*/
public class JdbcDemo {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1)导包--->jar包 mysql驱动jar包
//2)注册驱动
Class.forName("com.mysql.cj.jdbc.Driver"); //mysql8的驱动的实现类的路径带cj这个包
//3)获取数据库的连接对象
//驱动管理程序的类DriverManager:
//public static Connection getConnection(String url, // url:连接数据库的地址:
//String user, 数据库的用户名
// String password) 密码 throws SQLException
Connection conn = DriverManager.getConnection(
//url:数据库后面? 一堆参数 mysql5.7以后
"jdbc:mysql://localhost:3306/javaee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", //
"root",
"123456");
// 4)准备好sql语句
String sql = "insert into student values(9,'德邦',18,'男','艾欧尼亚',60,70)";
//5)通过连接对象创建执行对象Statement
//Statement createStatement()
Statement stmt = conn.createStatement();
//6)执行sql语句:通用方法:增删改
//int executeUpdate(String sql)
int count = stmt.executeUpdate(sql);
System.out.println("影响了"
+ count + "行");
//7)释放资源
stmt.close();//执行对象
conn.close(); //连接对象
}
}
1)PreparedStatement执行对象:
PreparedStatement执行对象:
* Connection接口:
* PreparedStatement prepareStatement(String sql):获取预编译对象,
同时将参数化的sql发送给数据库
* 通过预编译的sql语句对象,它的内存中就可以对参数?(占位符)进行赋值
3)PreparedStatement和Statement区别:
Statement:执行静态sql语句,写死了---存在字符串拼接
会造成SQL注入,是一种非常严重的问题,开发中不会使用Statement作为执行对象!
PreparedStatement
最大的特点:参数化的sql,防止参数的字符串拼接,有效防止SQL注入,比Statement更安全
4)代码封装:
public class DeptTool {
//定义私有化静态
private static String driverName = null;
private static String url = null;
private static String uers = null;
private static String password = null;
//无参构造私有化
private DeptTool() { }
static {
//创建一个空的properties属性集合列表
Properties properties = new Properties();
//获取src下的配置文件
InputStream res = DeptTool.class.getClassLoader().getResourceAsStream("jdbc.properties");
try {
//将资源流的内容加载到属性列表中
properties.load(res);
//通过键过取值
driverName = properties.getProperty("DriverName");
url = properties.getProperty("url");
uers = properties.getProperty("uers");
password = properties.getProperty("password");
//注册驱动
Class.forName(driverName);
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
//封装获取数据库的连接对象
public static Connection getConnection(){
Connection connection = null;
try {
connection = DriverManager.getConnection(url,uers,password);
return connection;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//针对DQL语句 释放资源封装
//ResultSet Statement Connection
public static void close(ResultSet res, Statement sta, Connection con){
if(res != null){
try {
res.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (sta != null){
try {
sta.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
//针对DDL DML语句释放资源封装
public static void close( Statement sta,Connection con){
close(null,sta,con);
}
}
--------------------------------------
public class Dept {
private int id ;
private String edept_name ;
private String dept_address;
public Dept() {
}
public Dept(int id, String edept_name, String dept_address) {
this.id = id;
this.edept_name = edept_name;
this.dept_address = dept_address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getEdept_name() {
return edept_name;
}
public void setEdept_name(String edept_name) {
this.edept_name = edept_name;
}
public String getDept_address() {
return dept_address;
}
public void setDept_address(String dept_address) {
this.dept_address = dept_address;
}
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", edept_name='" + edept_name + '\'' +
", dept_address='" + dept_address + '\'' +
'}';
}
}
-------------------------------------------------------------------
public interface DeptDemo {
//分页查询
List<Dept> limit(int indenx,int value);
//添加整行
void alter(Dept d);
//删除整行
void drop(int a);
//查询整行
Dept from(int b);
}
------------------------------------------------------------------
public class DeptDemoImpl implements DeptDemo{
@Override
public List<Dept> limit(int indenx, int value) {
//获取对象连接
Connection con = null;
con= DeptTool.getConnection();
PreparedStatement pre = null;
ResultSet res = null;
//准备SQL举例
String sql = "SELECT * FROM dept LIMIT ? ,?;";
List<Dept> list = new ArrayList<>();
//获取执行对象
try {
pre = con.prepareStatement(sql);
pre.setInt(1,indenx);
pre.setInt(2,value);
res = pre.executeQuery();
Dept dept = null;
while(res.next()){
int anInt = res.getInt(1);
String string = res.getString(2);
String string1 = res.getString(3);
dept = new Dept(anInt,string,string1);
list.add(dept);
}
return list;
} catch (SQLException e) {
e.printStackTrace();
}finally {
DeptTool.close(res,pre,con);
}
return null;
}
@Override
public void alter(Dept d) {
//获取数据库连接对象
Connection connection = null;
PreparedStatement pre = null;
connection = DeptTool.getConnection();
//准备SQL语句
String sql = "INSERT INTO dept VALUES (?,?,?);";
try {
//获取执行对象
pre = connection.prepareStatement(sql);
pre.setInt(1,d.getId());
pre.setString(2,d.getEdept_name());
pre.setString(3,d.getDept_address());
pre.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
DeptTool.close(pre,connection);
}
}
@Override
public void drop(int a) {
//连接数据库
Connection connection = null;
PreparedStatement ment = null;
connection = DeptTool.getConnection();
//准备SQL语句
String sql = "DELETE FROM dept WHERE id = ?;";
//创建执行对象
try {
ment = connection.prepareStatement(sql);
ment.setInt(1,a);
int i = ment.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//释放资源
DeptTool.close(ment,connection);
}
}
@Override
public Dept from(int b) {
//连接数据库
Connection con = null;
PreparedStatement prepared = null;
con = DeptTool.getConnection();
//准备SQL语句
String sql = "select *FROM dept WHERE id = ?;";
Dept dept = null;
ResultSet result = null;
//执行对象
try {
prepared = con.prepareStatement(sql);
prepared.setInt(1,b);
result = prepared.executeQuery();
dept = new Dept();
while (result.next()){
String str = result.getString(2);
String str1 = result.getString(3);
dept.setId(b);
dept.setEdept_name(str);
dept.setDept_address(str1);
}
return dept;
} catch (SQLException e) {
e.printStackTrace();
}finally {
DeptTool.close(result,prepared,con);
}
return null;
}
}
------------------------------------------------
public class DeptTest {
public static void main(String[] args) {
//分页
limit();
alter();
drop();
from();
}
public static void limit(){
DeptDemoImpl deptDemo = new DeptDemoImpl();
List<Dept> m = deptDemo.limit(0, 2);
for (Dept l : m){
System.out.println(l);
}
}
public static void alter(){
Dept dept = new Dept(4,"DEVELOPMENT","China");
DeptDemoImpl deptDemo = new DeptDemoImpl();
deptDemo.alter(dept);
}
public static void drop(){
DeptDemoImpl deptDemo = new DeptDemoImpl();
deptDemo.drop(50);
}
private static void from() {
DeptDemoImpl deptDemo = new DeptDemoImpl();
Dept from = deptDemo.from(2);
System.out.println(from);
}
}
4)五大步骤:
commons-dbtuls开源工具类库:对jdbc简易封装,简化书写代码!
下载地址:https://commons.apache.org/proper/commons-dbutils/ 官网
1)导包
数据库驱动jar包
druid连接池的包
junit的包以及依赖包
commons-dbtuls的包
commons-dbutils-1.7.jar 核心包
commons-lang-2.6.jar 语言包
commons-logging-1.2.jar 日志包 ---后期使用log4j.properties:日志记录文件
commons-collections-3.2.2.jar
2)配置文件 jdbc.properties:里面提供的数据库的连接参数(里面的名称不能写)以及连接池的参数
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/javaee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000
minIdle=3
maxIdle=4
3)书写实体类 com.qf.pojo
Student
4)书写数据库的接口
com.qf.dao
StudentDao
5)com.qf.dao.impl
StudentDaoImpl
实现
这里使用Dbutils工具的核心类
创建执行对象QueryRunner
5)案例:
自定义工具类
* 获取连接对象
* 获取数据源:DataSource
*/
public class DruidJbdcUtils {
//线程 存储Connection:模拟线程
private static ThreadLocal<Connection> t1 = new ThreadLocal<>() ;
private static DataSource ds ;
//静态代码块
static{
try {
//加载druid.properties配置文件
Properties prop = new Properties() ;
//读取当前druid.properties里面的内容,获取到它所在的资源文件输入流对象
InputStream inputStream = DruidJbdcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
//加载属性列表中
prop.load(inputStream) ;
//创建数据源对象
ds = DruidDataSourceFactory.createDataSource(prop); //获取数据源
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//定义静态功能,获取数据源
public static DataSource getDataSource(){
return ds ;
}
//获取连接对象
//连接对象每一个现在模拟线程:用户都要连接对象,将连接对象:存储ThreadLocal
public static Connection getConnetion(){
Connection conn = null ;
//先从线程ThreadLocal获取当前里面的连接对象
//get():获取当前线程所在的连接对象
try {
conn = t1.get();
if(conn == null ){
//如果当前线程没有没有连接对象
//从数据库连接池中获取
conn = ds.getConnection(); //从数据源(连接池)中获取连接对象,将连接对象绑定当当前线程上
//绑定当前当线程上
t1.set(conn);
}
return conn ;
} catch (SQLException e) {
e.printStackTrace();
}
return null ;
}
//封装释放资源代码
//针对DQL语句操作,释放资源
//ResuletSet,Statement,Connection
public static void close(ResultSet rs, Statement stmt, Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
// 将释放资源也可以封装到功能中
//针对的是DDL/DML语句操作时释放资源
public static void close(Statement stmt,Connection conn){
close(null,stmt,conn);
}
//后期需要用到事务
//封装事务的代码
//开启事务
public static void startStransaction() throws SQLException {
Connection connection = ds.getConnection();
connection.setAutoCommit(false) ; //禁用自动提交
//释放资源
connection.close() ; //归还到连接池中
//需要从线程中解绑
t1.remove();
}
//事务回滚
public static void rollBackAndClose() throws SQLException {
Connection connection = ds.getConnection();
connection.rollback() ;//事务回滚
//释放资源
connection.close() ; //归还到连接池中
//需要从线程中解绑
t1.remove();
}
//提交事务
public static void commitAndClose() throws SQLException {
Connection connection = ds.getConnection();
connection.commit(); ;//提交事务
//释放资源
connection.close() ; //归还到连接池中
//需要从线程中解绑
t1.remove();
}
public static void main(String[] args) {
DataSource dataSource = DruidJbdcUtils.getDataSource();
System.out.println(dataSource);
Connection connetion = DruidJbdcUtils.getConnetion();
System.out.println(connetion);
}
}
----------学生的数据接口层--------------------
* 针对学生的数据接口层
*/
public interface StudentDao {
/**
* 查询所有学生信息
* @return 返回的学生列表
*/
List<Student> findAllStudent() throws SQLException;
/**
* 通过学生的编号获取学生信息
* @param id 学生编号
* @return 返回的就是学生实体
* @throws SQLException
*/
Student findStudentById(int id) throws SQLException ;
/**
* 添加学生数据
* @param student
*/
void addStudent(Student student) throws SQLException;
/**
* 获取总记录数
* @return
*/
int getTotalCount() throws SQLException;
}
--------------------------Dbutils工具类实现-----------------------------
* 使用Dbutils工具类实现
*
* QueryRunner对象
*
* query(String sql...)
* update(String sql,Object...params)
*/
public class StudentDaoImpl implements StudentDao {
/**
* 查询所有学生数据
* @return 列表
* @throws SQLException
*/
@Override
public List<Student> findAllStudent() throws SQLException {
//默认自动提交:创建执行对象
//public QueryRunner(DataSource ds)
QueryRunner qr = new QueryRunner(DruidJbdcUtils.getDataSource()) ; //同时加载数据源
//书写sql
String sql = "select * from student" ;
//通用的查询方法
//public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:查询的结果处理的接口 ResultSetHandler
//public class BeanListHandler<T> implements ResultSetHandler<List<T>>
//将ResultSet中所有的数据转化成List,List中存放的是类对象
//参数3:params 实际参数
List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));
return list;
}
/**
* * 通过学生的编号获取学生信息
* @param id 学生编号
* @return 返回的就是学生实体
* @throws SQLException
*/
@Override
public Student findStudentById(int id) throws SQLException {
//创建执行对象
QueryRunner qr = new QueryRunner(DruidJbdcUtils.getDataSource()) ;
//准备sql
String sql = "select * from student where id = ?" ;
//执行查询
//将查询某一条记录,封装到一条实体中
//public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:查询的结果处理的接口 ResultSetHandler
//public class BeanHandler<T> implements ResultSetHandler<T>
//将ResultSet中查询的某一一行的数据转化成类对象
Student student = qr.query(sql, new BeanHandler<Student>(Student.class), id);
//不需要释放资源
return student;
}
/**
* 添加学数据
* @param student
*/
@Override
public void addStudent(Student student) throws SQLException {
//执行对象
QueryRunner qr = new QueryRunner(DruidJbdcUtils.getDataSource()) ;
//sql
String sql = "insert into student values(?,?,?,?,?,?,?)" ;
//通用的更新操作
//public int update(String sql, Object... params) throws SQLException {}:针对增删改
int count = qr.update(sql, student.getId(),
student.getName(),
student.getAge(),
student.getSex(),
student.getAddress(),
student.getMath(),
student.getEnglish());
System.out.println(count);
}
/**
* 查询总记录数
* @return
*/
@Override
public int getTotalCount() throws SQLException {
//执行对象
QueryRunner qr = new QueryRunner(DruidJbdcUtils.getDataSource()) ;
//sql
String sql = "select count(id) from student" ;
//将查询某一条记录,封装到一条实体中
//public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
//参数1:sql语句
//参数2:查询的结果处理的接口 ResultSetHandler
//public class ScalarHandler<T> implements ResultSetHandler<T>
//将ResultSet中一条记录的其中某一列的数据存成Object
// public ScalarHandler()
Object obj = qr.query(sql, new ScalarHandler<>());
String strObj = String.valueOf(obj);
//String---Int
int count = Integer.parseInt(strObj);
return count;
}
}
-------------------单元测试类-----
* @author Kuke
* @date 2021/11/8 14:44
*/
public class StudentTest {
@Test
public void testFindAll() throws SQLException {
StudentDao sd = new StudentDaoImpl() ;
List<Student> list = sd.findAllStudent();
if(list!=null){
for(Student s:list){
System.out.println(s);
}
}
}
@Test
public void testStudentById() throws SQLException {
StudentDao sd = new StudentDaoImpl() ;
Student student = sd.findStudentById(5);
System.out.println(student);
}
//测试添加
@Test
public void testAdd() throws SQLException {
StudentDao sd = new StudentDaoImpl() ;
Student student = new Student() ;
student.setId(11) ;
student.setName("孙杰") ;
student.setAge(20) ;
student.setSex("男");
student.setAddress("西安市");
student.setMath(89);
student.setEnglish(90);
sd.addStudent(student);
}
//测试查询总记录数
@Test
public void testgetCount() throws SQLException {
StudentDao sd = new StudentDaoImpl() ;
int totalCount = sd.getTotalCount();
System.out.println(totalCount);
}
}
5)注解:
1)注解概念:
标记类,方法,参数,成员变量,由一种特殊的含义 (能被解析的)
2)注解有哪些类型:
注解中的属性(方法名)---返回值类型 (5种 类型!)
* String
* 枚举类型Enum
* 注解类型@Annotation
* 基本类型
* 以上类型的数组
3)注解的分类
注解的分类
* jdk内置注解
* @Overrid:标记当前这个方法是否为重写方法: 重写了类/抽象类或者接口
* @Deprecated:标记某个方法是过时方法
* @SuppressWarnings:压制警告, 一般企业中, 项目部署上线的时候,代码中不能黄色警告线!
* @FunctionalInteface:函数式接口 :jdk8后,
* 接口如果一个抽象方法,那么这个接口就可以是函数式接口----使用lambda表达式
*
* 内置注解底层依赖的元注解
* @Target(ElementType.METHOD)
* 标记当前这个注解所作用的范围
* 属性:
* ElementType[] values()--->返回值枚举的数组--->里面一些常量
* TYPE,当前注解可以作用在类上
*
*
* FIELD,当前这个注解可以作用成员属性上
METHOD, ...当前这个注解可以作用在方法上
*
* @Retention(RetentionPolicy.SOURCE) :
* 当做标记@Override注解的保留的阶段
* RetentionPolicy value();
*
* 返回值枚举类型
* SOURCE :原码编译阶段
* CLASS: 类 的加载
* RUNTIME:运行阶段