持久层框架,半自动ORM框架
在jsp中引入资源文件路径
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
然后在basePath后面跟路径,不带/
<%=basePath%>......
jdbc连接数据库的方式
/*
* JDBC操作数据库的步骤:
* 1.注册驱动
* 告知JVM使用的是哪一个数据库的驱动
* 2.获得连接
* 使用JDBC中的类,完成对mysql数据库的连接(TCP协议)
* 3.获得语句执行平台
* 通过连接对象获取对SQL语句的执行者对象
* 4.执行sql语句
* 使用执行者对象,向数据库执行SQL语句
* 获取数据库的执行后的结果
* 5.处理结果
* 6.释放资源
* 调用一堆close
*/
public class JDBCTest {
public static void main(String[] args) throws Exception {
public static void main(String[] args) throws Exception {
// 1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取连接对象
String url = "jdbc:mysql://localhost:3306/itheima";
Connection conn = DriverManager.getConnection(url, "root", "root");
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String user = sc.nextLine();
System.out.println("请输入密码:");
String pass = sc.nextLine();
// 拼写SQL语句
String sql = "select * from users where username = ? and password = ? ";
// 3.获取执行SQL语句
//Connection接口
PreparedStatement pst = conn.prepareStatement(sql);
//调用pst对象的setXXX方法设置问号占位符的参数
pst.setObject(1, user);
pst.setObject(2, pass);
System.out.println(sql);
// 4.调用执行者对象方法,执行SQL语句获取结果集
ResultSet rs = pst.executeQuery();
// 5.处理结果集
while (rs.next()) {
System.out.println(rs.getString("username") + "\t" + rs.getString("password"));
}
// 6.关闭资源
rs.close();
pst.close();
conn.close();
}
}
使用mybatis
1引入jar包
2配置mybatis
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- mybatis的环境配置,此信息在开发中只需照搬即可 -->
<environments default="development">
<environment id="development">
<!-- 配置JDBC事务,此事务由mybatis管理 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 配置连接池,此连接池为mybatis连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 映射文件 (加载所需要的局部配置)
Mappers
<mapper resource=’’/>
使用相对于类路径的资源
如:<mapper resource="sqlmap/User.xml" />
<mapper url=’’/>
使用完全限定路径
如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />
<mapper class=’’/>
使用mapper接口的全限定名
如:<mapper class="com.sjg.dao.UserMapper"/>
注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;
<package name=’’/>(推荐)
注册指定包下的所有映射文件
如:<package name="com.sjg.dao"/>
注意:此种方法要求mapper接口和mapper映射文件要名称相同,且放到同一个目录下;
-->
<mappers>
<mapper resource="config/User.xml"/>
<package name="com.sjg.dao"/>
</mappers>
</configuration>
mybatis的核心对象SqlSession
1:向sql语句传递参数
2:执行sql语句
3:获取执行sql语句的结果
4:事务的控制
如何拿到SqlSession
1:通过配置文件获取数据库连接信息
2:通过配置信息构建SqlSessionFactory
3:通过SqlSessionFactory打开数据库连接会话SqlSession
public static void main(String[] args) {
String resource = "config/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 构建sqlSession工厂
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
// 获取sqlSession
SqlSession session = sqlSessionFactory.openSession();
}
mybatis的mapper文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
//相当于文件的唯一标识
<mapper namespace="com.atguigu.crud.dao.EmployeeMapper">
//配置数据库对应的Java类型
<resultMap type="com.atguigu.crud.bean.Employee" id="WithDeptResultMap">
<id column="emp_id" jdbcType="INTEGER" property="empId" />
<result column="emp_name" jdbcType="VARCHAR" property="empName" />
<result column="gender" jdbcType="CHAR" property="gender" />
<result column="email" jdbcType="VARCHAR" property="email" />
<result column="d_id" jdbcType="INTEGER" property="dId" />
<!-- 指定联合查询出的部门字段的封装 -->
<association property="department" javaType="com.atguigu.crud.bean.Department">
<id column="dept_id" property="deptId"/>
<result column="dept_name" property="deptName"/>
</association>
</resultMap>
<sql id="columns"> emp_id, emp_name, gender, email, d_id
</sql>
// parameterType为接受参数类型
<select id="queryMessageList" parameterType="com.atguigu.crud.bean.Employee" resultMap="WithDeptResultMap">
select <include refid="columns"/> from MESSAGE
<where>
<if test="empId!= null and !"".equals(empId.trim())">
and COMMAND=#{command}
</if>
<if test="empName!= null and !"".equals(empName.trim())">
and DESCRIPTION like '%' #{empName} '%'
</if>
</where>
</select>
<delete id="deleteOne" parameterType="int">
delete from MESSAGE where ID = #{_parameter}
</delete>
<delete id="deleteBatch" parameterType="java.util.List">
delete from MESSAGE where ID in(
<foreach collection="list" item="item" separator=",">
#{item}
</foreach>
)
</delete>
</mapper>
使用sqlSession:
例如
sqlSession.selectList("mapper+id");
传参
sqlSession.selectList("mapper+id",conmand);
mybatis中ognl表达式
java常用操作符有的需要转义
mybatis调试log4j整合
引入log4j的jar包
配置log4j
输出日志的级别和位置
log4j.rootLogger=DEBUG,Console
配置日志的位置
log4j.appender.Console=org.apache.log4j.ConsoleAppender
日志布局
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
日志输出格式
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
特定包日志输出其他级别,个性化
log4j.logger.org.apache=INFO
在mybatis.xml中,指定使用log4j为日志实现,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
</configuration>
这里的value值可以是SLF4J、Apache Commons Logging、Log4J2、Log4J、JDK logging(除Log4J2、Log4J外,其他未验证),并会按顺序查找
在web.xml中也需要配置======
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener>
mybatis对于增删改(和数据库引擎有关)
需要sqlSession.comimt();提交
一对多
<mapper namespace="Command">
<resultMap type="com.imooc.bean.Command" id="Command">
<id column="C_ID" jdbcType="INTEGER" property="id"/>
<result column="NAME" jdbcType="VARCHAR" property="name"/>
<result column="DESCRIPTION" jdbcType="VARCHAR" property="description"/>
<collection property="contentList" resultMap="CommandContent.Content"/>
</resultMap>
<select id="queryCommandList" parameterType="com.imooc.bean.Command" resultMap="Command">
select a.ID C_ID,a.NAME,a.DESCRIPTION,b.ID,b.CONTENT,b.COMMAND_ID
from COMMAND a left join COMMAND_CONTENT b
on a.ID=b.COMMAND_ID
<where>
<if test="name != null and !"".equals(name.trim())">
and a.NAME=#{name}
</if>
<if test="description != null and !"".equals(description.trim())">
and a.DESCRIPTION like '%' #{description} '%'
</if>
</where>
</select>
</mapper>
常用标签
MyBatis 获取数据库中自增主键值
<!--
useGeneratedKeys 设置为 true
keyProperty 表示把获得的自增主键的值赋给 javabean 中的哪个属性,
这里表示赋值给 employee 的 id 属性
-->
<insert id="addEmp" parameterType="employee"
useGeneratedKeys="true" keyProperty="id">
insert into t_employee(username, gender, email) values (#{username}, #{gender}, #{email})
</insert>
mybatis接口式编程
1:mybatis的mapper文件的namespace属性和代理接口的包名+接口名一样
2:方法名与mapper文件的id,传入参数,返回值类型一样
mybatis调用接口(底层通过动态代理)
//获得代理的实例
IMessage imessage = sqlSession.getMapper(IMessage.class//接口);
messageList = imessage.queryMessageList(parameter);
配置mybatis分页拦截器
配置文件中配置plugin
<plugins>
<plugin interceptor="com.imooc.interceptor.PageInterceptor">
<property name="test" value="abc"/>
</plugin>
</plugins>
/**
* 分页拦截器
*/
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})
public class PageInterceptor implements Interceptor {
private String test;
// 这里是每次执行操作的时候,都会进行这个拦截器的方法内
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY);
MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");
// 配置文件中SQL语句的ID
String id = mappedStatement.getId();
if(id.matches(".+ByPage$")) {
BoundSql boundSql = statementHandler.getBoundSql();
// 原始的SQL语句
String sql = boundSql.getSql();
// 查询总条数的SQL语句
String countSql = "select count(*) from (" + sql + ")a";
Connection connection = (Connection)invocation.getArgs()[0];
PreparedStatement countStatement = connection.prepareStatement(countSql);
ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue("delegate.parameterHandler");
parameterHandler.setParameters(countStatement);
ResultSet rs = countStatement.executeQuery();
Map<?,?> parameter = (Map<?,?>)boundSql.getParameterObject();
Page page = (Page)parameter.get("page");
if(rs.next()) {
page.setTotalNumber(rs.getInt(1));
}
// 改造后带分页查询的SQL语句
String pageSql = sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
metaObject.setValue("delegate.boundSql.sql", pageSql);
}
return invocation.proceed();
}
// 主要是为了把这个拦截器生成一个代理放到拦截器链中(拦截进行过滤)
@Override
public Object plugin(Object target) {
System.out.println(this.test);
return Plugin.wrap(target, this);
}
//拿到配置文件里面的值
@Override
public void setProperties(Properties properties) {
this.test = properties.getProperty("test");
// TODO Auto-generated method stub
}
}