框架是什么–框架是一个可复用性的JAVA程序
框架干了什么—框架就是为了完成技术整合
框架为何这么重要—框架完成了大型项目中的重点难题—“高内聚,低耦合”
SSM框架分为–Spring(技术整合、代码调优框架)、Mybatis(解决持久层数据问题框架)、SpringMVC(WEB应用开发,MVC开发模式)
Mybatis入门配置
首先需要安装依赖在pom.xml中
装载两个依赖 mybatis和mysql 前提要设置好仓库因为maven的网络仓库默认是境外的所以会有延迟,我们可以换成国内的镜像仓库
其次需要四个文件
第一个 主配置文件–SqlMapConfig.xml 放在resource目录下
主配置文件除开文件头内容外
<?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标签,一个是同样被configuration包含的mapper标签。前者是为了配置数据库的连接池(也就是为了连接数据库所需要的驱动信息和数据库信息),后者是为了告诉sqlsessionfactory包含数据库查询具体内容的Dao映射配置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="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/web/core/model/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
第二个 dao层接口类–包含数据库查询的方法名但没有具体内容
这个接口有两个作用一个意义,在执行查询任务的时候,要么让这个接口成为代理对象的接口类型,通过代理对象完成数据操作要么通过Dao实现类来完成数据库操作。意义就在于相当于是在里面注册了一个表相关所有数据库操作的名字
package com.web.core.model.dao;
import com.web.core.model.User;
import java.util.List;
public interface IUserDao {
List<User> findall();
}
第三个 对应dao层接口类的映射xml文件–包含数据库查询的具体内容
xml文件中包含了两个主要的标签和文件头,一个是mapper 里面的namespace需要指出这个Dao映射配置文件所对应的Dao接口的全限定类名。一个是select,撞在了对应Dao接口提供数据库的操作的具体内容,同时还可以对传入参数和结果类型等状态进行指定。
<?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.web.core.model.dao.IUserDao">
<select id="findall" resultType="com.web.core.model.User">
select * from user;
</select>
</mapper>
import com.web.core.model.User;
import com.web.core.model.dao.IUserDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Client {
public static void main(String[] args) throws IOException {
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in);
SqlSession sqlSession=factory.openSession();
IUserDao userDao=sqlSession.getMapper(IUserDao.class);
List<User> users=userDao.findall();
for (User user:users){
System.out.println(user);
}
sqlSession.close();
in.close();
}
}
tip:此处有两个方式完成这个目的,一个是上文所讲述的XML方式,一个是另一种注解开发模式,通过在Dao接口中的注解,可以直接在方法上加入select注解来标注每一个Dao接口方法的具体内容,同时主配置文件中的mapper就不用再标注映射文件了,因为映射内容已经放到了Dao接口的注解中所以应当是class=“Dao接口全限定类名” 同时也要注意如果采用注解开发请删除搜有的dao接口映射配置XML文件否则会报错
第四个 是持久层功能完成后对数据封装的类,简而言之就是封装结果集的类
这个类主要是配置,表中所有字段以及getset方法,为的是便于打印封装结果集。
package com.web.core.model;
public class User {
private String username;
private String password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}
然后如何去启动Mybatis框架的数据查询功能需要五步
1.通过Resource静态类读取主配置文件的输入文件流
2.连续通过sqlsessionfactorybuilder和sqlsessionfactory两个类加上构建者模式和工厂模式在不需要关注细节和解耦的条件下生成sqlsession文件并且通过getMapper方法创建Dao接口的代理对象然后通过代理对象调用findall查找全部方法完成数据库操作
import com.web.core.model.User;
import com.web.core.model.dao.IUserDao;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class Client {
public static void main(String[] args) throws IOException {
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in);
SqlSession sqlSession=factory.openSession();
IUserDao userDao=sqlSession.getMapper(IUserDao.class);
List<User> users=userDao.findall();
for (User user:users){
System.out.println(user);
}
sqlSession.close();
in.close();
}
}
tip:我们可以通过代理对象的形式动态的根据配置文件增强IUserDao接口类使其实现类实例具有查询的能力,但是我们也可以通过编写Dao接口类的实现类来达到和动态代理相同的目的。
Dao接口实现类,首先要实现对应的Dao层接口类,其次在构造方法中获取并赋值传入的sqlsessionfactory参数。然后在每一个持久层操作方法内都用工厂打开数据库会话操作封装返回数据。----Dao实现类是是静态代理。
总结:目前遇到了两个多途径解决的问题。
第一个是用注解开发代替了XML的映射开发
第二个是用Dao接口实现类代替了动态创建对象
增删改查
主要是对XML映射文件和Dao接口进行改变,由于我们主要采用的都是动态代理的方式就不需要再每次都要手动添加一个Dao实现类,可以直接由Mybatis框架帮我们完成查询工作
增删改查中,主要用到的两个参数是paramType和resultType,一个代表输入参数的类型一个代表输出参数的类型
还有一个标签selectKey主要是放在insert标签中用于返回一些数据,但是在具体实验的时候发现
<insert id="save" parameterType="com.web.core.model.User">
<selectKey keyProperty="id" keyColumn="id" resultType="int">
select last_insert_id();
</selectKey>
insert into user (username,password) values(#{username},#{password});
</insert>
这是保存的配置文件,这个操作并没有像想象中的一样返回一个插入数据后自增的ID,而是会默认返回该语句的执行结果–所影响的行数,在断电测试中发现,即便没有指名要返回一个对象但是select last_insert_id();语句的查询结果还是返回到了被我们当做参数传入的user对象实例中的id成员属性。
由此我们得到了如何判断一个语句是否执行的方式以及正确应该寻找返回值的地方。
同时在模糊搜索的时候发现,除了主键条件查询以外的所有查询对结果集类型都有限制,如果查询结果有多条但是,我们接口中规定的返回值类型只是一个对象而不是一个对象集合,那么就会出现错误。
如果我们在User数据库模型类中定义的表字段和实际表中的字段不符合,当然一般是符合的,那么我们有两种方式可以解决问题,一种是直接在sql语句中用as关键字设置别名,一种是在每个Dao接口的xml配置文件中设置结果集字段的不同。
<resultMap type="com.web.domain.User" id="userMap">
<id column="id" property="userId"/>
<result column="username" property="userName"/>
<result column="sex" property="userSex"/>
<result column="address" property="userAddress"/>
<result column="birthday" property="userBirthday"/>
</resultMap>
事务类型,正常事务没有自动提交所以我们需要在增删改的后面加上一个session.commit();但是这个是可以开启自动事务提交的,我们可以在工厂模式创建session对象的时候传入ture就可以开启自动事务提交:session=factory.opensession(ture)