Spring的数据库开发

boobor 7年前
   <p>Spring JDBC框架操作mysql数据库</p>    <ul>     <li>Spring中的JDBC为我们省去连接和关闭数据库的代码,我们着重关注对数据库的操作。Spring框架在数据库开发中的应用主要使用的是JDBCTemplate类,该类作为Spring对JDBC支持的核心,提供了所有对数据库操作功能的支持。我们将使用JDBCTemplate类完成对mysql数据库的增、删、改、查等操作。</li>     <li>Spring框架提供JDBC支持主要由4个包组成,分别是core(核心包)、object(对象包)、dataSource(数据源包)和support(支持包),JdbcTemplate类就在核心包中,该类包含所有数据库操作的基本方法。      <ul>       <li>core核心包:包含了JDBC的核心功能,重要的类:JdbcTemplate类、SimpleJdbcInsert类、SimpleJdbcCall类以及NamedParameterJdbcTemplate类;</li>       <li>dataSource:数据源包,访问数据源的实用工具类,他有多种数据源的实现,可以在JavaEE容器外部测试JDBC代码;</li>       <li>object:对象包,以面向对象的方式访问数据库,它允许执行查询并返回结果作为业务对象,可以在数据表的列和业务对象的属性之间映射查询结果;</li>       <li>support支持包:core和object包的支持类,例如,提供异常转换功能的SQLException类。</li>      </ul> </li>     <li>首先介绍一下项目创建前的准备,本地mysql数据库安装完成,且可以用root用户登入,登入密码为123;而且需要额外的一些jar包:</li>    </ul>    <p style="text-align:center"><img src="https://simg.open-open.com/show/abf82e241ec132d864956a8fe20c2a90.png"></p>    <p>然后在mysql数据库中创建名为User的数据库,此时数据库User中没有任何表项:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/d2ed4075ca65a7fc959686ddb7c030b2.png"></p>    <p>然后在Eclipse下新建Java项目,并且在src目录下新建lib文件夹,将jar包复制到lib文件夹下,对jar包配置路径(Build Path),然后在src目录下新建包com.jdbc,在包下新建applicationContext.xml文件,该文件为Spring的JDBC配置文件,文件如下:</p>    <pre>  <code class="language-java"><?xml version="1.0" encoding="UTF-8"?>  <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"         "http://www.springframework.org/dtd/spring-beans.dtd">  <beans>      <!-- 配置数据源 -->       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">         <!-- 数据库驱动 -->         <property name="driverClassName" value="com.mysql.jdbc.Driver"/>         <!-- 连接数据库的URL 数据库名为已经创建好的User -->         <property name="url" value="jdbc:mysql://localhost/User"/>         <!-- 连接数据库的用户名 -->         <property name="username" value="root"/>         <!-- 连接数据的密码 -->         <property name="password" value="123"/>      </bean>      <!-- 配置JDBC模板 -->      <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">         <!-- 默认必须使用数据源 -->         <property name="dataSource" ref="dataSource"/>      </bean>  </beans>  </code></pre>    <p>JdbcTemplate提供大量的查询和更新数据库的方法,如下我们分别介绍execute()方法、update()方法、query()方法。</p>    <ul>     <li>execute()方法</li>    </ul>    <p>execute(String sql)方法能够完成执行SQL语句的功能,下面以创建和删除数据库表的SQL语句为例,在如上创建的Java项目的src目录的com.jdbc下创建Client类,调用JdbcTemplate对象的execute()方法,实现对数据库表的创建和删除。代码如下:</p>    <pre>  <code class="language-java">public class Client {        public static void main(String[] args) {          // TODO Auto-generated method stub          //定义配置文件路径          String path = "com/jdbc/JdbcTemplateBeans.xml";          //加载配置文件          ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);          //获取jdbcTemplate实例          JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");          String sql = "create table t_user(userID int primary key auto_increment, userName varchar(20), password varchar(32))";          jdbcTemplate.execute(sql);          /*           * //当t_user表创建完成后,下一次执行如下两条语句,该数据库表t_user将会被删除           *           String deltable = "drop table t_user";          jdbcTemplate.execute(deltable);*/      }  }  </code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/f9008f6b590e44b2c10e868e322629d5.png"></p>    <ul>     <li>update()方法</li>    </ul>    <p>update()方法可以完成插入、更新和删除操作。在update方法中存在多个重载的方法,具体介绍如下:</p>    <ol>     <li>int update(String sql):该方法是最简单的update方法重载形式,可以直接传入SQL语句并返回受影响的行数;</li>     <li>int update(PreparedStatementCreatorpsc):该方法执行从PreparedStatementCreatorpsc返回的语句,然后返回受影响的行数;</li>     <li>int update(String sql, PreparedStatementSetterpss):该方法通过PreparedStatementSetterpss设置SQL语句中的参数,并返回受影响的行数;</li>     <li>int update(String sql, Object...args):该方法使用Object...args设置SQL语句中的参数,要求参数不能为空,并返回受影响的行数。</li>    </ol>    <p>接下来我们实现对用户信息的插入、修改和删除操作。首次按创建User类和UserFactory工厂类,代码如下:</p>    <pre>  <code class="language-java">public class User {      private int userID;  //用户ID      private String userName;  //用户名      private String passwd;    //用户密码      public int getUserID() {          return userID;      }      public void setUserID(int userID) {          this.userID = userID;      }      public String getUserName() {          return userName;      }      public void setUserName(String userName) {          this.userName = userName;      }      public String getPasswd() {          return passwd;      }      public void setPasswd(String passwd) {          this.passwd = passwd;      }  }  /*  *用户工厂类负责创建User对象  */  public class UserFactory {      public User createUser(String name, int id, String password){          User user = new User();          user.setUserName(name);          user.setUserID(id);          user.setPasswd(password);          return user;      }  }  </code></pre>    <p>接下来创建UserDao接口,负责定义对User数据的操作,实现对User的增加、修改和删除操作,然后定义具体的实现类UserDaoImpl类,代码如下:</p>    <pre>  <code class="language-java">/*  *定义对User对象的操作  */  public interface UserDao {      public int addUser(User user);      public int updateUser(User user);      public int deleteUser(User user);  }    /*   * UserDao接口的具体实现类   */  public class UserDaoImpl implements UserDao{      private JdbcTemplate jdbcTemplate;            public void setJdbcTemplate(JdbcTemplate jdbc){          this.jdbcTemplate = jdbc;      }      @Override      public int addUser(User user) {          // TODO Auto-generated method stub          String sql = "insert into t_user(userid,username,password)values(?,?,?)";          Object[] obj = new Object[]{                  user.getUserID(),                  user.getUserName(),                  user.getPasswd()          };          return this.execute(sql, obj);      }        @Override      public int updateUser(User user) {          // TODO Auto-generated method stub          String sql = "update t_user set username=?,password=? where userid=?";          Object[] obj = new Object[]{                  user.getUserName(),                  user.getPasswd(),                  user.getUserID()          };          return this.execute(sql, obj);      }        @Override      public int deleteUser(User user) {          // TODO Auto-generated method stub          String sql = "delete from t_user where userid=?";          Object[] obj = new Object[]{                  user.getUserID()          };          return this.execute(sql, obj);      }          //负责SQL语句的执行      private int execute(String sql, Object[] obj){          return this.jdbcTemplate.update(sql, obj);      }  }  </code></pre>    <p>UserDaoImpl类中有对JdbcTemplate类的引用,因此要在applicationContext.xml文件中实现UserDaoImpl对JdbcTemplate类的依赖注入,则在如上的applicationContext.xml文件的基础上,需要增加如下代码:</p>    <pre>  <code class="language-java"><bean id="userDao" class="com.jdbc.UserDaoImpl">      <property name="jdbcTemplate" ref="jdbcTemplate"/>  </bean>  </code></pre>    <p>客户端首先实现对User对象的添加操作,代码如下:</p>    <pre>  <code class="language-java">public class Client {        public static void main(String[] args) {          // TODO Auto-generated method stub          //定义配置文件路径          String path = "com/jdbc/JdbcTemplateBeans.xml";          //加载配置文件          ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);          //获取jdbcTemplate实例          JdbcTemplate jdbcTemplate = (JdbcTemplate) applicationContext.getBean("jdbcTemplate");          String sql = "create table t_user(userid int primary key auto_increment, username varchar(20), password varchar(32))";          jdbcTemplate.execute(sql);   //创建数据库表          UserDao userDao = (UserDao) applicationContext.getBean("userDao");          User user1 = new UserFactory().createUser("张三", 1, "qwer");          User user2 = new UserFactory().createUser("李四", 2, "password");          User user3 = new UserFactory().createUser("王五", 3, "wangwu");          //插入三条数据,输出为1则表示插入成功,否则插入失败          System.out.println(userDao.addUser(user1));          System.out.println(userDao.addUser(user2));          System.out.println(userDao.addUser(user3));      }  }  </code></pre>    <p>在数据库端,通过输入select * from t_user; 查询数据库表中的数据,如下图所示:</p>    <p><img src="https://simg.open-open.com/show/69e73cf761906142d1091fcbc8164148.png"></p>    <p>如上图中,我们看到李四用户的密码不太合理,需要更改其密码值,则Client的代码如下:</p>    <pre>  <code class="language-java">public class Client {        public static void main(String[] args) {          // TODO Auto-generated method stub          //定义配置文件路径          String path = "com/jdbc/JdbcTemplateBeans.xml";          //加载配置文件          ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);          UserDao userDao = (UserDao) applicationContext.getBean("userDao");          User user2 = new UserFactory().createUser("李四", 2, "lisi");          //更新李四用户的密码为lisi          userDao.updateUser(user2);      }  }  </code></pre>    <p>查询数据库t_user表可以看到李四用户的密码已经更改为lisi:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/ac9d27bf89f64174940f2cabf834d93c.png"></p>    <p>最后我们实现对张三用户的删除操作,代码就很简单了,如下:</p>    <pre>  <code class="language-java">public class Client {        public static void main(String[] args) {          // TODO Auto-generated method stub          //定义配置文件路径          String path = "com/jdbc/JdbcTemplateBeans.xml";          //加载配置文件          ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);          UserDao userDao = (UserDao) applicationContext.getBean("userDao");          User user1 = new UserFactory().createUser("张三", 1, "qwer");          System.out.println(userDao.deleteUser(user1));      }  }  </code></pre>    <p>最后可以看到张三用户被无情的从数据库表t_user中删除了:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/1b419ab189ae34e71a1148f5695aab51.png"></p>    <ul>     <li>query()方法</li>    </ul>    <p>JdbcTemplate对JDBC的流程做了封装,提供了大量的query()方法来处理各种对数据库表的查询操作,常用的query()方法如下:</p>    <ol>     <li>  List query(String sql, PreparedStatementSetterpss, RowMapper rowMapper):该方法根据String类型参数提供的SQL语句创建PreparedStatement对象,通过RowMapper将结果返回到List中;</li>     <li>List query(String sql,Object[] args, RowMapper rowMapper):该方法使用Object[]的值来设置SQL中的参数值,采用RowMapper回调方法可以直接返回List类型的数据;</li>     <li>queryForObject(String sql,Object[]args, RowMapper rowMapper):该方法将args参数绑定到SQL语句中,通过RowMapper返回单行记录,并转换为一个Object类型返回;</li>     <li>queryForList(String sql, Object[] args, class<T>elementType):该方法可以返回多行数据的结果,但必须是返回列表,elementType参数返回的是List元素类型。</li>    </ol>    <p>接下来,我们尝试一下从t_user表中查询数据,在UserDao接口中增加按照id查询的方法和查询所有用户的方法,在UserDaoImpl中具体实现两个方法,代码如下:</p>    <pre>  <code class="language-java">public interface UserDao {      //在原有代码基础上增加的两个方法      public User findUserByID(int id);      public List<User> findAllUser();  }    /*   * UserDao接口的具体实现类   */  public class UserDaoImpl implements UserDao{      @Override      public User findUserByID(int id) {          // TODO Auto-generated method stub          String sql = "select * from t_user where userid=?";          //将结果集通过Java的反射机制映射到Java对象中          RowMapper<User> rowMapper = new BeanPropertyRowMapper(User.class);          return this.jdbcTemplate.queryForObject(sql, rowMapper, id);      }      @Override      public List<User> findAllUser() {          // TODO Auto-generated method stub          String sql = "select * from t_user";          RowMapper<User> rowMapper = new BeanPropertyRowMapper(User.class);          return this.jdbcTemplate.query(sql, rowMapper);      }  }  </code></pre>    <p>然后在Client类中调用者两个方法,实现对t_user表的查询操作:</p>    <pre>  <code class="language-java">public class Client {        public static void main(String[] args) {          // TODO Auto-generated method stub          //定义配置文件路径          String path = "com/jdbc/JdbcTemplateBeans.xml";          //加载配置文件          ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);          User user = userDao.findUserByID(2);          System.out.println(user);          List<User> userList = userDao.findAllUser();          for(User u : userList){              System.out.println(u);          }      }  }  </code></pre>    <p>同时呢,User类中应该覆写toString()方法,输出用户ID、用户名和用户密码:</p>    <pre>  <code class="language-java">public class User {      //在原有代码基础上覆写toString()方法      @Override      public String toString(){          return "user ID:" + this.getUserID() + "     userName:" + this.getUserName() + "     user password:" + this.getPassword();      }  }  </code></pre>    <p style="text-align:center"><img src="https://simg.open-open.com/show/5ec98faa814a5c11e8392beac7b66bea.png"></p>    <p>运行该程序发现在Java反射的过程中password属性的值为null, 即没有将数据库中的值映射到User对象中 ,那么问题出在哪里呢?数据库表t_user中密码字段标签为password,然而Java在反射的过程中,会在User类中找setPassword(String password)方法,而本片博客的User类中设置密码的方法为setPasswd(String passwd),导致在反射过程中无法找到setPassword(String password)方法,最终才会导致查询出来的password字段值为空,解决方法当然是将User类中的setPasswd(String passwd)方法改名为setPassword(String password)即可。</p>    <p>本片文章介绍了JdbcTemplate类对mysql数据库的操作,包括execute()、update()、query()三种方法,并通过案例演示了三种方法的使用。</p>    <p> </p>    <p>来自:http://www.cnblogs.com/zhanglei93/p/6233900.html</p>    <p> </p>