代码:G:\CODE_MY\heimabase\mybatis\02\day02_eesy_01mybatisCRUD
第一步:导入依赖
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
第二步:创建实体类
第三步:创建xml主配置文件
第四步:写Dao的接口
第五步:写和接口一样的路径的配置文件sql的
第六步:测试。
-------------------------------------------------------------01----------------------------------------------------------------
写保存的方法:
第一步:
/**
* 保存用户
* @param user
*/
void saveUser(User user);
第二步:按照原来的JDBC的写法是一堆的问号的。
传入的#参数是什么格式的呢?要是get和set生成的话就直接写属性的名字,要是手写的就写get后面的名字。
<!-- 保存用户 -->
<insert id="saveUser" parameterType="com.itheima.domain.User">
insert into user(username,address,sex,birthday)values(#{userName},#{address},#{sex},#{birthday});
</insert>
1.parameterType
2.#里面是参数
注意实体类和数据库是在哪里映射的?
public <E> List<E> selectList(Mapper mapper, Connection conn) {
PreparedStatement pstm = null;
ResultSet rs = null;
try {
//1.取出mapper中的数据
String queryString = mapper.getQueryString();//select * from user
String resultType = mapper.getResultType();//com.itheima.domain.User
Class domainClass = Class.forName(resultType);
//2.获取PreparedStatement对象
pstm = conn.prepareStatement(queryString);
//3.执行SQL语句,获取结果集
rs = pstm.executeQuery();
//4.封装结果集
List<E> list = new ArrayList<E>();//定义返回值
while(rs.next()) {
//实例化要封装的实体类对象
E obj = (E)domainClass.newInstance();
//取出结果集的元信息:ResultSetMetaData
ResultSetMetaData rsmd = rs.getMetaData();
//取出总列数
int columnCount = rsmd.getColumnCount();
//遍历总列数
for (int i = 1; i <= columnCount; i++) {
//获取每列的名称,列名的序号是从1开始的
String columnName = rsmd.getColumnName(i);
//根据得到列名,获取每列的值
Object columnValue = rs.getObject(columnName);
//给obj赋值:使用Java内省机制(借助PropertyDescriptor实现属性的封装)
PropertyDescriptor pd = new PropertyDescriptor(columnName,domainClass);//要求:实体类的属性和数据库表的列名保持一致
//获取它的写入方法
Method writeMethod = pd.getWriteMethod();
//把获取的列的值,给对象赋值
writeMethod.invoke(obj,columnValue);
}
//把赋好值的对象加入到集合中
list.add(obj);
}
return list;
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
release(pstm,rs);
}
}
第三步:测试
/**
* 测试保存操作
*/
@Test
public void testSave(){
User user = new User();
user.setUserName("modify User property");
user.setUserAddress("北京市顺义区");
user.setUserSex("男");
user.setUserBirthday(new Date());
System.out.println("保存操作之前:"+user);
//5.执行保存方法
userDao.saveUser(user);
System.out.println("保存操作之后:"+user);
}
两个注解:
@Before//用于在测试方法执行之前执行
public void init()throws Exception{
//1.读取配置文件,生成字节输入流
in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.获取SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3.获取SqlSession对象
sqlSession = factory.openSession();
//4.获取dao的代理对象
userDao = sqlSession.getMapper(IUserDao.class);
}
@After//用于在测试方法执行之后执行
public void destroy()throws Exception{
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
至于这里有提交事务。
-------------------------------------------------------------02----------------------------------------------------------------
更新操作:
<update id="updateUser" parameterType="com.itheima.domain.User">
update user set username=#{userName},address=#{address},sex=#{sex},birthday=#{birthday} where id=#{id}
</update>
删除操作:
<!-- 删除用户-->
<delete id="deleteUser" parameterType="java.lang.Integer/INT/Integer不分大小写">
delete from user where id = #{uid}
</delete>
参数可以写int integer,大小写都可以的,只有一个参数的话只写占位符就可以,#{}里面是随便写的。
-------------------------------------------------------------03----------------------------------------------------------------
查询一个:
/**
* 根据id查询用户信息
* @param userId
* @return
*/
User findById(Integer userId);
查询
<!-- 根据id查询用户 -->
<select id="findById" parameterType="INT这个随便写" resultMap="com.itheima.domain.User">
select * from user where id = #{uid}
</select>
模糊查询:
<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultMap="com.itheima.domain.User">
select * from user where username like #{name}
<!-- select * from user where username like '%${value这个是固定的}%' 这个一般不用的-->
</select>
------------------------------------------------------04---------------------------------------------------------
查询总的用户数量:
<!-- 获取用户的总记录条数 -->
<select id="findTotal" resultType="int">
select count(id) from user;
</select>
基本的crud操作:
其他的写法,这个是固定的写法就是这么写的。
select * from user where username like '%${value}%'
区别是什么?
第一种是比较好的。预处理的比较好是可以克服注入攻击的。
-------------------------------------------------------------05-----------------------------------------------------------------
增删改的方法:
注意一点保存由于是自增长的原因我们是不知道id的,但是我们就想知道id应该怎么办呢?
sql:
<!-- 保存用户 -->
<insert id="saveUser" parameterType="user">
<!-- 配置插入操作后,获取插入数据的id -->
<selectKey keyProperty="userId/id这个是实体类属性不是数据库列" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{userName},#{address},#{sex},#{birthday});
</insert>
selectKey标签。
-----------------------------------------------------06------------------------------------------------------
mybatis的参数深入?
什么是ognl表达式?
通过对象中的取值方法来获取数据。
user.getUsername();
user.username;
这个就解释了为什么可以这样的写了。而不是getUsername。
--------------------------------
深入:查询条件对象。
/**
* 根据queryVo中的条件查询用户
* @param vo
* @return
*/
List<User> findUserByVo(QueryVo vo);
<!-- 根据queryVo的条件查询用户 -->
<select id="findUserByVo" parameterType="com.itheima.domain.QueryVo" resultMap="com.itheima.domain.USer">
select * from user where username like #{user.username}
</select>
-------------------------------------------------------------07-----------------------------------------------------------------
结果类型的封装:实体类和数据库列名不一样。
增加删除修改的话修改#的参数就可以了,因为没有返回值的映射。
查询:
有些可以封装进去有些不能,mysql数据库在window系统下不区分大小写。所以userName=username,可以进去的。
-----------------------------------------------------------------------08--------------------------------------------------------------
列名和实体类的名称不一致的话,解决办法:
1.起别名
2.配置查询结果的列名和实体类的属性名的对应关系
第一步:
第二步:
-------------------------------------------------------------09-----------------------------------------------------------------