SpringJDBC与MyBatis;实体类属性与数据库表字段名不一致的解决方法;
--------------------------------------------------------------------------------------------------------------------
springjdbc
一.springjdbc是什么?
- spring框架对jdbc api的封装,使用起来更加简单.比如,不用考虑获得连接与关闭连接等等。
二.如何使用?
step1. 配置DataSource。
step2. 配置JdbcTemplate。
step3. 调用JdbcTemplate提供的方法。
1. <!-- 配置DataSource -->
<bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="#{jdbc.driverClass}"/>
<property name="url" value="#{jdbc.url}"/>
<property name="username" value="#{jdbc.user}"/>
<property name="password" value="#{jdbc.password}"/>
<property name="maxActive" value="#{jdbc.MaxActive}"/>
<property name="initialSize" value="#{jdbc.InitialSize}"/>
</bean>
2. <!-- 配置JdbcTemplate -->
<bean id="jt" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="ds"/>
</bean>
3.
@Repository
public class UserDao {
@Resource(name="jt")
private JdbcTemplate jt;
public void save(User user){
String sql = "INSERT INTO l_user "
+ "VALUES(l_user_seq.nextval,?,? )";
jt.update(sql,new Object[]{user.getName(),user.getAge()});
}
/*
* 需要写一个RowMapper接口的类,该类规定了如何将结果集中的
* 一条记录转换成相应的java对象(比如User对象)
*/
public List<User> findAll(){
List<User> users = new ArrayList<User>();
String sql = "SELECT *FROM L_USER ";
users = jt.query(sql,new UserRowMapper());
return users;
}
class UserRowMapper implements RowMapper<User>{
/*
* rst:结果集;
* index:记录的下标,从0开始
* @see org.springframework.jdbc.core.RowMapper#mapRow(java.sql.ResultSet, int)
*/
public User mapRow(ResultSet rs, int index) throws SQLException {
User user = new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setAge(rs.getInt("age"));
return user;
}
}
public User findById(int id){
User user = null;
String sql = "SELECT *FROM l_user "
+ "WHERE id=? ";
user = jt.queryForObject(sql, new Object[]{id},new UserRowMapper());
return user;
}
/*
* 这样写查询不到数据时不会报异常
*/
public User findById2(int id){
User user = null;
String sql = "SELECT *FROM l_user "
+ "WHERE id=? ";
List<User> users = jt.query(sql,new Object[]{id},new UserRowMapper());
if(users!=null && users.size()>0){
return users.get(0);
}
return user;
}
public void update(User user){
String sql = "UPDATE l_user "
+ "SET name=?,age=? WHERE ID=?";
jt.update(sql,new Object[]{user.getName(),user.getAge(),user.getId()});
}
public void delete(int id){
String sql = "DELETE FROM l_user "
+ "WHERE id=?";
jt.update(sql,new Object[]{id});
}
/**
* 获得总的记录数.
* 建议使用queryForObject方法.
* 不建议使用queryForInt方法.
* @return
*/
public int getTotalRow(){
String sql = "SELECT COUNT(*)FROM l_user";
return jt.queryForObject(sql, Integer.class);
}
}
------------------------------------------------------------------------------------------------------------------------
MyBatis简介
iBatis—>MyBatis
- 作用:对数据库进行操作
JDBC—>JdbcTemplate—>MyBatis
MyBatis是对JDBC技术的封装.
- 封装了获取连接,生成Statement,执行SQL过程
- 封装了SQL参数设置过程(将参数设置到#{xx})
- 封装了将结果集映射成实体对象过程(resultType指定,名称对应)
编程步骤:
- 导入mybatis包+数据库驱动包(mybatis-3.3.3.jar ojdbc14-10.2.0.4.0.jar)
- 添加一个SqlMapConfig.xml主配置文件
- 根据表写实体类/在Mapper.xml配置文件中编写SQL/利用MyBatis调用SQL
SqlMapConfig.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
<configuration>
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver"
value="oracle.jdbc.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@localhost :1521:xe"/>
<property name="username" value="system" />
<property name="password" value="12345" />
</dataSource>
</environment>
</environments>
<!-- 加载SQL定义文件 -->
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>
实体类:
public class User implements Serializable{
private Integer id;
private String name;
private Integer age;
...get/set方法
}
在UserMapper.xml配置文件中编写SQL:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.tedu.dao.UserDAO">
<!--
parameterType:参数值类型
resultType:结果集类型
-->
<select id="findById" parameterType="int" resultType="com.tedu.entity.User">
SELECT * FROM l_user
WHERE id=#{id}
</select>
<select id="findAll" resultType="com.tedu.entity.User">
SELECT * FROM l_user
</select>
<insert id="saveUser" parameterType="com.tedu.entity.User">
INSERT INTO l_user
(id,name,age)
VALUES
<!-- 参数的名字指实体类里的属性名 -->
(l_user_seq.nextval,#{name},#{age})
</insert>
<update id="updateUser" parameterType="com.tedu.entity.User">
UPDATE l_user
SET name=#{name},age=#{age}
WHERE id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
DELETE FROM l_user
WHERE id=#{id}
</delete>
<!-- 按name字段模糊查询 -->
<select id="findLikeName" parameterType="String" resultType="com.tedu.entity.User">
SELECT * FROM l_user
WHERE name LIKE #{name}
</select>
<select id="findName" parameterType="int" resultType="map">
SELECT ID,NAME
FROM l_user
WHERE ID=#{id}
</select>
<select id="findNames" resultType="map">
SELECT ID,NAME
FROM l_user
</select>
<select id="findAllUsers" resultType="map">
SELECT ID,NAME,AGE
FROM l_user
</select>
</mapper>
利用MyBatis调用SQL:
一.Util:
public class MyBatisUtil {
public static SqlSession getSession() throws Exception{
/*
* SqlSessionFactoryBuilder
* SqlSessionFactory
* SqlSession
*/
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//加载SqlMapConfig.xml主配置文件
String conf = "SqlMapConfig.xml";
Reader reader = Resources.getResourceAsReader(conf);
//SqlSessionFactory
SqlSessionFactory factory = builder.build(reader);
//SqlSession
SqlSession session = factory.openSession();
return session;
}
}
测试类:
public class TestUser {
@Test
//测试获取SqlSession,findById
public void test1() throws Exception{
SqlSession session = MyBatisUtil.getSession();
System.out.println(session);
//使用SqlSession执行SQL操作
User user = session.selectOne("findById",2);
if(user != null){
System.out.println(user);
System.out.println(user.getName());
System.out.println(user.getAge());
}
session.close();
}
@Test
//测试findAll
public void test2() throws Exception{
SqlSession session = MyBatisUtil.getSession();
List<User> users = session.selectList("findAll");
for(User u:users){
System.out.println(u.getId());
System.out.println(u.getName());
System.out.println(u.getAge());
}
session.close();
}
@Test
//测试添加
public void test3() throws Exception{
SqlSession session = MyBatisUtil.getSession();
User user = new User();
//user.setId(10);用序列
user.setName("MySQL");
user.setAge(20);
//执行insert
session.insert("saveUser",user);
//增删改需要手动提交事务
session.commit();
session.close();
}
@Test
//测试更新
public void test4() throws Exception{
SqlSession session = MyBatisUtil.getSession();
User user = new User();
user.setId(1);
user.setName("DAMEN");
user.setAge(30);
//返回值为更新的行数
int rows = session.update("updateUser",user);
if(rows>=1){
System.out.println("更新成功!更新了"+rows+"行!");
}else{
System.out.println("更新失败!");
}
session.commit();
session.close();
}
@Test
//测试删除
public void test5() throws Exception{
SqlSession session = MyBatisUtil.getSession();
int rows = session.delete("deleteUser",22);
if(rows>=1){
System.out.println("删除成功!删除了"+rows+"行!");
}else{
System.out.println("删除失败!");
}
session.commit();
session.close();
}
@Test
//测试模糊查询
public void test6() throws Exception{
SqlSession session = MyBatisUtil.getSession();
List<User> users = session.selectList("findLikeName", "M%");
if(users!=null){
for(User u:users){
System.out.println(u.getId());
System.out.println(u.getName());
System.out.println(u.getAge());
}
}
session.close();
}
@Test
//测试map查询结果
public void test7() throws Exception{
SqlSession session = MyBatisUtil.getSession();
Map<String,Object> map = session.selectOne("findName",23);
if(map!=null){
System.out.println(map);
//查询出的map中的key为字段名,记录为value
System.out.println(map.get("ID")+","+map.get("NAME"));
}
session.close();
}
@Test
//测试map查询结果
public void test8() throws Exception{
SqlSession session = MyBatisUtil.getSession();
List<Map<String,Object>> maps = session.selectList("findNames");
if(maps!=null){
for(Map<String,Object> m:maps){
//查询出的map中的key为字段名,记录为value
System.out.println(m.get("ID")+","+m.get("NAME"));
}
}
session.close();
}
@Test
//测试返回list查询结果
public void test9() throws Exception{
SqlSession session = MyBatisUtil.getSession();
List<Map<String,Object>> maps = session.selectList("findAllUsers");
if(maps!=null){
for(Map<String,Object> m:maps){
//查询出的map中的key为字段名,记录为value
System.out.println(m.get("ID")+","+m.get("NAME")+","+m.get("AGE"));
}
}
session.close();
}
@Test
//测试Mapper映射其接口
public void test10() throws Exception{
SqlSession session = MyBatisUtil.getSession();
//根据接口生成实现对象
UserDAO dao = session.getMapper(UserDAO.class);
System.out.println(dao.getClass().getName());
List<User> users = dao.findAll();
if(users!=null){
for(User u:users){
System.out.println(u.getId()+","+u.getName()+","+u.getAge());
}
}
session.close();
}
}
------------------------
Mapper映射器(接口)
MyBatis提供了一个Mapper映射器接口规则,按规则写出的接口,MyBatis框架可以自动生成实现组件对象。
(不再需要自己写dao,只需要写实体类对应的接口即可)
UserDAO接口—》JdbcUserDAO实现类—》生成对象使用
Mapper映射器接口—》生成对象使用
映射器接口接口规则:
- 方法名参考SQL定义的id属性(保持一致)
- 方法参数类型参考SQL定义的parameterType属性(保持一致)
-方法返回类型
- 增删改:可以是void 或 int
- 查询:单行结果类型为resultType,多行结果类型为List
- 将SQL定义文件元素的namespace属性指定为"包名.接口名"
/**
* Mapper映射器接口:对应UserMapper.xml里的sql语句
* 方法名--->id属性
* 参数--->parameterType属性
* 返回值类型-->增删改void或int;查询参考resultType属性
* 查询结果为多个的话返回值为list类型.
* @author Administrator
*
*/
public interface UserDAO {
public User findById(int id);
public List<User> findAll();
public int saveUser(User user);
public int updateUser(User user);
public int deletdUser(int id);
public List<User> findLikeName(String name);
public Map<String,Object> findName(int id);
public List<Map<String,Object>> findNames();
public List<Map<String,Object>> findAllUsers();
}
-----------------------------------------------------------------------------------------------------------
实体类属性与数据库表字段名不一致的解决方法:
<!-- 当属性名与字段名不一致的解决方法
方法一:用别名
-->
<!-- <select id="findAll2" resultMap="costMap">
SELECT cost_id id,name,...
FROM cost
</select> -->
<!-- 方法二:自定义属性
利用resultMap自定义装载规则,替代resultType.
-->
<select id="findAll2" resultMap="costMap">
SELECT *FROM cost
</select>
<resultMap type="com.tedu.entity.Cost" id="costMap">
<id property="id" column="cost_id"/>
<result property="name" column="name"/>
<!-- ...可以省略名称一致的字段 -->
</resultMap>
--------------------------------------------------------------------------------------------------------------------