JDBC的使用:
1. 注册Driver -> oracle.jdbc.driver.OracleDriver
*方式一:Class.forName("oracle.jdbc.driver.OracleDriver");
方式二:Driver driver = new DriverImpl();
DriverManager.registerDriver(driver);
方式三:-Djdbc.drivers=oracle.jdbc.driver.OracleDriver
2. 获得Connection
*方式一:Connection conn = DriverManager.getConnection(
url,user,password);
方式二:Driver driver = new DriverImpl();
Connection conn = driver.connect(url,pro);
3. 创建Statement
. Statement stmt = conn.createStatement();
//和数据库交互,传输sql语句到数据库,sql语句接下来
//在数据库内编译、优化好等着进一步执行;
. PreparedStatement pstmt =
conn.prepareStatement(sql);
4. 执行SQL语句
//实现和数据库交互,传输SQL语句到数据库并执行SQL
ResultSet rs = stmt.executeQuery(sql);
int i = stmt.executeUpdate(sql);
boolean flag = stmt.execute(sql);
//实现和数据库交互,传输参数值到数据库并执行SQL
pstmt.setInt(1,100);
pstmt.setString(2,"zs");
pstmt.setDate(3,Date.valueOf("1979-9-1"));
ResultSet rs = pstmt.executeQuery();
int i = pstmt.executeUpdate();
boolean flag = pstmt.execute();
5. 处理结果集
1) 使用结果集(ResultSet)对象的访问方法获取数据;
a. next():下一个记录
b. first():第一个记录
c. last():最后一个记录
d. previous():上一个记录
2) 通过字段名或索引取得数据
3) 结果集保持了一个指向了当前行的指针,初始化位置为第一个记录前。
6. 关闭对象、释放资源,一般推荐先构建的后释放
一般在finally里定义;
1) 首先关闭记录集;
2) 其次关闭声明;
3) 最后关闭连接对象。
mybatis:对java数据持久层轻度封装的开源框架,抽象了大量的JDBC冗余代码(hibernate是重度封装)
1.mybatis-config.xml文件,配置连接方式,数据库的信息,mappers引入需要连接的mapper文件路径
2.mapper文件,用于编写dao接口中的方法实现(动态代理)
结果集映射ResultMaps
<resultMap id="StudentResult" type="com.briup.pojo.Student">
<id property="studId" column="stud_id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
</resultMap>
resultMap的id值应该在此名空间内是唯一的,并且type属性是完全限定类名或者是返回类型的别名。
<result>子元素被用来将一个resultset列映射到对象的一个属性中。
<id>元素和<result>元素功能相同,不过<id>它被用来映射到唯一标识属性,用来区分和比较对象(一般和主键列相对应)
1.一对一映射
(1)级联查询,将第二张表引入第一张
可以直接<result property="birthday" column="dob"/>
<result property="address.addrId" column="addr_id"/>将调用getaddress,getaddrid相当于调用两次address中的方法,或者<association property="address" resultMap="AddressResult" ></association>将结果集引入
(2)嵌套查询
<association property="address"
column="addr_id"
select="findAddressById" />
相当于在一个查询中调用另一个查询,效率可能会低
2.一对多映射:返回是集合
(1)级联查询,多一个<collection property="courses" resultMap="CourseResult"/>表示多的一方查询结果放在少的一方
(2)嵌套查询,和一对一相同,多一个collection标签
两种映射方式 执行sql的个数
嵌套结果 1
嵌套查询 1+N (N表示多的地方有多少行)
3.多对多:中间用桥表实现一对一关系
实际上操作还是双向的一对多,不可能看所有的老师教所有的学生,从哪个方向冗余都很多,实际上并不会这么做
<![CDATA[ < ]]>表示实体小于或者用<表示
extends标签继承子结果映射,减少了代码的书写量
动态sql:用于精简代码,页面传入值时动态增加或减少sql
通过使用<if>,<choose>,<where>,<foreach>,<trim>元素提供了对构造动态SQL语句
添加主键
<selectKey keyProperty="studId" resultType="int" order="BEFORE">
SELECT my_seq.nextval FROM DUAL
</selectKey>
注:SelectKey需要注意order属性,像MySQL、SQLServer等一类支持自动增长类型的数据库中,order需要设置为after才会取到正确的值。像Oracle这样取序列的情况,需要设置为before,否则会报错。
Mybatis 分页显示
<select id="findAllUsers" resultType="User">
select id,name,gender from t_user
</select>
public List<User> findAllUsers(RowBounds rowBounds);
然后,你可以加载第一页数据(前5条):
int offset = 0;起始位置
int limit = 5; 几条数据
RowBounds rowBounds = new RowBounds(offset, limit);
List<Student> = studentMapper.getStudents(rowBounds);
若要展示第二页,使用offset=5,limit=5
但是其实Mybatis的分页是基于内存的分页(查出所有记录再按偏移量和limit取结果),在大数据量的情况下这样的分页效率会很低。
oracle使用rownum也可以完成分页:效率高于mybatis的函数分页
rownum 只能等于1
rownum 大于0
rownum 可以小于任何数
例如:把sql语句查询结果当做一张表再查询
select *
from (
select rownum as rowno, t.*
from t_user t
where rownum <= 10
) temp
where temp.rowno >= 5;
mybatis有两级缓存
一级缓存:缓存同一个session中查询的相同数据
注意:session调用commit或close方法后,一级缓存就会被清空
二级缓存: 在不同的session对象之间可以共享缓存数据(默认不开启)
1.mybatis-config.xml文件中保证<setting name="cacheEnabled" value="true"/>设置中是缓存功能是开启的,默认就是开启的true
2.在需要二级缓存的xml映射文件中,手动开启缓存功能,在根元素中加入一个标签即可:<cache/>
3.一个session查询完数据之后,需要调用commit或者close方法后,这个数据才会进入到缓存中,然后其他session就可以共享到这个缓存数据了
注意:默认情况下,被二级缓存保存的对象需要实现序列化接口,可以通过cache标签的readOnly属性进行设置
mybatis的注解:不用写mapper配置文件,直接在接口上配置注解
@Insert注解来定义一个INSERT映射语句:@Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
自动生成主键:@SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",keyProperty="studId", resultType=int.class, before=true)
@select查询:@Select("SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM STUDENTS WHERE STUD_ID=#{studId}")
@Delete
@Update:更新修改
结果映射@Results(
{
@Result(id = true, column = "stud_id", property = "studId"),
@Result(column = "name", property = "name"),
@Result(column = "email", property = "email"),
@Result(column = "addr_id", property = "address.addrId")
})
1. 注册Driver -> oracle.jdbc.driver.OracleDriver
*方式一:Class.forName("oracle.jdbc.driver.OracleDriver");
方式二:Driver driver = new DriverImpl();
DriverManager.registerDriver(driver);
方式三:-Djdbc.drivers=oracle.jdbc.driver.OracleDriver
2. 获得Connection
*方式一:Connection conn = DriverManager.getConnection(
url,user,password);
方式二:Driver driver = new DriverImpl();
Connection conn = driver.connect(url,pro);
3. 创建Statement
. Statement stmt = conn.createStatement();
//和数据库交互,传输sql语句到数据库,sql语句接下来
//在数据库内编译、优化好等着进一步执行;
. PreparedStatement pstmt =
conn.prepareStatement(sql);
4. 执行SQL语句
//实现和数据库交互,传输SQL语句到数据库并执行SQL
ResultSet rs = stmt.executeQuery(sql);
int i = stmt.executeUpdate(sql);
boolean flag = stmt.execute(sql);
//实现和数据库交互,传输参数值到数据库并执行SQL
pstmt.setInt(1,100);
pstmt.setString(2,"zs");
pstmt.setDate(3,Date.valueOf("1979-9-1"));
ResultSet rs = pstmt.executeQuery();
int i = pstmt.executeUpdate();
boolean flag = pstmt.execute();
5. 处理结果集
1) 使用结果集(ResultSet)对象的访问方法获取数据;
a. next():下一个记录
b. first():第一个记录
c. last():最后一个记录
d. previous():上一个记录
2) 通过字段名或索引取得数据
3) 结果集保持了一个指向了当前行的指针,初始化位置为第一个记录前。
6. 关闭对象、释放资源,一般推荐先构建的后释放
一般在finally里定义;
1) 首先关闭记录集;
2) 其次关闭声明;
3) 最后关闭连接对象。
mybatis:对java数据持久层轻度封装的开源框架,抽象了大量的JDBC冗余代码(hibernate是重度封装)
1.mybatis-config.xml文件,配置连接方式,数据库的信息,mappers引入需要连接的mapper文件路径
2.mapper文件,用于编写dao接口中的方法实现(动态代理)
结果集映射ResultMaps
<resultMap id="StudentResult" type="com.briup.pojo.Student">
<id property="studId" column="stud_id" />
<result property="name" column="name" />
<result property="email" column="email" />
<result property="phone" column="phone" />
</resultMap>
resultMap的id值应该在此名空间内是唯一的,并且type属性是完全限定类名或者是返回类型的别名。
<result>子元素被用来将一个resultset列映射到对象的一个属性中。
<id>元素和<result>元素功能相同,不过<id>它被用来映射到唯一标识属性,用来区分和比较对象(一般和主键列相对应)
1.一对一映射
(1)级联查询,将第二张表引入第一张
可以直接<result property="birthday" column="dob"/>
<result property="address.addrId" column="addr_id"/>将调用getaddress,getaddrid相当于调用两次address中的方法,或者<association property="address" resultMap="AddressResult" ></association>将结果集引入
(2)嵌套查询
<association property="address"
column="addr_id"
select="findAddressById" />
相当于在一个查询中调用另一个查询,效率可能会低
2.一对多映射:返回是集合
(1)级联查询,多一个<collection property="courses" resultMap="CourseResult"/>表示多的一方查询结果放在少的一方
(2)嵌套查询,和一对一相同,多一个collection标签
两种映射方式 执行sql的个数
嵌套结果 1
嵌套查询 1+N (N表示多的地方有多少行)
3.多对多:中间用桥表实现一对一关系
实际上操作还是双向的一对多,不可能看所有的老师教所有的学生,从哪个方向冗余都很多,实际上并不会这么做
<![CDATA[ < ]]>表示实体小于或者用<表示
extends标签继承子结果映射,减少了代码的书写量
动态sql:用于精简代码,页面传入值时动态增加或减少sql
通过使用<if>,<choose>,<where>,<foreach>,<trim>元素提供了对构造动态SQL语句
添加主键
<selectKey keyProperty="studId" resultType="int" order="BEFORE">
SELECT my_seq.nextval FROM DUAL
</selectKey>
注:SelectKey需要注意order属性,像MySQL、SQLServer等一类支持自动增长类型的数据库中,order需要设置为after才会取到正确的值。像Oracle这样取序列的情况,需要设置为before,否则会报错。
Mybatis 分页显示
<select id="findAllUsers" resultType="User">
select id,name,gender from t_user
</select>
public List<User> findAllUsers(RowBounds rowBounds);
然后,你可以加载第一页数据(前5条):
int offset = 0;起始位置
int limit = 5; 几条数据
RowBounds rowBounds = new RowBounds(offset, limit);
List<Student> = studentMapper.getStudents(rowBounds);
若要展示第二页,使用offset=5,limit=5
但是其实Mybatis的分页是基于内存的分页(查出所有记录再按偏移量和limit取结果),在大数据量的情况下这样的分页效率会很低。
oracle使用rownum也可以完成分页:效率高于mybatis的函数分页
rownum 只能等于1
rownum 大于0
rownum 可以小于任何数
例如:把sql语句查询结果当做一张表再查询
select *
from (
select rownum as rowno, t.*
from t_user t
where rownum <= 10
) temp
where temp.rowno >= 5;
mybatis有两级缓存
一级缓存:缓存同一个session中查询的相同数据
注意:session调用commit或close方法后,一级缓存就会被清空
二级缓存: 在不同的session对象之间可以共享缓存数据(默认不开启)
1.mybatis-config.xml文件中保证<setting name="cacheEnabled" value="true"/>设置中是缓存功能是开启的,默认就是开启的true
2.在需要二级缓存的xml映射文件中,手动开启缓存功能,在根元素中加入一个标签即可:<cache/>
3.一个session查询完数据之后,需要调用commit或者close方法后,这个数据才会进入到缓存中,然后其他session就可以共享到这个缓存数据了
注意:默认情况下,被二级缓存保存的对象需要实现序列化接口,可以通过cache标签的readOnly属性进行设置
mybatis的注解:不用写mapper配置文件,直接在接口上配置注解
@Insert注解来定义一个INSERT映射语句:@Insert("INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL,ADDR_ID, PHONE)
自动生成主键:@SelectKey(statement="SELECT STUD_ID_SEQ.NEXTVAL FROM DUAL",keyProperty="studId", resultType=int.class, before=true)
@select查询:@Select("SELECT STUD_ID AS STUDID, NAME, EMAIL, PHONE FROM STUDENTS WHERE STUD_ID=#{studId}")
@Delete
@Update:更新修改
结果映射@Results(
{
@Result(id = true, column = "stud_id", property = "studId"),
@Result(column = "name", property = "name"),
@Result(column = "email", property = "email"),
@Result(column = "addr_id", property = "address.addrId")
})