基础内容
项目结构搭建:
pojo,domain,po,vo,bo的区别
pojo:不按mvc分层,只是java bean:有一些属性,还有get,set方法。
domain:不按mvc分层,只是java bean:有一些属性,还有get,set方法。
po:用在持久层;还可以在增加或者修改的时候,从页面直接传入action中,它里面的java bean类名等于表名,属性名等于表的字段名,还有对应的get,set方法。
vo:view object,表现层对象;主要用于高级查询中从页面接收传过来的各种参数。好处是好处是扩展性强。
解释:假如页面中返回的数据包括学生表和选课表中的数据,但这两类数据明显不在同一张表中。这时候,可以封装成vo类的对象,传递数据。
bo:用在service层,现在企业基本不用。
jdbc问题总结
频繁创建释放资源;
SQL语句在程序中硬编码;
sql的参数硬编码;
结果集硬编码;
Note: mybatis依赖的包不可更换为其他版本=。=
技巧:创建文件的时候选File即可,之后通过文件后缀确定文件类型;
MyBatis入门程序
映射文件:
<mapper namespace="test">
<select id="findUserById" parameterType="java.lang.Integer" resultType="com.User">
select * from user where id=#{id}
</select>
<select id="findUserByName" parameterType="java.lang.String" resultTupe="com.User">
<!-- 则selectList中,参数要写为'%王%'的形式 -->
<!-- select * from user where name=#{name} -->
select * from user where name=${value}
</select>
<insert id="insertUser" parameterType="com.User">
<!-- 执行 select LAST_INSERT_ID() 数据库函数,返回自增的主键-->
<!-- 目的:返回插入数据的id; -->
<!-- 这里的这条语句是用于mysql数据库的,oracle另说; -->
<!-- keyProperty:将返回的主键放入传入参数的Id中保存;
order:当前函数相对于insert语句的执行顺序;取值BEFORE和AFTER;
在insert前执行是before,在insert之后是after;
resultType:id的类型;
-->
<selectKey keyProperty="" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
<!-- 这里的username等,与User实体类中的属性名称对应 -->
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{addrss})
</insert>
</mapper>
namespace:命名空间,做sql隔离;就是,每个实体都会对应一个映射文件,为了避免在集成的时候出现重名,所有用namespace进行隔离;这也是之前看到的在dao文件中,用this.namespace().select(),的使用的原理。
select标签中的一些属性解释:
- id:sql语句唯一标识;
- parameterType:指定传入参数类型
- resultType:返回结果集类型
- #{}占位符:起到占位作用;如果传入的是基本类型,那么#{}中的变量名称可以随便写;
- ${}拼接符:字符串原样拼接;如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value;注意:拼接符有sql注入的风险,所以慎用;如果数据库查询语句需要用到like的时候,可用拼接符;
- #{},如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性名,即属性.属性;
比如说,这里的insert user,对应的#{}中的名称,必须是User类的属性名,比如说username即为User类的一个成员变量;
测试文件中:
public void testFindUserById() throws Exception{
String resource="SqlMapConfig.xml";
//通过流将核心配置文件读取进来;
InputStream inputStream = Resources.getResourceAsStream(resource);
//
SqlSessionFactory factory = new SqlSessionFactoryBuilder().bulid(inputStream);
//
SqlSession openSession = factory.openSession();
User user = openSession.selectOne("test.findUserById",1);
openSession.close();
}
核心配置文件中加载映射文件:
<mappers>
<mapper resources="User.xml"/>
</mappers>
MyBatis会自动开启事务,但不知道何时提交;所以需要手动提交事务;
(然后陆续看了增删查改的实现以及原生DAO的实现方式,具体实现看项目,这里不写了;下面可能写一下动态代理DAO实现,也是看心情)
动态代理DAO实现
简单记一下:就是利用MyBatis生成实现类,而不用自己写;
主要就是,写mapper文件和接口类,四点注意事项:
- 映射文件的namespace要等于接口的全路径名;
- 映射文件的id要与接口的方法名一致;
- 映射文件的parameterType要与接口的输入参数一致;
- 映射文件的resultType要与接口的返回值类型一致;
使用的时候:
public class UserMapperTest {
private SqlSessionFactory factory;
//作用:before表示在测试方法前执行这个方法;
@Before
public void setUp() throws Exception{
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
factory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception{
SqlSession openSession=factory.openSession();
//实现类mybatis自动生成,所以不用new userdaoimpl;
//通过getMapper方法实例化接口;
//amazing
UserMapper mapper=openSession.getMapper(UserMapper.class);
//调用接口中的方法;
User user=mapper.findUserById(1);
System.out.println(user);
}
}
SqlMapConfig核心配置文件
SqlMapConfig中的属性:
properties:用于配置数据库连接参数;
typeAliases:别名;
使用:
<?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>
<properties resource="db.properties"/>
<typeAliases>
<!--
定义单个pojo类别名;
type:类的全路径名称;
alias:别名;
-->
<typeAlias type="cn.itheima.pojo.User" alias="user"/>
<!-- 使用包扫描的方式批量定义别名;
定以后别名等于类名,不区分大小写,但建议按照java命名规则来,首字母小写,以后每个单词的首字母大写;
-->
<package name="cn.itheima.pojo"/>
</typeAliases>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理-->
<transactionManager type="JDBC"/>
<!-- 数据库连接池-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
<!--
使用class属性引入接口的全路径名称;
使用规则:
1. 接口名称和映射文件名称除扩展名外要完全相同;
2. 接口和映射文件要放在同一目录下;
-->
<!-- <mapper class="cn.itheima.mapper.UserMapper"/> -->
<!--
使用包扫描的方式,批量引入Mapper接口
使用规则:
1. 接口名称和映射文件名称除扩展名外要完全相同;
2. 接口和映射文件要放在同一目录下;
-->
<package name="cn.itheima.mapper"/>
</mappers>
</configuration>
总结
- MyBatis是一个持久层框架,作用是跟数据库完成增删改查
- 原生DAO实现(需要接口和实现类)
- 动态代理方式(只需要接口)
- #{} 占位符:占位
如果传入的是基本类型,那么#{}中的变量名称可以随意写
如果传入的参数是pojo类型,那么#{}中的变量名必须是pojo中的属性.属性.属性… - ${}拼接符:字符串原样拼接
如果传入的是基本类型,那么${}中的变量名必须是value
如果传入的参数是pojo类型,那么\${}中的变量名必须是pojo中的属性.属性.属性…
注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格; - 映射文件:
传入参数类型通过paramaterType属性指定;
返回结果集类型通过resultType属性指定; - hibernate和mybatis区别:
- hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.
缺点:sql语句无法优化
应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
总的来说,在用于量不大,并发量小的时候使用. - mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
有点:学习成本低, sql语句可以优化, 执行效率高,速度快
缺点:编码量较大,会拖慢开发周期
应用场景: 互联网项目,比如电商,P2p等
总的来说是用户量较大,并发高的项目.
- hibernate:它是一个标准的orm框架,比较重量级,学习成本高.