面试题
1.jdbc和mybatis优缺点
1.jdbc操作步骤比较繁琐,比较执行贾琏欲执事 而mybatis不用 消除这个代码
2.jdbc需要自己手动设置 参数 以及处理返回结果集—而mybatis不需要
3.mybatis可以采用xml和注解来写sql…jdbc把sql写到代码里面,提高维护性
4.jdbc 它是操作最底层的代码,mybatis也是从jdbc上面封装出来框架,mybatis支持缓存
2.jpa一级缓存和二级缓存是什么?
1.jpa一级缓存:属于entityManager级别缓存,jpa自带的,不用做任何配置,命中条件同一个entityManagerFactory,同一个EntityMManager同一个OID
2.二级缓存:属于entityManagerFactory级别缓存,不是自带,需要相应配置才行,命中条 件 同一个entityManagerFactory,同一个EntityMManager同一个OID
3.#和 $区别:
(1) $ 取得对象里面的某个属性 比如 ${id} Long getId
# 都可以
(2)重点 # select * from product where productName = ? 预编译的对象 $ select * from product where productName = 罗技G500 拼接字符串方式
#推荐使用 $ sql注入问题
(3)后面使用$的 orderby+limit 后面就不需要添加引号
Mybatis使用方法
1.导入jar包
注意:后面的框起来的两个包是日志框架的包(slf4j),方便我们排错的
2.建表
3.配置Mybatis-config.xml
<?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>
<!-- 开发环境-->
<environments default="development">
<!--
一个环境 id:为这个环境取唯一一个id名称
-->
<environment id="development">
<!--
事务管理 type:JDBC(支持事务)/MANAGED(什么都不做)
mysql: innodb MyISAM
-->
<transactionManager type="JDBC" />
<!-- 数据源, 连接池 type(POOLED):MyBatis自带的连接池 -->
<dataSource type="POOLED">
<!-- 连接数据库的参数 四大金刚 -->
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///test" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 这个mappers代表的是相应的ORM映射文件 -->
<mappers>
<mapper resource="cn/itsource/mybatis/domain/ProductMapper.xml" />
</mappers>
</configuration>
4.配置对应domain的xml(比如ProductMapper.xml)
下面是最简单的增删查改,和高级查询,批量增加,修改,删除
<?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="cn.itsource.mybatis.domain.ProductMapper">
<!--
select:表示查询标签
id: 代表给标签取个名称 必须唯一
resultType:返回值类型
-->
<select id="findAll" resultType="cn.itsource.mybatis.domain.Product">
select * from product
</select>
<!--新增 parameterType 参数类型
useGeneratedKeys:是否得到主键
keyColumn:数据库主键的列
keyProperty:对应实体类的属性
-->
<insert id="save" parameterType="cn.itsource.mybatis.domain.Product"
useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into product(productName,salePrice,costPrice)
values (#{productName},#{salePrice},#{costPrice})
</insert>
<update id="update" parameterType="cn.itsource.mybatis.domain.Product">
update product set productName=#{productName},salePrice=#{salePrice},costPrice=#{costPrice}
where id=#{id}
</update>
<delete id="delete" parameterType="long">
delete from product where id =#{id}
</delete>
<select id="findOne" parameterType="cn.itsource.mybatis.query.ProductQuery" resultType="cn.itsource.mybatis.domain.Product">
select * from product where productName=#{productName}
</select>
<sql id="whereSql">
<where>
<if test="productName!=null">
and productName=#{productName}
</if>
<if test="id!=null">
and id=#{id}
</if>
</where>
</sql>
<select id="queryByCondition" parameterType="cn.itsource.mybatis.query.ProductQuery" resultType="cn.itsource.mybatis.domain.Product">
select * from product
<include refid="whereSql"></include>
</select>
<delete id="deleteBatch" parameterType="list">
delete from product where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</delete>
<insert id="insertBatch" parameterType="list">
insert into product(productName,salePrice,costPrice)
values
<foreach collection="list" item="product" separator=",">
(#{product.productName},#{product.salePrice},#{product.costPrice})
</foreach>
</insert>
<update id="updateBatch" parameterType="map">
update product set productName=#{productName} where id in
<foreach collection="list" item="id" open="(" close=")" separator=",">
#{id}
</foreach>
</update>
</mapper>
5工具类的抽取
这里使用的是枚举的单例模式
INSTANCE;
private static SqlSessionFactory sqlSessionFactory;
//静态代码块
static {
Reader reader=null;
try {
reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
//抽取一个---sqlSession
public SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
MyBatis的细节问题
1.主键问题
有时候 保存一条数据之后,需要拿到这条数据的主键,拿到之后可以做后续事情
useGeneratedKeys="true" keyColumn="id" keyProperty="id"
1. useGeneratedKeys:是否得到主键
2. keyColumn:数据库主键的列
3. 3.keyProperty:对应实体类的属性
2.日志问题
1.为什么要使用日志?
有时候,需要打印的sql的信息 比如sql的传参数 返回值 – 必须使用日志
2.日志框架
a)自己写:
通过反射技术 ,可以拿到参数 可以方法 拿到返回值
b)log4j -- 使用比较多
c)日志框架标准
以前没有日志框架的, 每个人处理日志 都不一样 ..
日志标准 -- slf4j(抽象标准) -->很多实现:
logging,logback,log4j
3.使用日志框架
1.导入jar包(在上面说导入mybatis的jar包的时候说了到哪个)
2.写一个配置文件
log4j.rootLogger=ERROR, stdout
日志等级(了解): OFF level > FATAL(致命) > ERROR(错误) > WARN (警告)>
# INFO (提示)> DEBUG (调试)> trace > ALL level(所有配置)
#输出效果 如果你设置日志级别是trace,则大于等于这个级别的日志都会输出
# 关闭日志输出
#log4j.rootLogger=NONE 不想打印日志 就配置NONE
# WARN为一般警告,比如session丢失、
# INFO为一般要显示的信息,比如登录登出、
# DEBUG为程序的调试信息
# TRACE 堆栈信息
# 扫描包 配置自己包
#注意点 包名/配置等级 配置DEBUG/ALL
log4j.logger.cn.itsource=DEBUG/TRACE
#ConsoleAppender:输出控制台
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#layout: 格式样式
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#采用下面的样式输出 [20191224]类名
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n